diff options
Diffstat (limited to 'servers')
109 files changed, 6971 insertions, 4687 deletions
diff --git a/servers/SCsub b/servers/SCsub index 2cd4741d56..66a1b9b26f 100644 --- a/servers/SCsub +++ b/servers/SCsub @@ -13,6 +13,7 @@ SConscript("rendering/SCsub") SConscript("audio/SCsub") SConscript("text/SCsub") SConscript("debugger/SCsub") +SConscript("extensions/SCsub") lib = env.add_library("servers", env.servers_sources) diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp index b9eca14a4c..f38d0adfb2 100644 --- a/servers/audio/audio_effect.cpp +++ b/servers/audio/audio_effect.cpp @@ -30,5 +30,36 @@ #include "audio_effect.h" +void AudioEffectInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { + if (GDVIRTUAL_REQUIRED_CALL(_process, p_src_frames, p_dst_frames, p_frame_count)) { + return; + } +} +bool AudioEffectInstance::process_silence() const { + bool ret; + if (GDVIRTUAL_CALL(_process_silence, ret)) { + return ret; + } + return false; +} + +void AudioEffectInstance::_bind_methods() { + GDVIRTUAL_BIND(_process, "src_buffer", "dst_buffer", "frame_count"); + GDVIRTUAL_BIND(_process_silence); +} + +//// + +Ref<AudioEffectInstance> AudioEffect::instantiate() { + Ref<AudioEffectInstance> ret; + if (GDVIRTUAL_REQUIRED_CALL(_instantiate, ret)) { + return ret; + } + return Ref<AudioEffectInstance>(); +} +void AudioEffect::_bind_methods() { + GDVIRTUAL_BIND(_instantiate); +} + AudioEffect::AudioEffect() { } diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h index 00a5d6c004..3a0578679d 100644 --- a/servers/audio/audio_effect.h +++ b/servers/audio/audio_effect.h @@ -33,20 +33,32 @@ #include "core/io/resource.h" #include "core/math/audio_frame.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" +#include "core/variant/native_ptr.h" class AudioEffectInstance : public RefCounted { GDCLASS(AudioEffectInstance, RefCounted); +protected: + GDVIRTUAL3(_process, GDNativeConstPtr<AudioFrame>, GDNativePtr<AudioFrame>, int) + GDVIRTUAL0RC(bool, _process_silence) + static void _bind_methods(); + public: - virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) = 0; - virtual bool process_silence() const { return false; } + virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count); + virtual bool process_silence() const; }; class AudioEffect : public Resource { GDCLASS(AudioEffect, Resource); +protected: + GDVIRTUAL0R(Ref<AudioEffectInstance>, _instantiate) + static void _bind_methods(); + public: - virtual Ref<AudioEffectInstance> instantiate() = 0; + virtual Ref<AudioEffectInstance> instantiate(); AudioEffect(); }; diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 39060286a4..1ebd57fa7f 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -76,10 +76,10 @@ void AudioStreamPlayback::seek(float p_time) { int AudioStreamPlayback::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { int ret; - if (GDVIRTUAL_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret)) { + if (GDVIRTUAL_REQUIRED_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret)) { return ret; } - WARN_PRINT_ONCE("AudioStreamPlayback::mix unimplemented!"); + return 0; } @@ -94,7 +94,7 @@ void AudioStreamPlayback::_bind_methods() { } ////////////////////////////// -void AudioStreamPlaybackResampled::_begin_resample() { +void AudioStreamPlaybackResampled::begin_resample() { //clear cubic interpolation history internal_buffer[0] = AudioFrame(0.0, 0.0); internal_buffer[1] = AudioFrame(0.0, 0.0); @@ -105,6 +105,30 @@ void AudioStreamPlaybackResampled::_begin_resample() { mix_offset = 0; } +int AudioStreamPlaybackResampled::_mix_internal(AudioFrame *p_buffer, int p_frames) { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_mix_resampled, p_buffer, p_frames, ret)) { + return ret; + } + + return 0; +} +float AudioStreamPlaybackResampled::get_stream_sampling_rate() { + float ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_stream_sampling_rate, ret)) { + return ret; + } + + return 0; +} + +void AudioStreamPlaybackResampled::_bind_methods() { + ClassDB::bind_method(D_METHOD("begin_resample"), &AudioStreamPlaybackResampled::begin_resample); + + GDVIRTUAL_BIND(_mix_resampled, "dst_buffer", "frame_count"); + GDVIRTUAL_BIND(_get_stream_sampling_rate); +} + int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { float target_rate = AudioServer::get_singleton()->get_mix_rate(); float playback_speed_scale = AudioServer::get_singleton()->get_playback_speed_scale(); @@ -200,6 +224,7 @@ bool AudioStream::is_monophonic() const { void AudioStream::_bind_methods() { ClassDB::bind_method(D_METHOD("get_length"), &AudioStream::get_length); ClassDB::bind_method(D_METHOD("is_monophonic"), &AudioStream::is_monophonic); + ClassDB::bind_method(D_METHOD("instance_playback"), &AudioStream::instance_playback); GDVIRTUAL_BIND(_instance_playback); GDVIRTUAL_BIND(_get_stream_name); GDVIRTUAL_BIND(_get_length); @@ -314,7 +339,7 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) { if (AudioDriver::get_singleton()->capture_start() == OK) { active = true; - _begin_resample(); + begin_resample(); } } diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index ce9bcabb9c..55031dec2c 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -81,10 +81,15 @@ class AudioStreamPlaybackResampled : public AudioStreamPlayback { uint64_t mix_offset; protected: - void _begin_resample(); + void begin_resample(); // Returns the number of frames that were mixed. - virtual int _mix_internal(AudioFrame *p_buffer, int p_frames) = 0; - virtual float get_stream_sampling_rate() = 0; + virtual int _mix_internal(AudioFrame *p_buffer, int p_frames); + virtual float get_stream_sampling_rate(); + + GDVIRTUAL2R(int, _mix_resampled, GDNativePtr<AudioFrame>, int) + GDVIRTUAL0RC(float, _get_stream_sampling_rate) + + static void _bind_methods(); public: virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override; diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp index ba2d257c0a..3c53887931 100644 --- a/servers/audio/effects/audio_effect_pitch_shift.cpp +++ b/servers/audio/effects/audio_effect_pitch_shift.cpp @@ -74,7 +74,7 @@ * *****************************************************************************/ -void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int64_t fftFrameSize, int64_t osamp, float sampleRate, float *indata, float *outdata,int stride) { +void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata,int stride) { /* @@ -85,32 +85,19 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6 */ double magn, phase, tmp, window, real, imag; - double freqPerBin, expct, reciprocalFftFrameSize; - int64_t i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2; + double freqPerBin, expct; + long i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2; /* set up some handy variables */ fftFrameSize2 = fftFrameSize/2; - reciprocalFftFrameSize = 1./fftFrameSize; stepSize = fftFrameSize/osamp; - freqPerBin = reciprocalFftFrameSize * sampleRate; - expct = Math_TAU * reciprocalFftFrameSize * stepSize; + freqPerBin = sampleRate/(double)fftFrameSize; + expct = 2.*Math_PI*(double)stepSize/(double)fftFrameSize; inFifoLatency = fftFrameSize-stepSize; - if (gRover == 0) { - gRover = inFifoLatency; - } + if (gRover == 0) { gRover = inFifoLatency; +} - // If pitchShift changes clear arrays to prevent some artifacts and quality loss. - if (lastPitchShift != pitchShift) { - lastPitchShift = pitchShift; - memset(gInFIFO, 0, MAX_FRAME_LENGTH * sizeof(float)); - memset(gOutFIFO, 0, MAX_FRAME_LENGTH * sizeof(float)); - memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(double)); - memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double)); - memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double)); - memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(double)); - memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(double)); - memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(double)); - } + /* initialize our static arrays */ /* main processing loop */ for (i = 0; i < numSampsToProcess; i++){ @@ -125,7 +112,7 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6 /* do windowing and re,im interleave */ for (k = 0; k < fftFrameSize;k++) { - window = -.5*cos(Math_TAU * reciprocalFftFrameSize * k)+.5; + window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5; gFFTworksp[2*k] = gInFIFO[k] * window; gFFTworksp[2*k+1] = 0.; } @@ -137,7 +124,6 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6 /* this is the analysis step */ for (k = 0; k <= fftFrameSize2; k++) { - /* de-interlace FFT buffer */ real = gFFTworksp[2*k]; imag = gFFTworksp[2*k+1]; @@ -155,15 +141,13 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6 /* map delta phase into +/- Pi interval */ qpd = tmp/Math_PI; - if (qpd >= 0) { - qpd += qpd&1; - } else { - qpd -= qpd&1; - } + if (qpd >= 0) { qpd += qpd&1; + } else { qpd -= qpd&1; +} tmp -= Math_PI*(double)qpd; /* get deviation from bin frequency from the +/- Pi interval */ - tmp = osamp*tmp/Math_TAU; + tmp = osamp*tmp/(2.*Math_PI); /* compute the k-th partials' true frequency */ tmp = (double)k*freqPerBin + tmp*freqPerBin; @@ -176,8 +160,8 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6 /* ***************** PROCESSING ******************* */ /* this does the actual pitch shifting */ - memset(gSynMagn, 0, fftFrameSize*sizeof(double)); - memset(gSynFreq, 0, fftFrameSize*sizeof(double)); + memset(gSynMagn, 0, fftFrameSize*sizeof(float)); + memset(gSynFreq, 0, fftFrameSize*sizeof(float)); for (k = 0; k <= fftFrameSize2; k++) { index = k*pitchShift; if (index <= fftFrameSize2) { @@ -200,7 +184,7 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6 tmp /= freqPerBin; /* take osamp into account */ - tmp = Math_TAU*tmp/osamp; + tmp = 2.*Math_PI*tmp/osamp; /* add the overlap phase advance back in */ tmp += (double)k*expct; @@ -215,35 +199,33 @@ void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int6 } /* zero negative frequencies */ - for (k = fftFrameSize+2; k < 2*MAX_FRAME_LENGTH; k++) { - gFFTworksp[k] = 0.; - } + for (k = fftFrameSize+2; k < 2*fftFrameSize; k++) { gFFTworksp[k] = 0.; +} /* do inverse transform */ smbFft(gFFTworksp, fftFrameSize, 1); /* do windowing and add to output accumulator */ for(k=0; k < fftFrameSize; k++) { - window = -.5*cos(Math_TAU * reciprocalFftFrameSize * k)+.5; + window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5; gOutputAccum[k] += 2.*window*gFFTworksp[2*k]/(fftFrameSize2*osamp); } - for (k = 0; k < stepSize; k++) { - gOutFIFO[k] = gOutputAccum[k]; - } + for (k = 0; k < stepSize; k++) { gOutFIFO[k] = gOutputAccum[k]; +} /* shift accumulator */ - memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(double)); + memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(float)); /* move input FIFO */ - for (k = 0; k < inFifoLatency; k++) { - gInFIFO[k] = gInFIFO[k+stepSize]; - } + for (k = 0; k < inFifoLatency; k++) { gInFIFO[k] = gInFIFO[k+stepSize]; +} } } } -void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign) + +void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign) /* FFT routine, (C)1996 S.M.Bernsee. Sign = -1 is FFT, 1 is iFFT (inverse) Fills fftBuffer[0...2*fftFrameSize-1] with the Fourier transform of the @@ -256,16 +238,14 @@ void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign of the frequencies of interest is in fftBuffer[0...fftFrameSize]. */ { - double wr, wi, arg, *p1, *p2, temp; - double tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i; - int64_t i, bitm, j, le, le2, k, logN; - logN = (int64_t)(log(fftFrameSize) / log(2.) + .5); + float wr, wi, arg, *p1, *p2, temp; + float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i; + long i, bitm, j, le, le2, k; for (i = 2; i < 2*fftFrameSize-2; i += 2) { for (bitm = 2, j = 0; bitm < 2*fftFrameSize; bitm <<= 1) { - if (i & bitm) { - j++; - } + if (i & bitm) { j++; +} j <<= 1; } if (i < j) { @@ -275,8 +255,7 @@ void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign *p1 = *p2; *p2 = temp; } } - - for (k = 0, le = 2; k < logN; k++) { + for (k = 0, le = 2; k < (long)(log((double)fftFrameSize)/log(2.)+.5); k++) { le <<= 1; le2 = le>>1; ur = 1.0; @@ -309,14 +288,6 @@ void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { float sample_rate = AudioServer::get_singleton()->get_mix_rate(); - // For pitch_scale 1.0 it's cheaper to just pass samples without processing them. - if (Math::is_equal_approx(base->pitch_scale, 1.0f)) { - for (int i = 0; i < p_frame_count; i++) { - p_dst_frames[i] = p_src_frames[i]; - } - return; - } - float *in_l = (float *)p_src_frames; float *in_r = in_l + 1; @@ -390,4 +361,7 @@ AudioEffectPitchShift::AudioEffectPitchShift() { pitch_scale = 1.0; oversampling = 4; fft_size = FFT_SIZE_2048; + wet = 0.0; + dry = 0.0; + filter = false; } diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h index 23da61bb32..0478d05ceb 100644 --- a/servers/audio/effects/audio_effect_pitch_shift.h +++ b/servers/audio/effects/audio_effect_pitch_shift.h @@ -40,33 +40,31 @@ class SMBPitchShift { float gInFIFO[MAX_FRAME_LENGTH]; float gOutFIFO[MAX_FRAME_LENGTH]; - double gFFTworksp[2 * MAX_FRAME_LENGTH]; - double gLastPhase[MAX_FRAME_LENGTH / 2 + 1]; - double gSumPhase[MAX_FRAME_LENGTH / 2 + 1]; - double gOutputAccum[2 * MAX_FRAME_LENGTH]; - double gAnaFreq[MAX_FRAME_LENGTH]; - double gAnaMagn[MAX_FRAME_LENGTH]; - double gSynFreq[MAX_FRAME_LENGTH]; - double gSynMagn[MAX_FRAME_LENGTH]; - int64_t gRover; - float lastPitchShift; - - void smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign); + float gFFTworksp[2 * MAX_FRAME_LENGTH]; + float gLastPhase[MAX_FRAME_LENGTH / 2 + 1]; + float gSumPhase[MAX_FRAME_LENGTH / 2 + 1]; + float gOutputAccum[2 * MAX_FRAME_LENGTH]; + float gAnaFreq[MAX_FRAME_LENGTH]; + float gAnaMagn[MAX_FRAME_LENGTH]; + float gSynFreq[MAX_FRAME_LENGTH]; + float gSynMagn[MAX_FRAME_LENGTH]; + long gRover; + + void smbFft(float *fftBuffer, long fftFrameSize, long sign); public: - void PitchShift(float pitchShift, int64_t numSampsToProcess, int64_t fftFrameSize, int64_t osamp, float sampleRate, float *indata, float *outdata, int stride); + void PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata, int stride); SMBPitchShift() { gRover = 0; memset(gInFIFO, 0, MAX_FRAME_LENGTH * sizeof(float)); memset(gOutFIFO, 0, MAX_FRAME_LENGTH * sizeof(float)); - memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(double)); - memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double)); - memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double)); - memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(double)); - memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(double)); - memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(double)); - lastPitchShift = 1.0; + memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(float)); + memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(float)); + memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(float)); + memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(float)); + memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(float)); + memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(float)); } }; @@ -103,6 +101,9 @@ public: float pitch_scale; int oversampling; FFTSize fft_size; + float wet; + float dry; + bool filter; protected: static void _bind_methods(); diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp index 6c917f3eb6..a3d615b925 100644 --- a/servers/audio/effects/audio_stream_generator.cpp +++ b/servers/audio/effects/audio_stream_generator.cpp @@ -169,7 +169,7 @@ float AudioStreamGeneratorPlayback::get_stream_sampling_rate() { void AudioStreamGeneratorPlayback::start(float p_from_pos) { if (mixed == 0.0) { - _begin_resample(); + begin_resample(); } skips = 0; active = true; diff --git a/servers/camera/camera_feed.cpp b/servers/camera/camera_feed.cpp index 3aab995857..624c06ecf1 100644 --- a/servers/camera/camera_feed.cpp +++ b/servers/camera/camera_feed.cpp @@ -33,7 +33,7 @@ #include "servers/rendering_server.h" void CameraFeed::_bind_methods() { - // The setters prefixed with _ are only exposed so we can have feeds through GDNative! + // The setters prefixed with _ are only exposed so we can have feeds through GDExtension! // They should not be called by the end user. ClassDB::bind_method(D_METHOD("get_id"), &CameraFeed::get_id); diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 58a51e3aea..819c151087 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -399,6 +399,9 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window); ClassDB::bind_method(D_METHOD("window_get_native_handle", "handle_type", "window_id"), &DisplayServer::window_get_native_handle, DEFVAL(MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("window_get_active_popup"), &DisplayServer::window_get_active_popup); + ClassDB::bind_method(D_METHOD("window_set_popup_safe_rect", "window", "rect"), &DisplayServer::window_set_popup_safe_rect); + ClassDB::bind_method(D_METHOD("window_get_popup_safe_rect", "window"), &DisplayServer::window_get_popup_safe_rect); ClassDB::bind_method(D_METHOD("window_set_title", "title", "window_id"), &DisplayServer::window_set_title, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_mouse_passthrough", "region", "window_id"), &DisplayServer::window_set_mouse_passthrough, DEFVAL(MAIN_WINDOW_ID)); @@ -552,6 +555,7 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(WINDOW_FLAG_ALWAYS_ON_TOP); BIND_ENUM_CONSTANT(WINDOW_FLAG_TRANSPARENT); BIND_ENUM_CONSTANT(WINDOW_FLAG_NO_FOCUS); + BIND_ENUM_CONSTANT(WINDOW_FLAG_POPUP); BIND_ENUM_CONSTANT(WINDOW_FLAG_MAX); BIND_ENUM_CONSTANT(WINDOW_EVENT_MOUSE_ENTER); diff --git a/servers/display_server.h b/servers/display_server.h index 81ac551f57..67dbab0924 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -226,6 +226,7 @@ public: WINDOW_FLAG_ALWAYS_ON_TOP, WINDOW_FLAG_TRANSPARENT, WINDOW_FLAG_NO_FOCUS, + WINDOW_FLAG_POPUP, WINDOW_FLAG_MAX, }; @@ -235,13 +236,18 @@ public: WINDOW_FLAG_BORDERLESS_BIT = (1 << WINDOW_FLAG_BORDERLESS), WINDOW_FLAG_ALWAYS_ON_TOP_BIT = (1 << WINDOW_FLAG_ALWAYS_ON_TOP), WINDOW_FLAG_TRANSPARENT_BIT = (1 << WINDOW_FLAG_TRANSPARENT), - WINDOW_FLAG_NO_FOCUS_BIT = (1 << WINDOW_FLAG_NO_FOCUS) + WINDOW_FLAG_NO_FOCUS_BIT = (1 << WINDOW_FLAG_NO_FOCUS), + WINDOW_FLAG_POPUP_BIT = (1 << WINDOW_FLAG_POPUP), }; virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()); virtual void show_window(WindowID p_id); virtual void delete_sub_window(WindowID p_id); + virtual WindowID window_get_active_popup() const { return INVALID_WINDOW_ID; }; + virtual void window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect){}; + virtual Rect2i window_get_popup_safe_rect(WindowID p_window) const { return Rect2i(); }; + virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const; virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0; diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h index f74a8fad23..3853ff4fdc 100644 --- a/servers/display_server_headless.h +++ b/servers/display_server_headless.h @@ -33,7 +33,7 @@ #include "servers/display_server.h" -#include "servers/rendering/rasterizer_dummy.h" +#include "servers/rendering/dummy/rasterizer_dummy.h" class DisplayServerHeadless : public DisplayServer { private: diff --git a/servers/extensions/SCsub b/servers/extensions/SCsub new file mode 100644 index 0000000000..eac66ea283 --- /dev/null +++ b/servers/extensions/SCsub @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +Import("env") + +import make_wrappers +from platform_methods import run_in_subprocess + +env.CommandNoCache(["ext_wrappers.gen.inc"], "make_wrappers.py", run_in_subprocess(make_wrappers.run)) + +env_object = env.Clone() + +env_object.add_source_files(env.servers_sources, "*.cpp") diff --git a/servers/extensions/make_wrappers.py b/servers/extensions/make_wrappers.py new file mode 100644 index 0000000000..862d313fba --- /dev/null +++ b/servers/extensions/make_wrappers.py @@ -0,0 +1,93 @@ +proto = """ +#define EXBIND$VER($RETTYPE m_name$ARG) \\ +GDVIRTUAL$VER($RETTYPE_##m_name$ARG)\\ +virtual $RETVAL m_name($FUNCARGS) $CONST override { \\ + $RETPRE\\ + GDVIRTUAL_REQUIRED_CALL(_##m_name$CALLARGS$RETREF);\\ + $RETPOST\\ +} +""" + + +def generate_version(argcount, const=False, returns=False): + s = proto + sproto = str(argcount) + method_info = "" + if returns: + sproto += "R" + s = s.replace("$RETTYPE", "m_ret, ") + s = s.replace("$RETVAL", "m_ret") + s = s.replace("$RETPRE", "m_ret ret; ZeroInitializer<m_ret>::initialize(ret);\\\n") + s = s.replace("$RETPOST", "return ret;\\\n") + + else: + s = s.replace("$RETTYPE", "") + s = s.replace("$RETVAL", "void") + s = s.replace("$RETPRE", "") + s = s.replace("$RETPOST", "return;") + + if const: + sproto += "C" + s = s.replace("$CONST", "const") + else: + s = s.replace("$CONST", "") + + s = s.replace("$VER", sproto) + argtext = "" + funcargs = "" + callargs = "" + + for i in range(argcount): + if i > 0: + funcargs += ", " + + argtext += ", m_type" + str(i + 1) + funcargs += "m_type" + str(i + 1) + " arg" + str(i + 1) + callargs += ", arg" + str(i + 1) + + if argcount: + s = s.replace("$ARG", argtext) + s = s.replace("$FUNCARGS", funcargs) + s = s.replace("$CALLARGS", callargs) + else: + s = s.replace("$ARG", "") + s = s.replace("$FUNCARGS", funcargs) + s = s.replace("$CALLARGS", callargs) + + if returns: + s = s.replace("$RETREF", ", ret") + else: + s = s.replace("$RETREF", "") + + return s + + +def run(target, source, env): + + max_versions = 12 + + txt = """ +#ifndef GDEXTENSION_WRAPPERS_GEN_H +#define GDEXTENSION_WRAPPERS_GEN_H + + +""" + + for i in range(max_versions + 1): + + txt += "/* " + str(i) + " Arguments */\n\n" + txt += generate_version(i, False, False) + txt += generate_version(i, False, True) + txt += generate_version(i, True, False) + txt += generate_version(i, True, True) + + txt += "#endif" + + with open(target[0], "w") as f: + f.write(txt) + + +if __name__ == "__main__": + from platform_methods import subprocess_main + + subprocess_main(globals()) diff --git a/servers/extensions/physics_server_3d_extension.cpp b/servers/extensions/physics_server_3d_extension.cpp new file mode 100644 index 0000000000..b2a9273538 --- /dev/null +++ b/servers/extensions/physics_server_3d_extension.cpp @@ -0,0 +1,322 @@ +/*************************************************************************/ +/* physics_server_3d_extension.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. */ +/*************************************************************************/ + +#include "physics_server_3d_extension.h" + +bool PhysicsDirectSpaceState3DExtension::is_body_excluded_from_query(const RID &p_body) const { + return exclude && exclude->has(p_body); +} + +thread_local const Set<RID> *PhysicsDirectSpaceState3DExtension::exclude = nullptr; + +void PhysicsDirectSpaceState3DExtension::_bind_methods() { + GDVIRTUAL_BIND(_intersect_ray, "from", "to", "collision_mask", "collide_with_bodies", "collide_with_areas", "hit_from_inside", "hit_back_faces", "result"); + GDVIRTUAL_BIND(_intersect_point, "position", "collision_mask", "collide_with_bodies", "collide_with_areas", "results", "max_results"); + GDVIRTUAL_BIND(_intersect_shape, "shape_rid", "transform", "motion", "margin", "collision_mask", "collide_with_bodies", "collide_with_areas", "result_count", "max_results"); + GDVIRTUAL_BIND(_cast_motion, "shape_rid", "transform", "motion", "margin", "collision_mask", "collide_with_bodies", "collide_with_areas", "closest_safe", "closest_unsafe", "info"); + GDVIRTUAL_BIND(_collide_shape, "shape_rid", "transform", "motion", "margin", "collision_mask", "collide_with_bodies", "collide_with_areas", "results", "max_results", "result_count"); + GDVIRTUAL_BIND(_rest_info, "shape_rid", "transform", "motion", "margin", "collision_mask", "collide_with_bodies", "collide_with_areas", "rest_info"); + GDVIRTUAL_BIND(_get_closest_point_to_object_volume, "object", "point"); +} + +PhysicsDirectSpaceState3DExtension::PhysicsDirectSpaceState3DExtension() { +} + +void PhysicsDirectBodyState3DExtension::_bind_methods() { + GDVIRTUAL_BIND(_get_total_gravity); + GDVIRTUAL_BIND(_get_total_linear_damp); + GDVIRTUAL_BIND(_get_total_angular_damp); + + GDVIRTUAL_BIND(_get_center_of_mass); + GDVIRTUAL_BIND(_get_center_of_mass_local); + GDVIRTUAL_BIND(_get_principal_inertia_axes); + + GDVIRTUAL_BIND(_get_inverse_mass); + GDVIRTUAL_BIND(_get_inverse_inertia); + + GDVIRTUAL_BIND(_set_linear_velocity, "velocity"); + GDVIRTUAL_BIND(_get_linear_velocity); + + GDVIRTUAL_BIND(_set_angular_velocity, "velocity"); + GDVIRTUAL_BIND(_get_angular_velocity); + + GDVIRTUAL_BIND(_set_transform, "transform"); + GDVIRTUAL_BIND(_get_transform); + + GDVIRTUAL_BIND(_get_velocity_at_local_position, "local_position"); + + GDVIRTUAL_BIND(_apply_central_impulse, "impulse"); + GDVIRTUAL_BIND(_apply_impulse, "impulse", "position"); + GDVIRTUAL_BIND(_apply_torque_impulse, "impulse"); + + GDVIRTUAL_BIND(_apply_central_force, "force"); + GDVIRTUAL_BIND(_apply_force, "force", "position"); + GDVIRTUAL_BIND(_apply_torque, "torque"); + + GDVIRTUAL_BIND(_add_constant_central_force, "force"); + GDVIRTUAL_BIND(_add_constant_force, "force", "position"); + GDVIRTUAL_BIND(_add_constant_torque, "torque"); + + GDVIRTUAL_BIND(_set_constant_force, "force"); + GDVIRTUAL_BIND(_get_constant_force); + + GDVIRTUAL_BIND(_set_constant_torque, "torque"); + GDVIRTUAL_BIND(_get_constant_torque); + + GDVIRTUAL_BIND(_set_sleep_state, "enabled"); + GDVIRTUAL_BIND(_is_sleeping); + + GDVIRTUAL_BIND(_get_contact_count); + + GDVIRTUAL_BIND(_get_contact_local_position, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_local_normal, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_impulse, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_local_shape, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_collider, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_collider_position, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_collider_id, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_collider_object, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_collider_shape, "contact_idx"); + GDVIRTUAL_BIND(_get_contact_collider_velocity_at_position, "contact_idx"); + GDVIRTUAL_BIND(_get_step); + GDVIRTUAL_BIND(_integrate_forces); + GDVIRTUAL_BIND(_get_space_state); +} + +PhysicsDirectBodyState3DExtension::PhysicsDirectBodyState3DExtension() { +} + +thread_local const Set<RID> *PhysicsServer3DExtension::exclude_bodies = nullptr; +thread_local const Set<ObjectID> *PhysicsServer3DExtension::exclude_objects = nullptr; + +bool PhysicsServer3DExtension::body_test_motion_is_excluding_body(RID p_body) const { + return exclude_bodies && exclude_bodies->has(p_body); +} + +bool PhysicsServer3DExtension::body_test_motion_is_excluding_object(ObjectID p_object) const { + return exclude_objects && exclude_objects->has(p_object); +} + +void PhysicsServer3DExtension::_bind_methods() { + GDVIRTUAL_BIND(_world_boundary_shape_create); + GDVIRTUAL_BIND(_separation_ray_shape_create); + GDVIRTUAL_BIND(_sphere_shape_create); + GDVIRTUAL_BIND(_box_shape_create); + GDVIRTUAL_BIND(_capsule_shape_create); + GDVIRTUAL_BIND(_cylinder_shape_create); + GDVIRTUAL_BIND(_convex_polygon_shape_create); + GDVIRTUAL_BIND(_concave_polygon_shape_create); + GDVIRTUAL_BIND(_heightmap_shape_create); + GDVIRTUAL_BIND(_custom_shape_create); + + GDVIRTUAL_BIND(_shape_set_data, "shape", "data"); + + GDVIRTUAL_BIND(_shape_get_type, "shape"); + GDVIRTUAL_BIND(_shape_get_data, "shape"); + + GDVIRTUAL_BIND(_space_create); + GDVIRTUAL_BIND(_space_set_active, "space", "active"); + GDVIRTUAL_BIND(_space_is_active, "space"); + GDVIRTUAL_BIND(_space_set_param, "space", "param", "value"); + GDVIRTUAL_BIND(_space_get_param, "space", "param"); + GDVIRTUAL_BIND(_space_get_direct_state, "space"); + + GDVIRTUAL_BIND(_area_create); + GDVIRTUAL_BIND(_area_set_space, "area", "space"); + GDVIRTUAL_BIND(_area_get_space, "area"); + + GDVIRTUAL_BIND(_area_add_shape, "area", "shape", "transform", "disabled"); + GDVIRTUAL_BIND(_area_set_shape, "area", "shape_idx", "shape"); + GDVIRTUAL_BIND(_area_set_shape_transform, "area", "shape_idx", "transform"); + GDVIRTUAL_BIND(_area_set_shape_disabled, "area", "shape_idx", "disabled"); + + GDVIRTUAL_BIND(_area_get_shape_count, "area"); + GDVIRTUAL_BIND(_area_get_shape, "area", "shape_idx"); + GDVIRTUAL_BIND(_area_get_shape_transform, "area", "shape_idx"); + + GDVIRTUAL_BIND(_area_remove_shape, "area", "shape_idx"); + GDVIRTUAL_BIND(_area_clear_shapes, "area"); + + GDVIRTUAL_BIND(_area_set_collision_layer, "area", "layer"); + GDVIRTUAL_BIND(_area_set_collision_mask, "area", "mask"); + + GDVIRTUAL_BIND(_area_set_param, "area", "param", "value"); + GDVIRTUAL_BIND(_area_set_transform, "area", "transform"); + + GDVIRTUAL_BIND(_area_get_param, "area", "param"); + GDVIRTUAL_BIND(_area_get_transform, "area"); + + GDVIRTUAL_BIND(_area_attach_object_instance_id, "area", "id"); + GDVIRTUAL_BIND(_area_get_object_instance_id, "area"); + + GDVIRTUAL_BIND(_area_set_monitor_callback, "area", "callback"); + GDVIRTUAL_BIND(_area_set_area_monitor_callback, "area", "callback"); + GDVIRTUAL_BIND(_area_set_monitorable, "area", "monitorable"); + + GDVIRTUAL_BIND(_area_set_ray_pickable, "area", "enable"); + + GDVIRTUAL_BIND(_body_create); + + GDVIRTUAL_BIND(_body_set_space, "body", "space"); + GDVIRTUAL_BIND(_body_get_space, "body"); + + GDVIRTUAL_BIND(_body_set_mode, "body", "mode"); + GDVIRTUAL_BIND(_body_get_mode, "body"); + + GDVIRTUAL_BIND(_body_set_collision_layer, "body", "layer"); + GDVIRTUAL_BIND(_body_get_collision_layer, "body"); + + GDVIRTUAL_BIND(_body_set_collision_mask, "body", "mask"); + GDVIRTUAL_BIND(_body_get_collision_mask, "body"); + + GDVIRTUAL_BIND(_body_add_shape, "body", "shape", "transform", "disabled"); + GDVIRTUAL_BIND(_body_set_shape, "body", "shape_idx", "shape"); + GDVIRTUAL_BIND(_body_set_shape_transform, "body", "shape_idx", "transform"); + GDVIRTUAL_BIND(_body_set_shape_disabled, "body", "shape_idx", "disabled"); + + GDVIRTUAL_BIND(_body_get_shape_count, "body"); + GDVIRTUAL_BIND(_body_get_shape, "body", "shape_idx"); + GDVIRTUAL_BIND(_body_get_shape_transform, "body", "shape_idx"); + + GDVIRTUAL_BIND(_body_remove_shape, "body", "shape_idx"); + GDVIRTUAL_BIND(_body_clear_shapes, "body"); + + GDVIRTUAL_BIND(_body_attach_object_instance_id, "body", "id"); + GDVIRTUAL_BIND(_body_get_object_instance_id, "body"); + + GDVIRTUAL_BIND(_body_set_enable_continuous_collision_detection, "body", "enable"); + GDVIRTUAL_BIND(_body_is_continuous_collision_detection_enabled, "body"); + + GDVIRTUAL_BIND(_body_set_param, "body", "param", "value"); + GDVIRTUAL_BIND(_body_get_param, "body", "param"); + + GDVIRTUAL_BIND(_body_reset_mass_properties, "body"); + + GDVIRTUAL_BIND(_body_set_state, "body", "state", "value"); + GDVIRTUAL_BIND(_body_get_state, "body", "state"); + + GDVIRTUAL_BIND(_body_apply_central_impulse, "body", "impulse"); + GDVIRTUAL_BIND(_body_apply_impulse, "body", "impulse", "position"); + GDVIRTUAL_BIND(_body_apply_torque_impulse, "body", "impulse"); + + GDVIRTUAL_BIND(_body_apply_central_force, "body", "force"); + GDVIRTUAL_BIND(_body_apply_force, "body", "force", "position"); + GDVIRTUAL_BIND(_body_apply_torque, "body", "torque"); + + GDVIRTUAL_BIND(_body_add_constant_central_force, "body", "force"); + GDVIRTUAL_BIND(_body_add_constant_force, "body", "force", "position"); + GDVIRTUAL_BIND(_body_add_constant_torque, "body", "torque"); + + GDVIRTUAL_BIND(_body_set_constant_force, "body", "force"); + GDVIRTUAL_BIND(_body_get_constant_force, "body"); + + GDVIRTUAL_BIND(_body_set_constant_torque, "body", "torque"); + GDVIRTUAL_BIND(_body_get_constant_torque, "body"); + + GDVIRTUAL_BIND(_body_set_axis_velocity, "body", "axis_velocity"); + + GDVIRTUAL_BIND(_body_set_axis_lock, "body", "axis", "lock"); + GDVIRTUAL_BIND(_body_is_axis_locked, "body", "axis"); + + GDVIRTUAL_BIND(_body_add_collision_exception, "body", "excepted_body"); + GDVIRTUAL_BIND(_body_remove_collision_exception, "body", "excepted_body"); + + GDVIRTUAL_BIND(_body_set_max_contacts_reported, "body", "amount"); + GDVIRTUAL_BIND(_body_get_max_contacts_reported, "body"); + + GDVIRTUAL_BIND(_body_set_omit_force_integration, "body", "enable"); + GDVIRTUAL_BIND(_body_is_omitting_force_integration, "body"); + + GDVIRTUAL_BIND(_body_set_force_integration_callback, "body", "callable", "userdata"); + + GDVIRTUAL_BIND(_body_set_ray_pickable, "body", "enable"); + + GDVIRTUAL_BIND(_body_test_motion, "body", "from", "motion", "margin", "max_collisions", "collide_separation_ray", "result"); + + GDVIRTUAL_BIND(_body_get_direct_state, "body"); + + GDVIRTUAL_BIND(_soft_body_get_bounds, "body"); + + GDVIRTUAL_BIND(_joint_create); + GDVIRTUAL_BIND(_joint_clear, "joint"); + + GDVIRTUAL_BIND(_joint_make_pin, "joint", "body_A", "local_A", "body_B", "local_B"); + GDVIRTUAL_BIND(_pin_joint_set_param, "joint", "param", "value"); + GDVIRTUAL_BIND(_pin_joint_get_param, "joint", "param"); + + GDVIRTUAL_BIND(_pin_joint_set_local_a, "joint", "local_A"); + GDVIRTUAL_BIND(_pin_joint_get_local_a, "joint"); + + GDVIRTUAL_BIND(_pin_joint_set_local_b, "joint", "local_B"); + GDVIRTUAL_BIND(_pin_joint_get_local_b, "joint"); + + GDVIRTUAL_BIND(_joint_make_hinge, "joint", "body_A", "hinge_A", "body_B", "hinge_B"); + + GDVIRTUAL_BIND(_hinge_joint_set_param, "joint", "param", "value"); + GDVIRTUAL_BIND(_hinge_joint_get_param, "joint", "param"); + + GDVIRTUAL_BIND(_hinge_joint_set_flag, "joint", "flag", "enabled"); + GDVIRTUAL_BIND(_hinge_joint_get_flag, "joint", "flag"); + + GDVIRTUAL_BIND(_joint_make_slider, "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"); + + GDVIRTUAL_BIND(_slider_joint_set_param, "joint", "param", "value"); + GDVIRTUAL_BIND(_slider_joint_get_param, "joint", "param"); + + GDVIRTUAL_BIND(_joint_make_cone_twist, "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"); + + GDVIRTUAL_BIND(_cone_twist_joint_set_param, "joint", "param", "value"); + GDVIRTUAL_BIND(_cone_twist_joint_get_param, "joint", "param"); + + GDVIRTUAL_BIND(_joint_get_type, "joint"); + + GDVIRTUAL_BIND(_joint_set_solver_priority, "joint", "priority"); + GDVIRTUAL_BIND(_joint_get_solver_priority, "joint"); + + GDVIRTUAL_BIND(_joint_make_generic_6dof, "joint", "body_A", "local_ref_A", "body_B", "local_ref_B"); + + GDVIRTUAL_BIND(_generic_6dof_joint_set_param, "joint", "axis", "param", "value"); + GDVIRTUAL_BIND(_generic_6dof_joint_get_param, "joint", "axis", "param"); + + GDVIRTUAL_BIND(_generic_6dof_joint_set_flag, "joint", "axis", "flag", "enable"); + GDVIRTUAL_BIND(_generic_6dof_joint_get_flag, "joint", "axis", "flag"); + + GDVIRTUAL_BIND(_free_rid, "rid"); + + GDVIRTUAL_BIND(_set_active, "active"); + + GDVIRTUAL_BIND(_get_process_info, "process_info"); +} + +PhysicsServer3DExtension::PhysicsServer3DExtension() { +} + +PhysicsServer3DExtension::~PhysicsServer3DExtension() { +} diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h new file mode 100644 index 0000000000..b40ab8a295 --- /dev/null +++ b/servers/extensions/physics_server_3d_extension.h @@ -0,0 +1,548 @@ +/*************************************************************************/ +/* physics_server_3d_extension.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 PHYSICS_SERVER_3D_EXTENSION_H +#define PHYSICS_SERVER_3D_EXTENSION_H + +#include "core/object/script_language.h" +#include "core/variant/native_ptr.h" +#include "core/variant/type_info.h" +#include "core/variant/typed_array.h" +#include "servers/extensions/ext_wrappers.gen.inc" +#include "servers/physics_server_3d.h" + +class PhysicsDirectBodyState3DExtension : public PhysicsDirectBodyState3D { + GDCLASS(PhysicsDirectBodyState3DExtension, PhysicsDirectBodyState3D); + +protected: + static void _bind_methods(); + +public: + // The warning is valid, but unavoidable. If the function is not overriden it will error anyway. + + EXBIND0RC(Vector3, get_total_gravity) + EXBIND0RC(real_t, get_total_angular_damp) + EXBIND0RC(real_t, get_total_linear_damp) + + EXBIND0RC(Vector3, get_center_of_mass) + EXBIND0RC(Vector3, get_center_of_mass_local) + EXBIND0RC(Basis, get_principal_inertia_axes) + EXBIND0RC(real_t, get_inverse_mass) + EXBIND0RC(Vector3, get_inverse_inertia) + EXBIND0RC(Basis, get_inverse_inertia_tensor) + + EXBIND1(set_linear_velocity, const Vector3 &) + EXBIND0RC(Vector3, get_linear_velocity) + + EXBIND1(set_angular_velocity, const Vector3 &) + EXBIND0RC(Vector3, get_angular_velocity) + + EXBIND1(set_transform, const Transform3D &) + EXBIND0RC(Transform3D, get_transform) + + EXBIND1RC(Vector3, get_velocity_at_local_position, const Vector3 &) + + EXBIND1(apply_central_impulse, const Vector3 &) + EXBIND2(apply_impulse, const Vector3 &, const Vector3 &) + EXBIND1(apply_torque_impulse, const Vector3 &) + + EXBIND1(apply_central_force, const Vector3 &) + EXBIND2(apply_force, const Vector3 &, const Vector3 &) + EXBIND1(apply_torque, const Vector3 &) + + EXBIND1(add_constant_central_force, const Vector3 &) + EXBIND2(add_constant_force, const Vector3 &, const Vector3 &) + EXBIND1(add_constant_torque, const Vector3 &) + + EXBIND1(set_constant_force, const Vector3 &) + EXBIND0RC(Vector3, get_constant_force) + + EXBIND1(set_constant_torque, const Vector3 &) + EXBIND0RC(Vector3, get_constant_torque) + + EXBIND1(set_sleep_state, bool) + EXBIND0RC(bool, is_sleeping) + + EXBIND0RC(int, get_contact_count) + + EXBIND1RC(Vector3, get_contact_local_position, int) + EXBIND1RC(Vector3, get_contact_local_normal, int) + EXBIND1RC(real_t, get_contact_impulse, int) + EXBIND1RC(int, get_contact_local_shape, int) + EXBIND1RC(RID, get_contact_collider, int) + EXBIND1RC(Vector3, get_contact_collider_position, int) + EXBIND1RC(ObjectID, get_contact_collider_id, int) + EXBIND1RC(Object *, get_contact_collider_object, int) + EXBIND1RC(int, get_contact_collider_shape, int) + EXBIND1RC(Vector3, get_contact_collider_velocity_at_position, int) + + EXBIND0RC(real_t, get_step) + + EXBIND0(integrate_forces) + EXBIND0R(PhysicsDirectSpaceState3D *, get_space_state) + + PhysicsDirectBodyState3DExtension(); +}; + +typedef PhysicsDirectSpaceState3D::RayResult PhysicsServer3DExtensionRayResult; +typedef PhysicsDirectSpaceState3D::ShapeResult PhysicsServer3DExtensionShapeResult; +typedef PhysicsDirectSpaceState3D::ShapeRestInfo PhysicsServer3DExtensionShapeRestInfo; + +GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionRayResult) +GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionShapeResult) +GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionShapeRestInfo) + +class PhysicsDirectSpaceState3DExtension : public PhysicsDirectSpaceState3D { + GDCLASS(PhysicsDirectSpaceState3DExtension, PhysicsDirectSpaceState3D); + + thread_local static const Set<RID> *exclude; + +protected: + static void _bind_methods(); + bool is_body_excluded_from_query(const RID &p_body) const; + + GDVIRTUAL8R(bool, _intersect_ray, const Vector3 &, const Vector3 &, uint32_t, bool, bool, bool, bool, GDNativePtr<PhysicsServer3DExtensionRayResult>) + GDVIRTUAL6R(int, _intersect_point, const Vector3 &, uint32_t, bool, bool, GDNativePtr<PhysicsServer3DExtensionShapeResult>, int) + GDVIRTUAL9R(int, _intersect_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDNativePtr<PhysicsServer3DExtensionShapeResult>, int) + GDVIRTUAL10R(bool, _cast_motion, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDNativePtr<real_t>, GDNativePtr<real_t>, GDNativePtr<PhysicsServer3DExtensionShapeRestInfo>) + GDVIRTUAL10R(bool, _collide_shape, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDNativePtr<Vector3>, int, GDNativePtr<int>) + GDVIRTUAL8R(bool, _rest_info, RID, const Transform3D &, const Vector3 &, real_t, uint32_t, bool, bool, GDNativePtr<PhysicsServer3DExtensionShapeRestInfo>) + GDVIRTUAL2RC(Vector3, _get_closest_point_to_object_volume, RID, const Vector3 &) + +public: + virtual bool intersect_ray(const RayParameters &p_parameters, RayResult &r_result) override { + exclude = &p_parameters.exclude; + bool ret = false; + GDVIRTUAL_REQUIRED_CALL(_intersect_ray, p_parameters.from, p_parameters.to, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, p_parameters.hit_from_inside, p_parameters.hit_back_faces, &r_result, ret); + exclude = nullptr; + return ret; + } + virtual int intersect_point(const PointParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { + exclude = &p_parameters.exclude; + int ret = false; + GDVIRTUAL_REQUIRED_CALL(_intersect_point, p_parameters.position, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); + exclude = nullptr; + return ret; + } + virtual int intersect_shape(const ShapeParameters &p_parameters, ShapeResult *r_results, int p_result_max) override { + exclude = &p_parameters.exclude; + int ret = 0; + GDVIRTUAL_REQUIRED_CALL(_intersect_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, ret); + exclude = nullptr; + return ret; + } + virtual bool cast_motion(const ShapeParameters &p_parameters, real_t &p_closest_safe, real_t &p_closest_unsafe, ShapeRestInfo *r_info = nullptr) override { + exclude = &p_parameters.exclude; + bool ret = false; + GDVIRTUAL_REQUIRED_CALL(_cast_motion, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, &p_closest_safe, &p_closest_unsafe, r_info, ret); + exclude = nullptr; + return ret; + } + virtual bool collide_shape(const ShapeParameters &p_parameters, Vector3 *r_results, int p_result_max, int &r_result_count) override { + exclude = &p_parameters.exclude; + bool ret = false; + GDVIRTUAL_REQUIRED_CALL(_collide_shape, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_results, p_result_max, &r_result_count, ret); + exclude = nullptr; + return ret; + } + virtual bool rest_info(const ShapeParameters &p_parameters, ShapeRestInfo *r_info) override { + exclude = &p_parameters.exclude; + bool ret = false; + GDVIRTUAL_REQUIRED_CALL(_rest_info, p_parameters.shape_rid, p_parameters.transform, p_parameters.motion, p_parameters.margin, p_parameters.collision_mask, p_parameters.collide_with_bodies, p_parameters.collide_with_areas, r_info, ret); + exclude = nullptr; + return ret; + } + + virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const override { + Vector3 ret; + GDVIRTUAL_REQUIRED_CALL(_get_closest_point_to_object_volume, p_object, p_point, ret); + return ret; + } + + PhysicsDirectSpaceState3DExtension(); +}; + +typedef PhysicsServer3D::MotionCollision PhysicsServer3DExtensionMotionCollision; +typedef PhysicsServer3D::MotionResult PhysicsServer3DExtensionMotionResult; + +struct PhysicsServer3DExtensionStateCallback { + void *instance; + void (*callback)(void *p_instance, PhysicsDirectBodyState3D *p_state); +}; + +GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionMotionCollision) +GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionMotionResult) +GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionStateCallback) + +class PhysicsServer3DExtension : public PhysicsServer3D { + GDCLASS(PhysicsServer3DExtension, PhysicsServer3D); + +protected: + static void _bind_methods(); + +public: + // The warning is valid, but unavoidable. If the function is not overriden it will error anyway. + + EXBIND0R(RID, world_boundary_shape_create) + EXBIND0R(RID, separation_ray_shape_create) + EXBIND0R(RID, sphere_shape_create) + EXBIND0R(RID, box_shape_create) + EXBIND0R(RID, capsule_shape_create) + EXBIND0R(RID, cylinder_shape_create) + EXBIND0R(RID, convex_polygon_shape_create) + EXBIND0R(RID, concave_polygon_shape_create) + EXBIND0R(RID, heightmap_shape_create) + EXBIND0R(RID, custom_shape_create) + + EXBIND2(shape_set_data, RID, const Variant &) + EXBIND2(shape_set_custom_solver_bias, RID, real_t) + + EXBIND2(shape_set_margin, RID, real_t) + EXBIND1RC(real_t, shape_get_margin, RID) + + EXBIND1RC(ShapeType, shape_get_type, RID) + EXBIND1RC(Variant, shape_get_data, RID) + EXBIND1RC(real_t, shape_get_custom_solver_bias, RID) + + /* SPACE API */ + + EXBIND0R(RID, space_create) + EXBIND2(space_set_active, RID, bool) + EXBIND1RC(bool, space_is_active, RID) + + EXBIND3(space_set_param, RID, SpaceParameter, real_t) + EXBIND2RC(real_t, space_get_param, RID, SpaceParameter) + + EXBIND1R(PhysicsDirectSpaceState3D *, space_get_direct_state, RID) + + EXBIND2(space_set_debug_contacts, RID, int) + EXBIND1RC(Vector<Vector3>, space_get_contacts, RID) + EXBIND1RC(int, space_get_contact_count, RID) + + /* AREA API */ + + //EXBIND0RID(area); + EXBIND0R(RID, area_create) + + EXBIND2(area_set_space, RID, RID) + EXBIND1RC(RID, area_get_space, RID) + + EXBIND4(area_add_shape, RID, RID, const Transform3D &, bool) + EXBIND3(area_set_shape, RID, int, RID) + EXBIND3(area_set_shape_transform, RID, int, const Transform3D &) + EXBIND3(area_set_shape_disabled, RID, int, bool) + + EXBIND1RC(int, area_get_shape_count, RID) + EXBIND2RC(RID, area_get_shape, RID, int) + EXBIND2RC(Transform3D, area_get_shape_transform, RID, int) + EXBIND2(area_remove_shape, RID, int) + EXBIND1(area_clear_shapes, RID) + + EXBIND2(area_attach_object_instance_id, RID, ObjectID) + EXBIND1RC(ObjectID, area_get_object_instance_id, RID) + + EXBIND3(area_set_param, RID, AreaParameter, const Variant &) + EXBIND2(area_set_transform, RID, const Transform3D &) + + EXBIND2RC(Variant, area_get_param, RID, AreaParameter) + EXBIND1RC(Transform3D, area_get_transform, RID) + + EXBIND2(area_set_collision_mask, RID, uint32_t) + EXBIND2(area_set_collision_layer, RID, uint32_t) + + EXBIND2(area_set_monitorable, RID, bool) + EXBIND2(area_set_ray_pickable, RID, bool) + + EXBIND2(area_set_monitor_callback, RID, const Callable &) + EXBIND2(area_set_area_monitor_callback, RID, const Callable &) + + /* BODY API */ + + //EXBIND2RID(body,BodyMode,bool); + EXBIND0R(RID, body_create) + + EXBIND2(body_set_space, RID, RID) + EXBIND1RC(RID, body_get_space, RID) + + EXBIND2(body_set_mode, RID, BodyMode) + EXBIND1RC(BodyMode, body_get_mode, RID) + + EXBIND4(body_add_shape, RID, RID, const Transform3D &, bool) + EXBIND3(body_set_shape, RID, int, RID) + EXBIND3(body_set_shape_transform, RID, int, const Transform3D &) + + EXBIND1RC(int, body_get_shape_count, RID) + EXBIND2RC(Transform3D, body_get_shape_transform, RID, int) + EXBIND2RC(RID, body_get_shape, RID, int) + + EXBIND3(body_set_shape_disabled, RID, int, bool) + + EXBIND2(body_remove_shape, RID, int) + EXBIND1(body_clear_shapes, RID) + + EXBIND2(body_attach_object_instance_id, RID, ObjectID) + EXBIND1RC(ObjectID, body_get_object_instance_id, RID) + + EXBIND2(body_set_enable_continuous_collision_detection, RID, bool) + EXBIND1RC(bool, body_is_continuous_collision_detection_enabled, RID) + + EXBIND2(body_set_collision_layer, RID, uint32_t) + EXBIND1RC(uint32_t, body_get_collision_layer, RID) + + EXBIND2(body_set_collision_mask, RID, uint32_t) + EXBIND1RC(uint32_t, body_get_collision_mask, RID) + + EXBIND2(body_set_user_flags, RID, uint32_t) + EXBIND1RC(uint32_t, body_get_user_flags, RID) + + EXBIND3(body_set_param, RID, BodyParameter, const Variant &) + EXBIND2RC(Variant, body_get_param, RID, BodyParameter) + + EXBIND1(body_reset_mass_properties, RID) + + EXBIND3(body_set_state, RID, BodyState, const Variant &) + EXBIND2RC(Variant, body_get_state, RID, BodyState) + + EXBIND2(body_apply_torque_impulse, RID, const Vector3 &) + EXBIND2(body_apply_central_impulse, RID, const Vector3 &) + EXBIND3(body_apply_impulse, RID, const Vector3 &, const Vector3 &) + + EXBIND2(body_apply_central_force, RID, const Vector3 &) + EXBIND3(body_apply_force, RID, const Vector3 &, const Vector3 &) + EXBIND2(body_apply_torque, RID, const Vector3 &) + + EXBIND2(body_add_constant_central_force, RID, const Vector3 &) + EXBIND3(body_add_constant_force, RID, const Vector3 &, const Vector3 &) + EXBIND2(body_add_constant_torque, RID, const Vector3 &) + + EXBIND2(body_set_constant_force, RID, const Vector3 &) + EXBIND1RC(Vector3, body_get_constant_force, RID) + + EXBIND2(body_set_constant_torque, RID, const Vector3 &) + EXBIND1RC(Vector3, body_get_constant_torque, RID) + + EXBIND2(body_set_axis_velocity, RID, const Vector3 &) + + EXBIND3(body_set_axis_lock, RID, BodyAxis, bool) + EXBIND2RC(bool, body_is_axis_locked, RID, BodyAxis) + + EXBIND2(body_add_collision_exception, RID, RID) + EXBIND2(body_remove_collision_exception, RID, RID) + + GDVIRTUAL1RC(TypedArray<RID>, _body_get_collision_exceptions, RID) + + void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) override { + TypedArray<RID> ret; + GDVIRTUAL_REQUIRED_CALL(_body_get_collision_exceptions, p_body, ret); + for (int i = 0; i < ret.size(); i++) { + p_exceptions->push_back(ret[i]); + } + } + + EXBIND2(body_set_max_contacts_reported, RID, int) + EXBIND1RC(int, body_get_max_contacts_reported, RID) + + EXBIND2(body_set_contacts_reported_depth_threshold, RID, real_t) + EXBIND1RC(real_t, body_get_contacts_reported_depth_threshold, RID) + + EXBIND2(body_set_omit_force_integration, RID, bool) + EXBIND1RC(bool, body_is_omitting_force_integration, RID) + + GDVIRTUAL2(_body_set_state_sync_callback, RID, GDNativePtr<PhysicsServer3DExtensionStateCallback>) + void body_set_state_sync_callback(RID p_body, void *p_instance, BodyStateCallback p_callback) override { + PhysicsServer3DExtensionStateCallback callback; + callback.callback = p_callback; + callback.instance = p_instance; + GDVIRTUAL_REQUIRED_CALL(_body_set_state_sync_callback, p_body, &callback); + } + EXBIND3(body_set_force_integration_callback, RID, const Callable &, const Variant &) + + EXBIND2(body_set_ray_pickable, RID, bool) + + GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, GDNativePtr<PhysicsServer3DExtensionMotionResult>) + + thread_local static const Set<RID> *exclude_bodies; + thread_local static const Set<ObjectID> *exclude_objects; + + bool body_test_motion_is_excluding_body(RID p_body) const; + bool body_test_motion_is_excluding_object(ObjectID p_object) const; + + bool body_test_motion(RID p_body, const MotionParameters &p_parameters, MotionResult *r_result = nullptr) override { + bool ret = false; + exclude_bodies = &p_parameters.exclude_bodies; + exclude_objects = &p_parameters.exclude_objects; + GDVIRTUAL_REQUIRED_CALL(_body_test_motion, p_body, p_parameters.from, p_parameters.motion, p_parameters.margin, p_parameters.max_collisions, p_parameters.collide_separation_ray, r_result, ret); + exclude_bodies = nullptr; + exclude_objects = nullptr; + return ret; + } + + EXBIND1R(PhysicsDirectBodyState3D *, body_get_direct_state, RID) + + /* SOFT BODY API */ + + EXBIND0R(RID, soft_body_create) + + EXBIND2(soft_body_update_rendering_server, RID, PhysicsServer3DRenderingServerHandler *) + + EXBIND2(soft_body_set_space, RID, RID) + EXBIND1RC(RID, soft_body_get_space, RID) + + EXBIND2(soft_body_set_ray_pickable, RID, bool) + + EXBIND2(soft_body_set_collision_layer, RID, uint32_t) + EXBIND1RC(uint32_t, soft_body_get_collision_layer, RID) + + EXBIND2(soft_body_set_collision_mask, RID, uint32_t) + EXBIND1RC(uint32_t, soft_body_get_collision_mask, RID) + + EXBIND2(soft_body_add_collision_exception, RID, RID) + EXBIND2(soft_body_remove_collision_exception, RID, RID) + + GDVIRTUAL1RC(TypedArray<RID>, _soft_body_get_collision_exceptions, RID) + + void soft_body_get_collision_exceptions(RID p_soft_body, List<RID> *p_exceptions) override { + TypedArray<RID> ret; + GDVIRTUAL_REQUIRED_CALL(_soft_body_get_collision_exceptions, p_soft_body, ret); + for (int i = 0; i < ret.size(); i++) { + p_exceptions->push_back(ret[i]); + } + } + + EXBIND3(soft_body_set_state, RID, BodyState, const Variant &) + EXBIND2RC(Variant, soft_body_get_state, RID, BodyState) + + EXBIND2(soft_body_set_transform, RID, const Transform3D &) + + EXBIND2(soft_body_set_simulation_precision, RID, int) + EXBIND1RC(int, soft_body_get_simulation_precision, RID) + + EXBIND2(soft_body_set_total_mass, RID, real_t) + EXBIND1RC(real_t, soft_body_get_total_mass, RID) + + EXBIND2(soft_body_set_linear_stiffness, RID, real_t) + EXBIND1RC(real_t, soft_body_get_linear_stiffness, RID) + + EXBIND2(soft_body_set_pressure_coefficient, RID, real_t) + EXBIND1RC(real_t, soft_body_get_pressure_coefficient, RID) + + EXBIND2(soft_body_set_damping_coefficient, RID, real_t) + EXBIND1RC(real_t, soft_body_get_damping_coefficient, RID) + + EXBIND2(soft_body_set_drag_coefficient, RID, real_t) + EXBIND1RC(real_t, soft_body_get_drag_coefficient, RID) + + EXBIND2(soft_body_set_mesh, RID, RID) + + EXBIND1RC(AABB, soft_body_get_bounds, RID) + + EXBIND3(soft_body_move_point, RID, int, const Vector3 &) + EXBIND2RC(Vector3, soft_body_get_point_global_position, RID, int) + + EXBIND1(soft_body_remove_all_pinned_points, RID) + EXBIND3(soft_body_pin_point, RID, int, bool) + EXBIND2RC(bool, soft_body_is_point_pinned, RID, int) + + /* JOINT API */ + + EXBIND0R(RID, joint_create) + + EXBIND1(joint_clear, RID) + + EXBIND5(joint_make_pin, RID, RID, const Vector3 &, RID, const Vector3 &) + + EXBIND3(pin_joint_set_param, RID, PinJointParam, real_t) + EXBIND2RC(real_t, pin_joint_get_param, RID, PinJointParam) + + EXBIND2(pin_joint_set_local_a, RID, const Vector3 &) + EXBIND1RC(Vector3, pin_joint_get_local_a, RID) + + EXBIND2(pin_joint_set_local_b, RID, const Vector3 &) + EXBIND1RC(Vector3, pin_joint_get_local_b, RID) + + EXBIND5(joint_make_hinge, RID, RID, const Transform3D &, RID, const Transform3D &) + EXBIND7(joint_make_hinge_simple, RID, RID, const Vector3 &, const Vector3 &, RID, const Vector3 &, const Vector3 &) + + EXBIND3(hinge_joint_set_param, RID, HingeJointParam, real_t) + EXBIND2RC(real_t, hinge_joint_get_param, RID, HingeJointParam) + + EXBIND3(hinge_joint_set_flag, RID, HingeJointFlag, bool) + EXBIND2RC(bool, hinge_joint_get_flag, RID, HingeJointFlag) + + EXBIND5(joint_make_slider, RID, RID, const Transform3D &, RID, const Transform3D &) + + EXBIND3(slider_joint_set_param, RID, SliderJointParam, real_t) + EXBIND2RC(real_t, slider_joint_get_param, RID, SliderJointParam) + + EXBIND5(joint_make_cone_twist, RID, RID, const Transform3D &, RID, const Transform3D &) + + EXBIND3(cone_twist_joint_set_param, RID, ConeTwistJointParam, real_t) + EXBIND2RC(real_t, cone_twist_joint_get_param, RID, ConeTwistJointParam) + + EXBIND5(joint_make_generic_6dof, RID, RID, const Transform3D &, RID, const Transform3D &) + + EXBIND4(generic_6dof_joint_set_param, RID, Vector3::Axis, G6DOFJointAxisParam, real_t) + EXBIND3RC(real_t, generic_6dof_joint_get_param, RID, Vector3::Axis, G6DOFJointAxisParam) + + EXBIND4(generic_6dof_joint_set_flag, RID, Vector3::Axis, G6DOFJointAxisFlag, bool) + EXBIND3RC(bool, generic_6dof_joint_get_flag, RID, Vector3::Axis, G6DOFJointAxisFlag) + + EXBIND1RC(JointType, joint_get_type, RID) + + EXBIND2(joint_set_solver_priority, RID, int) + EXBIND1RC(int, joint_get_solver_priority, RID) + + EXBIND2(joint_disable_collisions_between_bodies, RID, bool) + EXBIND1RC(bool, joint_is_disabled_collisions_between_bodies, RID) + + /* MISC */ + + GDVIRTUAL1(_free_rid, RID) + virtual void free(RID p_rid) override { + GDVIRTUAL_REQUIRED_CALL(_free_rid, p_rid); + } + + EXBIND1(set_active, bool) + + EXBIND0(init) + EXBIND1(step, real_t) + EXBIND0(sync) + EXBIND0(end_sync) + EXBIND0(flush_queries) + EXBIND0(finish) + + EXBIND0RC(bool, is_flushing_queries) + EXBIND1R(int, get_process_info, ProcessInfo) + + PhysicsServer3DExtension(); + ~PhysicsServer3DExtension(); +}; + +#endif // PHYSICSSERVER3DEXTENSION_H diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp index 5a96dae8ca..06f035a506 100644 --- a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp +++ b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp @@ -32,7 +32,9 @@ #include "godot_collision_object_2d.h" GodotBroadPhase2D::ID GodotBroadPhase2DBVH::create(GodotCollisionObject2D *p_object, int p_subindex, const Rect2 &p_aabb, bool p_static) { - ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care? + uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; + uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); + ID oid = bvh.create(p_object, true, tree_id, tree_collision_mask, p_aabb, p_subindex); // Pair everything, don't care? return oid + 1; } @@ -41,8 +43,9 @@ void GodotBroadPhase2DBVH::move(ID p_id, const Rect2 &p_aabb) { } void GodotBroadPhase2DBVH::set_static(ID p_id, bool p_static) { - GodotCollisionObject2D *it = bvh.get(p_id - 1); - bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care? + uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; + uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); + bvh.set_tree(p_id - 1, tree_id, tree_collision_mask, false); } void GodotBroadPhase2DBVH::remove(ID p_id) { @@ -56,7 +59,8 @@ GodotCollisionObject2D *GodotBroadPhase2DBVH::get_object(ID p_id) const { } bool GodotBroadPhase2DBVH::is_static(ID p_id) const { - return !bvh.is_pairable(p_id - 1); + uint32_t tree_id = bvh.get_tree_id(p_id - 1); + return tree_id == 0; } int GodotBroadPhase2DBVH::get_subindex(ID p_id) const { @@ -64,11 +68,11 @@ int GodotBroadPhase2DBVH::get_subindex(ID p_id) const { } int GodotBroadPhase2DBVH::cull_segment(const Vector2 &p_from, const Vector2 &p_to, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); + return bvh.cull_segment(p_from, p_to, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } int GodotBroadPhase2DBVH::cull_aabb(const Rect2 &p_aabb, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); + return bvh.cull_aabb(p_aabb, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } void *GodotBroadPhase2DBVH::_pair_callback(void *self, uint32_t p_A, GodotCollisionObject2D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject2D *p_object_B, int subindex_B) { diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.h b/servers/physics_2d/godot_broad_phase_2d_bvh.h index d77e0574eb..b11ad0e75e 100644 --- a/servers/physics_2d/godot_broad_phase_2d_bvh.h +++ b/servers/physics_2d/godot_broad_phase_2d_bvh.h @@ -38,7 +38,34 @@ #include "core/math/vector2.h" class GodotBroadPhase2DBVH : public GodotBroadPhase2D { - BVH_Manager<GodotCollisionObject2D, true, 128, Rect2, Vector2> bvh; + template <class T> + class UserPairTestFunction { + public: + static bool user_pair_check(const T *p_a, const T *p_b) { + // return false if no collision, decided by masks etc + return p_a->interacts_with(p_b); + } + }; + + template <class T> + class UserCullTestFunction { + public: + static bool user_cull_check(const T *p_a, const T *p_b) { + return true; + } + }; + + enum Tree { + TREE_STATIC = 0, + TREE_DYNAMIC = 1, + }; + + enum TreeFlag { + TREE_FLAG_STATIC = 1 << TREE_STATIC, + TREE_FLAG_DYNAMIC = 1 << TREE_DYNAMIC, + }; + + BVH_Manager<GodotCollisionObject2D, 2, true, 128, UserPairTestFunction<GodotCollisionObject2D>, UserCullTestFunction<GodotCollisionObject2D>, Rect2, Vector2> bvh; static void *_pair_callback(void *, uint32_t, GodotCollisionObject2D *, int, uint32_t, GodotCollisionObject2D *, int); static void _unpair_callback(void *, uint32_t, GodotCollisionObject2D *, int, uint32_t, GodotCollisionObject2D *, int, void *); diff --git a/servers/physics_2d/godot_collision_object_2d.h b/servers/physics_2d/godot_collision_object_2d.h index 1e9baad8d9..19d6e91561 100644 --- a/servers/physics_2d/godot_collision_object_2d.h +++ b/servers/physics_2d/godot_collision_object_2d.h @@ -180,7 +180,7 @@ public: return p_other->collision_layer & collision_mask; } - _FORCE_INLINE_ bool interacts_with(GodotCollisionObject2D *p_other) const { + _FORCE_INLINE_ bool interacts_with(const GodotCollisionObject2D *p_other) const { return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask; } diff --git a/servers/physics_2d/godot_joints_2d.cpp b/servers/physics_2d/godot_joints_2d.cpp index 0876184d8c..0c21b08ea9 100644 --- a/servers/physics_2d/godot_joints_2d.cpp +++ b/servers/physics_2d/godot_joints_2d.cpp @@ -118,22 +118,26 @@ bool GodotPinJoint2D::setup(real_t p_step) { K1[0].y = 0.0f; K1[1].y = A->get_inv_mass() + B_inv_mass; + Vector2 r1 = rA - A->get_center_of_mass(); + Transform2D K2; - K2[0].x = A->get_inv_inertia() * rA.y * rA.y; - K2[1].x = -A->get_inv_inertia() * rA.x * rA.y; - K2[0].y = -A->get_inv_inertia() * rA.x * rA.y; - K2[1].y = A->get_inv_inertia() * rA.x * rA.x; + K2[0].x = A->get_inv_inertia() * r1.y * r1.y; + K2[1].x = -A->get_inv_inertia() * r1.x * r1.y; + K2[0].y = -A->get_inv_inertia() * r1.x * r1.y; + K2[1].y = A->get_inv_inertia() * r1.x * r1.x; Transform2D K; K[0] = K1[0] + K2[0]; K[1] = K1[1] + K2[1]; if (B) { + Vector2 r2 = rB - B->get_center_of_mass(); + Transform2D K3; - K3[0].x = B->get_inv_inertia() * rB.y * rB.y; - K3[1].x = -B->get_inv_inertia() * rB.x * rB.y; - K3[0].y = -B->get_inv_inertia() * rB.x * rB.y; - K3[1].y = B->get_inv_inertia() * rB.x * rB.x; + K3[0].x = B->get_inv_inertia() * r2.y * r2.y; + K3[1].x = -B->get_inv_inertia() * r2.x * r2.y; + K3[0].y = -B->get_inv_inertia() * r2.x * r2.y; + K3[1].y = B->get_inv_inertia() * r2.x * r2.x; K[0] += K3[0]; K[1] += K3[1]; diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp index 68dac67d21..04b8d3c741 100644 --- a/servers/physics_2d/godot_space_2d.cpp +++ b/servers/physics_2d/godot_space_2d.cpp @@ -995,11 +995,8 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D:: return collided; } +// Assumes a valid collision pair, this should have been checked beforehand in the BVH or octree. void *GodotSpace2D::_broadphase_pair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_self) { - if (!A->interacts_with(B)) { - return nullptr; - } - GodotCollisionObject2D::Type type_A = A->get_type(); GodotCollisionObject2D::Type type_B = B->get_type(); if (type_A > type_B) { diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp index 9a6b96c411..ecdf74fd41 100644 --- a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp +++ b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp @@ -33,7 +33,9 @@ #include "godot_collision_object_3d.h" GodotBroadPhase3DBVH::ID GodotBroadPhase3DBVH::create(GodotCollisionObject3D *p_object, int p_subindex, const AABB &p_aabb, bool p_static) { - ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care? + uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; + uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); + ID oid = bvh.create(p_object, true, tree_id, tree_collision_mask, p_aabb, p_subindex); // Pair everything, don't care? return oid + 1; } @@ -42,8 +44,9 @@ void GodotBroadPhase3DBVH::move(ID p_id, const AABB &p_aabb) { } void GodotBroadPhase3DBVH::set_static(ID p_id, bool p_static) { - GodotCollisionObject3D *it = bvh.get(p_id - 1); - bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care? + uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; + uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); + bvh.set_tree(p_id - 1, tree_id, tree_collision_mask, false); } void GodotBroadPhase3DBVH::remove(ID p_id) { @@ -57,7 +60,8 @@ GodotCollisionObject3D *GodotBroadPhase3DBVH::get_object(ID p_id) const { } bool GodotBroadPhase3DBVH::is_static(ID p_id) const { - return !bvh.is_pairable(p_id - 1); + uint32_t tree_id = bvh.get_tree_id(p_id - 1); + return tree_id == 0; } int GodotBroadPhase3DBVH::get_subindex(ID p_id) const { @@ -65,15 +69,15 @@ int GodotBroadPhase3DBVH::get_subindex(ID p_id) const { } int GodotBroadPhase3DBVH::cull_point(const Vector3 &p_point, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_point(p_point, p_results, p_max_results, p_result_indices); + return bvh.cull_point(p_point, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } int GodotBroadPhase3DBVH::cull_segment(const Vector3 &p_from, const Vector3 &p_to, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); + return bvh.cull_segment(p_from, p_to, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } int GodotBroadPhase3DBVH::cull_aabb(const AABB &p_aabb, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); + return bvh.cull_aabb(p_aabb, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } void *GodotBroadPhase3DBVH::_pair_callback(void *self, uint32_t p_A, GodotCollisionObject3D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject3D *p_object_B, int subindex_B) { diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.h b/servers/physics_3d/godot_broad_phase_3d_bvh.h index 7138019a9c..7660030195 100644 --- a/servers/physics_3d/godot_broad_phase_3d_bvh.h +++ b/servers/physics_3d/godot_broad_phase_3d_bvh.h @@ -36,7 +36,34 @@ #include "core/math/bvh.h" class GodotBroadPhase3DBVH : public GodotBroadPhase3D { - BVH_Manager<GodotCollisionObject3D, true, 128> bvh; + template <class T> + class UserPairTestFunction { + public: + static bool user_pair_check(const T *p_a, const T *p_b) { + // return false if no collision, decided by masks etc + return p_a->interacts_with(p_b); + } + }; + + template <class T> + class UserCullTestFunction { + public: + static bool user_cull_check(const T *p_a, const T *p_b) { + return true; + } + }; + + enum Tree { + TREE_STATIC = 0, + TREE_DYNAMIC = 1, + }; + + enum TreeFlag { + TREE_FLAG_STATIC = 1 << TREE_STATIC, + TREE_FLAG_DYNAMIC = 1 << TREE_DYNAMIC, + }; + + BVH_Manager<GodotCollisionObject3D, 2, true, 128, UserPairTestFunction<GodotCollisionObject3D>, UserCullTestFunction<GodotCollisionObject3D>> bvh; static void *_pair_callback(void *, uint32_t, GodotCollisionObject3D *, int, uint32_t, GodotCollisionObject3D *, int); static void _unpair_callback(void *, uint32_t, GodotCollisionObject3D *, int, uint32_t, GodotCollisionObject3D *, int, void *); diff --git a/servers/physics_3d/godot_collision_object_3d.h b/servers/physics_3d/godot_collision_object_3d.h index 0178838a25..515b945564 100644 --- a/servers/physics_3d/godot_collision_object_3d.h +++ b/servers/physics_3d/godot_collision_object_3d.h @@ -169,7 +169,7 @@ public: return p_other->collision_layer & collision_mask; } - _FORCE_INLINE_ bool interacts_with(GodotCollisionObject3D *p_other) const { + _FORCE_INLINE_ bool interacts_with(const GodotCollisionObject3D *p_other) const { return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask; } diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index a1912dc660..f7270713e0 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -920,7 +920,7 @@ RID GodotPhysicsServer3D::soft_body_create() { return rid; } -void GodotPhysicsServer3D::soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) { +void GodotPhysicsServer3D::soft_body_update_rendering_server(RID p_body, PhysicsServer3DRenderingServerHandler *p_rendering_server_handler) { GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_COND(!soft_body); @@ -1355,7 +1355,7 @@ int GodotPhysicsServer3D::joint_get_solver_priority(RID p_joint) const { return joint->get_priority(); } -void GodotPhysicsServer3D::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { +void GodotPhysicsServer3D::joint_disable_collisions_between_bodies(RID p_joint, bool p_disable) { GodotJoint3D *joint = joint_owner.get_or_null(p_joint); ERR_FAIL_COND(!joint); diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h index b903f4808c..00ed763e01 100644 --- a/servers/physics_3d/godot_physics_server_3d.h +++ b/servers/physics_3d/godot_physics_server_3d.h @@ -253,7 +253,7 @@ public: virtual RID soft_body_create() override; - virtual void soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) override; + virtual void soft_body_update_rendering_server(RID p_body, PhysicsServer3DRenderingServerHandler *p_rendering_server_handler) override; virtual void soft_body_set_space(RID p_body, RID p_space) override; virtual RID soft_body_get_space(RID p_body) const override; @@ -353,7 +353,7 @@ public: virtual void joint_set_solver_priority(RID p_joint, int p_priority) override; virtual int joint_get_solver_priority(RID p_joint) const override; - virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) override; + virtual void joint_disable_collisions_between_bodies(RID p_joint, bool p_disable) override; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const override; /* MISC */ diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/servers/physics_3d/godot_soft_body_3d.cpp index 095050b7f3..f09da92cae 100644 --- a/servers/physics_3d/godot_soft_body_3d.cpp +++ b/servers/physics_3d/godot_soft_body_3d.cpp @@ -147,7 +147,7 @@ void GodotSoftBody3D::set_mesh(RID p_mesh) { } } -void GodotSoftBody3D::update_rendering_server(RenderingServerHandler *p_rendering_server_handler) { +void GodotSoftBody3D::update_rendering_server(PhysicsServer3DRenderingServerHandler *p_rendering_server_handler) { if (soft_mesh.is_null()) { return; } diff --git a/servers/physics_3d/godot_soft_body_3d.h b/servers/physics_3d/godot_soft_body_3d.h index 5028e81dd8..d9f5078313 100644 --- a/servers/physics_3d/godot_soft_body_3d.h +++ b/servers/physics_3d/godot_soft_body_3d.h @@ -157,7 +157,7 @@ public: void set_mesh(RID p_mesh); - void update_rendering_server(RenderingServerHandler *p_rendering_server_handler); + void update_rendering_server(PhysicsServer3DRenderingServerHandler *p_rendering_server_handler); Vector3 get_vertex_position(int p_index) const; void set_vertex_position(int p_index, const Vector3 &p_position); diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp index 2490a2f506..e28b6da0d9 100644 --- a/servers/physics_3d/godot_space_3d.cpp +++ b/servers/physics_3d/godot_space_3d.cpp @@ -1007,11 +1007,8 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D:: return collided; } +// Assumes a valid collision pair, this should have been checked beforehand in the BVH or octree. void *GodotSpace3D::_broadphase_pair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_self) { - if (!A->interacts_with(B)) { - return nullptr; - } - GodotCollisionObject3D::Type type_A = A->get_type(); GodotCollisionObject3D::Type type_B = B->get_type(); if (type_A > type_B) { diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index fc119e49e9..17c94978d1 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -33,6 +33,22 @@ #include "core/config/project_settings.h" #include "core/string/print_string.h" +void PhysicsServer3DRenderingServerHandler::set_vertex(int p_vertex_id, const void *p_vector3) { + GDVIRTUAL_REQUIRED_CALL(_set_vertex, p_vertex_id, p_vector3); +} +void PhysicsServer3DRenderingServerHandler::set_normal(int p_vertex_id, const void *p_vector3) { + GDVIRTUAL_REQUIRED_CALL(_set_normal, p_vertex_id, p_vector3); +} +void PhysicsServer3DRenderingServerHandler::set_aabb(const AABB &p_aabb) { + GDVIRTUAL_REQUIRED_CALL(_set_aabb, p_aabb); +} + +void PhysicsServer3DRenderingServerHandler::_bind_methods() { + GDVIRTUAL_BIND(_set_vertex, "vertex_id", "vertices"); + GDVIRTUAL_BIND(_set_normal, "vertex_id", "normals"); + GDVIRTUAL_BIND(_set_aabb, "aabb"); +} + PhysicsServer3D *PhysicsServer3D::singleton = nullptr; void PhysicsDirectBodyState3D::integrate_forces() { diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index f830c95b58..4811f7a039 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -33,6 +33,9 @@ #include "core/io/resource.h" #include "core/object/class_db.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" +#include "core/variant/native_ptr.h" class PhysicsDirectSpaceState3D; @@ -202,13 +205,21 @@ public: PhysicsDirectSpaceState3D(); }; -class RenderingServerHandler { +class PhysicsServer3DRenderingServerHandler : public Object { + GDCLASS(PhysicsServer3DRenderingServerHandler, Object) +protected: + GDVIRTUAL2(_set_vertex, int, GDNativeConstPtr<void>) + GDVIRTUAL2(_set_normal, int, GDNativeConstPtr<void>) + GDVIRTUAL1(_set_aabb, const AABB &) + + static void _bind_methods(); + public: - virtual void set_vertex(int p_vertex_id, const void *p_vector3) = 0; - virtual void set_normal(int p_vertex_id, const void *p_vector3) = 0; - virtual void set_aabb(const AABB &p_aabb) = 0; + virtual void set_vertex(int p_vertex_id, const void *p_vector3); + virtual void set_normal(int p_vertex_id, const void *p_vector3); + virtual void set_aabb(const AABB &p_aabb); - virtual ~RenderingServerHandler() {} + virtual ~PhysicsServer3DRenderingServerHandler() {} }; class PhysicsTestMotionParameters3D; @@ -552,7 +563,7 @@ public: virtual RID soft_body_create() = 0; - virtual void soft_body_update_rendering_server(RID p_body, RenderingServerHandler *p_rendering_server_handler) = 0; + virtual void soft_body_update_rendering_server(RID p_body, PhysicsServer3DRenderingServerHandler *p_rendering_server_handler) = 0; virtual void soft_body_set_space(RID p_body, RID p_space) = 0; virtual RID soft_body_get_space(RID p_body) const = 0; @@ -624,7 +635,7 @@ public: virtual void joint_set_solver_priority(RID p_joint, int p_priority) = 0; virtual int joint_get_solver_priority(RID p_joint) const = 0; - virtual void joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) = 0; + virtual void joint_disable_collisions_between_bodies(RID p_joint, bool p_disable) = 0; virtual bool joint_is_disabled_collisions_between_bodies(RID p_joint) const = 0; virtual void joint_make_pin(RID p_joint, RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) = 0; diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index ecaef886e1..e44f82672d 100644 --- a/servers/physics_server_3d_wrap_mt.h +++ b/servers/physics_server_3d_wrap_mt.h @@ -269,7 +269,7 @@ public: FUNCRID(soft_body) - FUNC2(soft_body_update_rendering_server, RID, class RenderingServerHandler *) + FUNC2(soft_body_update_rendering_server, RID, PhysicsServer3DRenderingServerHandler *) FUNC2(soft_body_set_space, RID, RID) FUNC1RC(RID, soft_body_get_space, RID) @@ -369,7 +369,7 @@ public: FUNC2(joint_set_solver_priority, RID, int); FUNC1RC(int, joint_get_solver_priority, RID); - FUNC2(joint_disable_collisions_between_bodies, RID, const bool); + FUNC2(joint_disable_collisions_between_bodies, RID, bool); FUNC1RC(bool, joint_is_disabled_collisions_between_bodies, RID); /* MISC */ diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index f405dea770..9843492316 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -70,7 +70,9 @@ #include "rendering/rendering_device.h" #include "rendering/rendering_device_binds.h" #include "rendering_server.h" +#include "servers/extensions/physics_server_3d_extension.h" #include "servers/rendering/shader_types.h" +#include "text/text_server_dummy.h" #include "text/text_server_extension.h" #include "text_server.h" #include "xr/xr_interface.h" @@ -110,8 +112,12 @@ void preregister_server_types() { shader_types = memnew(ShaderTypes); GDREGISTER_CLASS(TextServerManager); - GDREGISTER_VIRTUAL_CLASS(TextServer); + GDREGISTER_ABSTRACT_CLASS(TextServer); GDREGISTER_CLASS(TextServerExtension); + GDREGISTER_CLASS(TextServerDummy); + + GDREGISTER_NATIVE_STRUCT(Glyph, "int start = -1;int end = -1;uint8_t count = 0;uint8_t repeat = 1;uint16_t flags = 0;float x_off = 0.f;float y_off = 0.f;float advance = 0.f;RID font_rid;int font_size = 0;int32_t index = 0"); + GDREGISTER_NATIVE_STRUCT(CaretInfo, "Rect2 leading_caret;Rect2 trailing_caret;TextServer::Direction leading_direction;TextServer::Direction trailing_direction"); Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager")); } @@ -119,20 +125,32 @@ void preregister_server_types() { void register_server_types() { OS::get_singleton()->set_has_server_feature_callback(has_server_feature_callback); - GDREGISTER_VIRTUAL_CLASS(DisplayServer); - GDREGISTER_VIRTUAL_CLASS(RenderingServer); + GDREGISTER_ABSTRACT_CLASS(DisplayServer); + GDREGISTER_ABSTRACT_CLASS(RenderingServer); GDREGISTER_CLASS(AudioServer); - GDREGISTER_VIRTUAL_CLASS(PhysicsServer2D); - GDREGISTER_VIRTUAL_CLASS(PhysicsServer3D); - GDREGISTER_VIRTUAL_CLASS(NavigationServer2D); - GDREGISTER_VIRTUAL_CLASS(NavigationServer3D); + GDREGISTER_ABSTRACT_CLASS(PhysicsServer2D); + GDREGISTER_ABSTRACT_CLASS(PhysicsServer3D); + GDREGISTER_VIRTUAL_CLASS(PhysicsServer3DExtension); + GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3DExtension); + GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3DExtension) + GDREGISTER_VIRTUAL_CLASS(PhysicsServer3DRenderingServerHandler) + + GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionRayResult, "Vector3 position;Vector3 normal;RID rid;ObjectID collider_id;Object *collider;int shape"); + GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionShapeResult, "RID rid;ObjectID collider_id;Object *collider;int shape"); + GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionShapeRestInfo, "Vector3 point;Vector3 normal;RID rid;ObjectID collider_id;int shape;Vector3 linear_velocity"); + GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionMotionCollision, "Vector3 position;Vector3 normal;Vector3 collider_velocity;real_t depth;int local_shape;ObjectID collider_id;RID collider;int collider_shape"); + GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionMotionResult, "Vector3 travel;Vector3 remainder;real_t collision_safe_fraction;real_t collision_unsafe_fraction;PhysicsServer3DExtensionMotionCollision collisions[32];int collision_count"); + GDREGISTER_NATIVE_STRUCT(PhysicsServer3DExtensionStateCallback, "void *instance;void (*callback)(void *p_instance, PhysicsDirectBodyState3D *p_state)"); + + GDREGISTER_ABSTRACT_CLASS(NavigationServer2D); + GDREGISTER_ABSTRACT_CLASS(NavigationServer3D); GDREGISTER_CLASS(XRServer); GDREGISTER_CLASS(CameraServer); - GDREGISTER_VIRTUAL_CLASS(RenderingDevice); + GDREGISTER_ABSTRACT_CLASS(RenderingDevice); - GDREGISTER_VIRTUAL_CLASS(XRInterface); + GDREGISTER_ABSTRACT_CLASS(XRInterface); GDREGISTER_CLASS(XRInterfaceExtension); // can't register this as virtual because we need a creation function for our extensions. GDREGISTER_CLASS(XRPose); GDREGISTER_CLASS(XRPositionalTracker); @@ -149,7 +167,7 @@ void register_server_types() { GDREGISTER_CLASS(AudioBusLayout); GDREGISTER_CLASS(AudioStreamGenerator); - GDREGISTER_VIRTUAL_CLASS(AudioStreamGeneratorPlayback); + GDREGISTER_ABSTRACT_CLASS(AudioStreamGeneratorPlayback); { //audio effects @@ -183,12 +201,12 @@ void register_server_types() { GDREGISTER_CLASS(AudioEffectRecord); GDREGISTER_CLASS(AudioEffectSpectrumAnalyzer); - GDREGISTER_VIRTUAL_CLASS(AudioEffectSpectrumAnalyzerInstance); + GDREGISTER_ABSTRACT_CLASS(AudioEffectSpectrumAnalyzerInstance); GDREGISTER_CLASS(AudioEffectCapture); } - GDREGISTER_VIRTUAL_CLASS(RenderingDevice); + GDREGISTER_ABSTRACT_CLASS(RenderingDevice); GDREGISTER_CLASS(RDTextureFormat); GDREGISTER_CLASS(RDTextureView); GDREGISTER_CLASS(RDAttachmentFormat); @@ -208,16 +226,16 @@ void register_server_types() { GDREGISTER_CLASS(CameraFeed); - GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState2D); - GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState2D); + GDREGISTER_ABSTRACT_CLASS(PhysicsDirectBodyState2D); + GDREGISTER_ABSTRACT_CLASS(PhysicsDirectSpaceState2D); GDREGISTER_CLASS(PhysicsRayQueryParameters2D); GDREGISTER_CLASS(PhysicsPointQueryParameters2D); GDREGISTER_CLASS(PhysicsShapeQueryParameters2D); GDREGISTER_CLASS(PhysicsTestMotionParameters2D); GDREGISTER_CLASS(PhysicsTestMotionResult2D); - GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3D); - GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3D); + GDREGISTER_ABSTRACT_CLASS(PhysicsDirectBodyState3D); + GDREGISTER_ABSTRACT_CLASS(PhysicsDirectSpaceState3D); GDREGISTER_CLASS(PhysicsRayQueryParameters3D); GDREGISTER_CLASS(PhysicsPointQueryParameters3D); GDREGISTER_CLASS(PhysicsShapeQueryParameters3D); diff --git a/servers/rendering/SCsub b/servers/rendering/SCsub index 0939b68482..06d1d28b08 100644 --- a/servers/rendering/SCsub +++ b/servers/rendering/SCsub @@ -5,3 +5,4 @@ Import("env") env.add_source_files(env.servers_sources, "*.cpp") SConscript("renderer_rd/SCsub") +SConscript("storage/SCsub") diff --git a/servers/rendering/dummy/rasterizer_canvas_dummy.h b/servers/rendering/dummy/rasterizer_canvas_dummy.h new file mode 100644 index 0000000000..194b5b5cfe --- /dev/null +++ b/servers/rendering/dummy/rasterizer_canvas_dummy.h @@ -0,0 +1,63 @@ +/*************************************************************************/ +/* rasterizer_canvas_dummy.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 RASTERIZER_CANVAS_DUMMY_H +#define RASTERIZER_CANVAS_DUMMY_H + +#include "servers/rendering/renderer_canvas_render.h" + +class RasterizerCanvasDummy : public RendererCanvasRender { +public: + PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override { return 0; } + void free_polygon(PolygonID p_polygon) override {} + + void 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) override {} + void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override {} + + RID light_create() override { return RID(); } + void light_set_texture(RID p_rid, RID p_texture) override {} + void light_set_use_shadow(RID p_rid, bool p_enable) override {} + void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override {} + void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override {} + + void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override {} + RID occluder_polygon_create() override { return RID(); } + void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override {} + void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override {} + void set_shadow_texture_size(int p_size) override {} + + bool free(RID p_rid) override { return true; } + void update() override {} + + RasterizerCanvasDummy() {} + ~RasterizerCanvasDummy() {} +}; + +#endif // !RASTERIZER_CANVAS_DUMMY_H diff --git a/servers/rendering/dummy/rasterizer_dummy.h b/servers/rendering/dummy/rasterizer_dummy.h new file mode 100644 index 0000000000..b3fbc18c46 --- /dev/null +++ b/servers/rendering/dummy/rasterizer_dummy.h @@ -0,0 +1,99 @@ +/*************************************************************************/ +/* rasterizer_dummy.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 RASTERIZER_DUMMY_H +#define RASTERIZER_DUMMY_H + +#include "core/templates/rid_owner.h" +#include "core/templates/self_list.h" +#include "scene/resources/mesh.h" +#include "servers/rendering/dummy/rasterizer_canvas_dummy.h" +#include "servers/rendering/dummy/rasterizer_scene_dummy.h" +#include "servers/rendering/dummy/rasterizer_storage_dummy.h" +#include "servers/rendering/dummy/storage/canvas_texture_storage.h" +#include "servers/rendering/dummy/storage/texture_storage.h" +#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering_server.h" + +class RasterizerDummy : public RendererCompositor { +private: + uint64_t frame = 1; + double delta = 0; + +protected: + RasterizerCanvasDummy canvas; + RendererDummy::CanvasTextureStorage canvas_texture_storage; + RendererDummy::TextureStorage texture_storage; + RasterizerStorageDummy storage; + RasterizerSceneDummy scene; + +public: + RendererCanvasTextureStorage *get_canvas_texture_storage() override { return &canvas_texture_storage; }; + RendererTextureStorage *get_texture_storage() override { return &texture_storage; }; + RendererStorage *get_storage() override { return &storage; } + RendererCanvasRender *get_canvas() override { return &canvas; } + RendererSceneRender *get_scene() override { return &scene; } + + void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override {} + + void initialize() override {} + void begin_frame(double frame_step) override { + frame++; + delta = frame_step; + } + + void prepare_for_blitting_render_targets() override {} + void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) override {} + + void end_frame(bool p_swap_buffers) override { + if (p_swap_buffers) { + DisplayServer::get_singleton()->swap_buffers(); + } + } + + void finalize() override {} + + static RendererCompositor *_create_current() { + return memnew(RasterizerDummy); + } + + static void make_current() { + _create_func = _create_current; + } + + bool is_low_end() const override { return true; } + uint64_t get_frame_number() const override { return frame; } + double get_frame_delta_time() const override { return delta; } + + RasterizerDummy() {} + ~RasterizerDummy() {} +}; + +#endif // RASTERIZER_DUMMY_H diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h new file mode 100644 index 0000000000..3855222554 --- /dev/null +++ b/servers/rendering/dummy/rasterizer_scene_dummy.h @@ -0,0 +1,217 @@ +/*************************************************************************/ +/* rasterizer_scene_dummy.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 RASTERIZER_SCENE_DUMMY_H +#define RASTERIZER_SCENE_DUMMY_H + +#include "servers/rendering/renderer_scene_render.h" + +class RasterizerSceneDummy : public RendererSceneRender { +public: + GeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; } + void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override {} + void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override {} + void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override {} + void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override {} + void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override {} + void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {} + void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override {} + void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override {} + void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override {} + void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override {} + void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {} + void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override {} + void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override {} + void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override {} + void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {} + void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override {} + void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override {} + + uint32_t geometry_instance_get_pair_mask() override { return 0; } + void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override {} + void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} + void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} + void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} + void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override {} + + void geometry_instance_free(GeometryInstance *p_geometry_instance) override {} + + /* SHADOW ATLAS API */ + + RID shadow_atlas_create() override { return RID(); } + void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override {} + void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override {} + bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override { return false; } + + void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override {} + int get_directional_light_shadow_size(RID p_light_intance) override { return 0; } + void set_directional_shadow_count(int p_count) override {} + + /* SDFGI UPDATE */ + + void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {} + int sdfgi_get_pending_region_count(RID p_render_buffers) const override { return 0; } + AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { return AABB(); } + uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { return 0; } + + /* SKY API */ + + RID sky_allocate() override { return RID(); } + void sky_initialize(RID p_rid) override {} + void sky_set_radiance_size(RID p_sky, int p_radiance_size) override {} + void sky_set_mode(RID p_sky, RS::SkyMode p_samples) override {} + void sky_set_material(RID p_sky, RID p_material) override {} + Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); } + + /* ENVIRONMENT API */ + + RID environment_allocate() override { return RID(); } + void environment_initialize(RID p_rid) override {} + void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override {} + void environment_set_sky(RID p_env, RID p_sky) override {} + void environment_set_sky_custom_fov(RID p_env, float p_scale) override {} + void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override {} + void environment_set_bg_color(RID p_env, const Color &p_color) override {} + void environment_set_bg_energy(RID p_env, float p_energy) override {} + void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override {} + void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override {} + + void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override {} + void environment_glow_set_use_bicubic_upscale(bool p_enable) override {} + void environment_glow_set_use_high_quality(bool p_enable) override {} + + void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) override {} + void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {} + void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override {} + void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} + void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override {} + void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} + + void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {} + + void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override {} + void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override {} + void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override {} + + void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override {} + + void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {} + + void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {} + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) override {} + void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {} + void environment_set_volumetric_fog_filter_active(bool p_enable) override {} + + Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); } + + bool is_environment(RID p_env) const override { return false; } + RS::EnvironmentBG environment_get_background(RID p_env) const override { return RS::ENV_BG_KEEP; } + int environment_get_canvas_max_layer(RID p_env) const override { return 0; } + + RID camera_effects_allocate() override { return RID(); } + void camera_effects_initialize(RID p_rid) override {} + void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override {} + void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override {} + + void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override {} + void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override {} + + void shadows_quality_set(RS::ShadowQuality p_quality) override {} + void directional_shadow_quality_set(RS::ShadowQuality p_quality) override {} + + RID light_instance_create(RID p_light) override { return RID(); } + void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override {} + void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override {} + void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {} + void light_instance_mark_visible(RID p_light_instance) override {} + + RID fog_volume_instance_create(RID p_fog_volume) override { return RID(); } + void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) override {} + void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) override {} + RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const override { return RID(); } + Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const override { return Vector3(); } + + RID reflection_atlas_create() override { return RID(); } + int reflection_atlas_get_size(RID p_ref_atlas) const override { return 0; } + void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override {} + + RID reflection_probe_instance_create(RID p_probe) override { return RID(); } + void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override {} + void reflection_probe_release_atlas_index(RID p_instance) override {} + bool reflection_probe_instance_needs_redraw(RID p_instance) override { return false; } + bool reflection_probe_instance_has_reflection(RID p_instance) override { return false; } + bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override { return false; } + bool reflection_probe_instance_postprocess_step(RID p_instance) override { return true; } + + RID decal_instance_create(RID p_decal) override { return RID(); } + void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override {} + + RID lightmap_instance_create(RID p_lightmap) override { return RID(); } + void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override {} + + RID voxel_gi_instance_create(RID p_voxel_gi) override { return RID(); } + void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override {} + bool voxel_gi_needs_update(RID p_probe) const override { return false; } + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override {} + + 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_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_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 {} + void set_time(double p_time, double p_step) override {} + void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override {} + + RID render_buffers_create() override { return RID(); } + void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) override {} + void gi_set_use_half_resolution(bool p_enable) override {} + + void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {} + bool screen_space_roughness_limiter_is_active() const override { return false; } + + void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override {} + void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override {} + + TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override { return TypedArray<Image>(); } + + bool free(RID p_rid) override { return false; } + void update() override {} + void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override {} + + virtual void decals_set_filter(RS::DecalFilter p_filter) override {} + virtual void light_projectors_set_filter(RS::LightProjectorFilter p_filter) override {} + + RasterizerSceneDummy() {} + ~RasterizerSceneDummy() {} +}; + +#endif // !RASTERIZER_SCENE_DUMMY_H diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/dummy/rasterizer_storage_dummy.h index 74c080660d..39837c794f 100644 --- a/servers/rendering/rasterizer_dummy.h +++ b/servers/rendering/dummy/rasterizer_storage_dummy.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rasterizer_dummy.h */ +/* rasterizer_storage_dummy.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,265 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_DUMMY_H -#define RASTERIZER_DUMMY_H +#ifndef RASTERIZER_STORAGE_DUMMY_H +#define RASTERIZER_STORAGE_DUMMY_H -#include "core/templates/rid_owner.h" -#include "core/templates/self_list.h" -#include "scene/resources/mesh.h" -#include "servers/rendering/renderer_compositor.h" -#include "servers/rendering/renderer_scene_render.h" -#include "servers/rendering_server.h" - -class RasterizerSceneDummy : public RendererSceneRender { -public: - GeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; } - void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override {} - void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override {} - void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override {} - void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override {} - void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override {} - void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {} - void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override {} - void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override {} - void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {} - void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override {} - void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override {} - void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {} - void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override {} - void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override {} - - uint32_t geometry_instance_get_pair_mask() override { return 0; } - void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override {} - void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} - void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} - void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} - void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override {} - - void geometry_instance_free(GeometryInstance *p_geometry_instance) override {} - - /* SHADOW ATLAS API */ - - RID shadow_atlas_create() override { return RID(); } - void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override {} - void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override {} - bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override { return false; } - - void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override {} - int get_directional_light_shadow_size(RID p_light_intance) override { return 0; } - void set_directional_shadow_count(int p_count) override {} - - /* SDFGI UPDATE */ - - void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {} - int sdfgi_get_pending_region_count(RID p_render_buffers) const override { return 0; } - AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override { return AABB(); } - uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override { return 0; } - - /* SKY API */ - - RID sky_allocate() override { return RID(); } - void sky_initialize(RID p_rid) override {} - void sky_set_radiance_size(RID p_sky, int p_radiance_size) override {} - void sky_set_mode(RID p_sky, RS::SkyMode p_samples) override {} - void sky_set_material(RID p_sky, RID p_material) override {} - Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); } - - /* ENVIRONMENT API */ - - RID environment_allocate() override { return RID(); } - void environment_initialize(RID p_rid) override {} - void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override {} - void environment_set_sky(RID p_env, RID p_sky) override {} - void environment_set_sky_custom_fov(RID p_env, float p_scale) override {} - void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override {} - void environment_set_bg_color(RID p_env, const Color &p_color) override {} - void environment_set_bg_energy(RID p_env, float p_energy) override {} - void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override {} - void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override {} - - void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override {} - void environment_glow_set_use_bicubic_upscale(bool p_enable) override {} - void environment_glow_set_use_high_quality(bool p_enable) override {} - - void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) override {} - void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {} - void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override {} - void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} - void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override {} - void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {} - - void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {} - - void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override {} - void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override {} - void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override {} - - void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override {} - - void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {} - - void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {} - void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) override {} - void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {} - void environment_set_volumetric_fog_filter_active(bool p_enable) override {} - - Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); } - - bool is_environment(RID p_env) const override { return false; } - RS::EnvironmentBG environment_get_background(RID p_env) const override { return RS::ENV_BG_KEEP; } - int environment_get_canvas_max_layer(RID p_env) const override { return 0; } - - RID camera_effects_allocate() override { return RID(); } - void camera_effects_initialize(RID p_rid) override {} - void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override {} - void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override {} - - void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override {} - void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override {} - - void shadows_quality_set(RS::ShadowQuality p_quality) override {} - void directional_shadow_quality_set(RS::ShadowQuality p_quality) override {} - - RID light_instance_create(RID p_light) override { return RID(); } - void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override {} - void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override {} - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {} - void light_instance_mark_visible(RID p_light_instance) override {} - - RID fog_volume_instance_create(RID p_fog_volume) override { return RID(); } - void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) override {} - void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) override {} - RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const override { return RID(); } - Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const override { return Vector3(); } - - RID reflection_atlas_create() override { return RID(); } - int reflection_atlas_get_size(RID p_ref_atlas) const override { return 0; } - void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override {} - - RID reflection_probe_instance_create(RID p_probe) override { return RID(); } - void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override {} - void reflection_probe_release_atlas_index(RID p_instance) override {} - bool reflection_probe_instance_needs_redraw(RID p_instance) override { return false; } - bool reflection_probe_instance_has_reflection(RID p_instance) override { return false; } - bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override { return false; } - bool reflection_probe_instance_postprocess_step(RID p_instance) override { return true; } - - RID decal_instance_create(RID p_decal) override { return RID(); } - void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override {} - - RID lightmap_instance_create(RID p_lightmap) override { return RID(); } - void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override {} - - RID voxel_gi_instance_create(RID p_voxel_gi) override { return RID(); } - void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override {} - bool voxel_gi_needs_update(RID p_probe) const override { return false; } - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override {} - - 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_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_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 {} - void set_time(double p_time, double p_step) override {} - void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override {} - - RID render_buffers_create() override { return RID(); } - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) override {} - void gi_set_use_half_resolution(bool p_enable) override {} - - void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {} - bool screen_space_roughness_limiter_is_active() const override { return false; } - - void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override {} - void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override {} - - TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override { return TypedArray<Image>(); } - - bool free(RID p_rid) override { return false; } - void update() override {} - void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override {} - - virtual void decals_set_filter(RS::DecalFilter p_filter) override {} - virtual void light_projectors_set_filter(RS::LightProjectorFilter p_filter) override {} - - RasterizerSceneDummy() {} - ~RasterizerSceneDummy() {} -}; +#include "servers/rendering/renderer_storage.h" +#include "storage/texture_storage.h" class RasterizerStorageDummy : public RendererStorage { public: - bool can_create_resources_async() const override { return false; } - - /* TEXTURE API */ - struct DummyTexture { - Ref<Image> image; - }; - mutable RID_PtrOwner<DummyTexture> texture_owner; - - RID texture_allocate() override { - DummyTexture *texture = memnew(DummyTexture); - ERR_FAIL_COND_V(!texture, RID()); - return texture_owner.make_rid(texture); - } - void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override { - DummyTexture *t = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!t); - t->image = p_image->duplicate(); - } - - void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override {} - void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override {} - void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override {} - void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override {} - void texture_proxy_initialize(RID p_texture, RID p_base) override {} - void texture_proxy_update(RID p_proxy, RID p_base) override {} - - void texture_2d_placeholder_initialize(RID p_texture) override {} - void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) override {} - void texture_3d_placeholder_initialize(RID p_texture) override {} - - Ref<Image> texture_2d_get(RID p_texture) const override { - DummyTexture *t = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND_V(!t, Ref<Image>()); - return t->image; - } - - Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const override { return Ref<Image>(); } - Vector<Ref<Image>> texture_3d_get(RID p_texture) const override { return Vector<Ref<Image>>(); } - - void texture_replace(RID p_texture, RID p_by_texture) override { free(p_by_texture); } - void texture_set_size_override(RID p_texture, int p_width, int p_height) override {} - - void texture_set_path(RID p_texture, const String &p_path) override {} - String texture_get_path(RID p_texture) const override { return String(); } - - void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override {} - void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override {} - void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) override {} - - void texture_debug_usage(List<RS::TextureInfo> *r_info) override {} - void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override {} - Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); } - - void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} - void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} - - /* CANVAS TEXTURE API */ - - RID canvas_texture_allocate() override { return RID(); } - void canvas_texture_initialize(RID p_rid) override {} - void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override {} - void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override {} - - void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override {} - void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override {} - /* SHADER API */ RID shader_allocate() override { return RID(); } @@ -408,10 +157,10 @@ public: 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_shadow_color(RID p_light, const Color &p_color) 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 {} @@ -421,8 +170,8 @@ public: 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 { return false; } - void light_directional_set_sky_only(RID p_light, bool p_sky_only) override {} - bool light_directional_is_sky_only(RID p_light) const override { return false; } + 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 { return RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; } RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override { return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; } RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) override { return RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; } @@ -481,6 +230,9 @@ public: AABB decal_get_aabb(RID p_decal) const override { return AABB(); } + void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} + void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} + /* VOXEL GI API */ RID voxel_gi_allocate() override { return RID(); } @@ -682,11 +434,8 @@ public: RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; } bool free(RID p_rid) override { - if (texture_owner.owns(p_rid)) { - // delete the texture - DummyTexture *texture = texture_owner.get_or_null(p_rid); - texture_owner.free(p_rid); - memdelete(texture); + if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) { + RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid); return true; } return false; @@ -721,81 +470,4 @@ public: ~RasterizerStorageDummy() {} }; -class RasterizerCanvasDummy : public RendererCanvasRender { -public: - PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) override { return 0; } - void free_polygon(PolygonID p_polygon) override {} - - void 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) override {} - void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override {} - - RID light_create() override { return RID(); } - void light_set_texture(RID p_rid, RID p_texture) override {} - void light_set_use_shadow(RID p_rid, bool p_enable) override {} - void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override {} - void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override {} - - void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override {} - RID occluder_polygon_create() override { return RID(); } - void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override {} - void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override {} - void set_shadow_texture_size(int p_size) override {} - - bool free(RID p_rid) override { return true; } - void update() override {} - - RasterizerCanvasDummy() {} - ~RasterizerCanvasDummy() {} -}; - -class RasterizerDummy : public RendererCompositor { -private: - uint64_t frame = 1; - double delta = 0; - -protected: - RasterizerCanvasDummy canvas; - RasterizerStorageDummy storage; - RasterizerSceneDummy scene; - -public: - RendererStorage *get_storage() override { return &storage; } - RendererCanvasRender *get_canvas() override { return &canvas; } - RendererSceneRender *get_scene() override { return &scene; } - - void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) override {} - - void initialize() override {} - void begin_frame(double frame_step) override { - frame++; - delta = frame_step; - } - - void prepare_for_blitting_render_targets() override {} - void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) override {} - - void end_frame(bool p_swap_buffers) override { - if (p_swap_buffers) { - DisplayServer::get_singleton()->swap_buffers(); - } - } - - void finalize() override {} - - static RendererCompositor *_create_current() { - return memnew(RasterizerDummy); - } - - static void make_current() { - _create_func = _create_current; - } - - bool is_low_end() const override { return true; } - uint64_t get_frame_number() const override { return frame; } - double get_frame_delta_time() const override { return delta; } - - RasterizerDummy() {} - ~RasterizerDummy() {} -}; - -#endif // RASTERIZER_DUMMY_H +#endif // !RASTERIZER_STORAGE_DUMMY_H diff --git a/servers/rendering/dummy/storage/canvas_texture_storage.h b/servers/rendering/dummy/storage/canvas_texture_storage.h new file mode 100644 index 0000000000..daa3ac5e42 --- /dev/null +++ b/servers/rendering/dummy/storage/canvas_texture_storage.h @@ -0,0 +1,53 @@ +/*************************************************************************/ +/* 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_DUMMY_H +#define CANVAS_TEXTURE_STORAGE_DUMMY_H + +#include "servers/rendering/storage/canvas_texture_storage.h" + +namespace RendererDummy { + +class CanvasTextureStorage : public RendererCanvasTextureStorage { +public: + virtual RID canvas_texture_allocate() override { return RID(); }; + 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 RendererDummy + +#endif // !CANVAS_TEXTURE_STORAGE_DUMMY_H diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h new file mode 100644 index 0000000000..d40a1842a4 --- /dev/null +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -0,0 +1,116 @@ +/*************************************************************************/ +/* 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 TEXTURE_STORAGE_DUMMY_H +#define TEXTURE_STORAGE_DUMMY_H + +#include "servers/rendering/rendering_server_globals.h" +#include "servers/rendering/storage/texture_storage.h" + +namespace RendererDummy { + +class TextureStorage : public RendererTextureStorage { +private: + struct DummyTexture { + Ref<Image> image; + }; + mutable RID_PtrOwner<DummyTexture> texture_owner; + +public: + static TextureStorage *get_singleton() { + // Here we cheat until we can retire RasterizerStorageDummy::free() + + return (TextureStorage *)RSG::texture_storage; + }; + + virtual bool can_create_resources_async() const override { return false; } + + DummyTexture *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); }; + + virtual RID texture_allocate() override { + DummyTexture *texture = memnew(DummyTexture); + ERR_FAIL_COND_V(!texture, RID()); + return texture_owner.make_rid(texture); + }; + + virtual void texture_free(RID p_rid) override { + // delete the texture + DummyTexture *texture = texture_owner.get_or_null(p_rid); + texture_owner.free(p_rid); + memdelete(texture); + }; + + virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override { + DummyTexture *t = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!t); + t->image = p_image->duplicate(); + }; + virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override{}; + virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override{}; + virtual void texture_proxy_initialize(RID p_texture, RID p_base) override{}; //all slices, then all the mipmaps, must be coherent + + virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override{}; + virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override{}; + virtual void texture_proxy_update(RID p_proxy, RID p_base) override{}; + + //these two APIs can be used together or in combination with the others. + virtual void texture_2d_placeholder_initialize(RID p_texture) override{}; + virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) override{}; + virtual void texture_3d_placeholder_initialize(RID p_texture) override{}; + + virtual Ref<Image> texture_2d_get(RID p_texture) const override { + DummyTexture *t = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND_V(!t, Ref<Image>()); + return t->image; + }; + virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const override { return Ref<Image>(); }; + virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const override { return Vector<Ref<Image>>(); }; + + virtual void texture_replace(RID p_texture, RID p_by_texture) override { texture_free(p_by_texture); }; + virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) override{}; + + virtual void texture_set_path(RID p_texture, const String &p_path) override{}; + virtual String texture_get_path(RID p_texture) const override { return String(); }; + + virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override{}; + virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override{}; + virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) override{}; + + virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) override{}; + + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override{}; + + virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); }; +}; + +} // namespace RendererDummy + +#endif // !TEXTURE_STORAGE_DUMMY_H diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 418d2bc42e..56eaa396c8 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -34,6 +34,7 @@ #include "renderer_viewport.h" #include "rendering_server_default.h" #include "rendering_server_globals.h" +#include "servers/rendering/storage/canvas_texture_storage.h" static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1; @@ -66,7 +67,7 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas } } - RENDER_TIMESTAMP("Render Canvas Items"); + RENDER_TIMESTAMP("Render CanvasItems"); bool sdf_flag; RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_directional_lights, p_transform, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, sdf_flag); @@ -338,7 +339,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 } void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { - RENDER_TIMESTAMP(">Render Canvas"); + RENDER_TIMESTAMP("> Render Canvas"); sdf_used = false; snapping_2d_transforms_to_pixel = p_snap_2d_transforms_to_pixel; @@ -384,7 +385,7 @@ void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, co } } - RENDER_TIMESTAMP("<End Render Canvas"); + RENDER_TIMESTAMP("< Render Canvas"); } bool RendererCanvasCull::was_sdf_used() { @@ -1530,26 +1531,26 @@ void RendererCanvasCull::canvas_set_shadow_texture_size(int p_size) { } RID RendererCanvasCull::canvas_texture_allocate() { - return RSG::storage->canvas_texture_allocate(); + return RSG::canvas_texture_storage->canvas_texture_allocate(); } void RendererCanvasCull::canvas_texture_initialize(RID p_rid) { - RSG::storage->canvas_texture_initialize(p_rid); + RSG::canvas_texture_storage->canvas_texture_initialize(p_rid); } void RendererCanvasCull::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { - RSG::storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture); + RSG::canvas_texture_storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture); } void RendererCanvasCull::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) { - RSG::storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess); + RSG::canvas_texture_storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess); } void RendererCanvasCull::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { - RSG::storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter); + RSG::canvas_texture_storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter); } void RendererCanvasCull::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { - RSG::storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat); + RSG::canvas_texture_storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat); } void RendererCanvasCull::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) { diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp index 82e8bd6ef9..fa4d9c8b31 100644 --- a/servers/rendering/renderer_compositor.cpp +++ b/servers/rendering/renderer_compositor.cpp @@ -45,7 +45,7 @@ bool RendererCompositor::is_xr_enabled() const { } RendererCompositor::RendererCompositor() { - xr_enabled = GLOBAL_GET("rendering/xr/enabled"); + xr_enabled = GLOBAL_GET("xr/shaders/enabled"); } RendererCanvasRender *RendererCanvasRender::singleton = nullptr; diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index e58fd7bebc..c2bc2c03d0 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -34,6 +34,8 @@ #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_storage.h" +#include "servers/rendering/storage/canvas_texture_storage.h" +#include "servers/rendering/storage/texture_storage.h" #include "servers/rendering_server.h" class RendererSceneRender; @@ -70,6 +72,8 @@ protected: public: static RendererCompositor *create(); + virtual RendererCanvasTextureStorage *get_canvas_texture_storage() = 0; + virtual RendererTextureStorage *get_texture_storage() = 0; virtual RendererStorage *get_storage() = 0; virtual RendererCanvasRender *get_canvas() = 0; virtual RendererSceneRender *get_scene() = 0; diff --git a/servers/rendering/renderer_rd/SCsub b/servers/rendering/renderer_rd/SCsub index 64e613ab91..d3ad381965 100644 --- a/servers/rendering/renderer_rd/SCsub +++ b/servers/rendering/renderer_rd/SCsub @@ -7,3 +7,4 @@ env.add_source_files(env.servers_sources, "*.cpp") SConscript("forward_clustered/SCsub") SConscript("forward_mobile/SCsub") SConscript("shaders/SCsub") +SConscript("storage_rd/SCsub") diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index 6ad3556969..24108b3a59 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -287,21 +287,21 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 1; - u.ids.push_back(state_uniform); + u.append_id(state_uniform); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(element_buffer); + u.append_id(element_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; - u.ids.push_back(cluster_render_buffer); + u.append_id(cluster_render_buffer); uniforms.push_back(u); } @@ -314,14 +314,14 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(cluster_render_buffer); + u.append_id(cluster_render_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(cluster_buffer); + u.append_id(cluster_buffer); uniforms.push_back(u); } @@ -329,7 +329,7 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; - u.ids.push_back(element_buffer); + u.append_id(element_buffer); uniforms.push_back(u); } @@ -342,14 +342,14 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(cluster_buffer); + u.append_id(cluster_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(p_color_buffer); + u.append_id(p_color_buffer); uniforms.push_back(u); } @@ -357,14 +357,14 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 3; - u.ids.push_back(p_depth_buffer); + u.append_id(p_depth_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 4; - u.ids.push_back(p_depth_buffer_sampler); + u.append_id(p_depth_buffer_sampler); uniforms.push_back(u); } @@ -398,7 +398,7 @@ void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const CameraMa } void ClusterBuilderRD::bake_cluster() { - RENDER_TIMESTAMP(">Bake Cluster"); + RENDER_TIMESTAMP("> Bake 3D Cluster"); RD::get_singleton()->draw_command_begin_label("Bake Light Cluster"); @@ -429,7 +429,7 @@ void ClusterBuilderRD::bake_cluster() { RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); - RENDER_TIMESTAMP("Render Elements"); + RENDER_TIMESTAMP("Render 3D Cluster Elements"); //render elements { @@ -466,7 +466,7 @@ void ClusterBuilderRD::bake_cluster() { RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_COMPUTE); } //store elements - RENDER_TIMESTAMP("Pack Elements"); + RENDER_TIMESTAMP("Pack 3D Cluster Elements"); { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -492,7 +492,7 @@ void ClusterBuilderRD::bake_cluster() { } else { RD::get_singleton()->barrier(RD::BARRIER_MASK_TRANSFER, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } - RENDER_TIMESTAMP("<Bake Cluster"); + RENDER_TIMESTAMP("< Bake 3D Cluster"); RD::get_singleton()->draw_command_end_label(); } diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 6c28cfd134..a5a9dae0b9 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -60,7 +60,7 @@ RID EffectsRD::_get_uniform_set_from_image(RID p_image) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_image); + u.append_id(p_image); uniforms.push_back(u); //any thing with the same configuration (one texture in binding 0 for set 0), is good RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, 0), 1); @@ -82,7 +82,7 @@ RID EffectsRD::_get_uniform_set_for_input(RID p_texture) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_INPUT_ATTACHMENT; u.binding = 0; - u.ids.push_back(p_texture); + u.append_id(p_texture); uniforms.push_back(u); // This is specific to our subpass shader RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, TONEMAP_MODE_SUBPASS), 0); @@ -104,8 +104,8 @@ RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture); uniforms.push_back(u); // anything with the same configuration (one texture in binding 0 for set 0), is good RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, 0), 0); @@ -132,16 +132,16 @@ RID EffectsRD::_get_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2 RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture1); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture1); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 1; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture2); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture2); uniforms.push_back(u); } // anything with the same configuration (one texture in binding 0 for set 0), is good @@ -164,8 +164,8 @@ RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_m RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture); uniforms.push_back(u); //any thing with the same configuration (one texture in binding 0 for set 0), is good RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, 0), 0); @@ -191,8 +191,8 @@ RID EffectsRD::_get_compute_uniform_set_from_texture_and_sampler(RID p_texture, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_sampler); - u.ids.push_back(p_texture); + u.append_id(p_sampler); + u.append_id(p_texture); uniforms.push_back(u); //any thing with the same configuration (one texture in binding 0 for set 0), is good RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.blur_shader.version_get_shader(ssao.blur_shader_version, 0), 0); @@ -219,16 +219,16 @@ RID EffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture1); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture1); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 1; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture2); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture2); uniforms.push_back(u); } //any thing with the same configuration (one texture in binding 0 for set 0), is good @@ -256,14 +256,14 @@ RID EffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_te RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_texture1); + u.append_id(p_texture1); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(p_texture2); + u.append_id(p_texture2); uniforms.push_back(u); } //any thing with the same configuration (one texture in binding 0 for set 0), is good @@ -332,7 +332,7 @@ void EffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer RD::get_singleton()->draw_list_draw(draw_list, true); } -void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary) { +void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview) { memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); if (p_flip_y) { @@ -348,10 +348,18 @@ void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, copy_to_fb.push_constant.srgb = true; } + CopyToFBMode mode; + if (p_multiview) { + mode = p_secondary.is_valid() ? COPY_TO_FB_MULTIVIEW_WITH_DEPTH : COPY_TO_FB_MULTIVIEW; + } else { + mode = p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY; + } + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); if (p_secondary.is_valid()) { + // TODO may need to do this differently when reading from depth buffer for multiview RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_secondary), 1); } RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); @@ -638,13 +646,13 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R ssr.push_constant.metallic_mask[3] = CLAMP(p_metallic_mask.a * 255.0, 0, 255); store_camera(p_camera, ssr.push_constant.projection); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[(p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[(p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL]); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr.push_constant, sizeof(ScreenSpaceReflectionPushConstant)); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_scale_depth), 0); - if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { + if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 1); } else { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 1); @@ -655,7 +663,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); } - if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { + if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) { //blur RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -667,10 +675,10 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R ssr_filter.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0]; ssr_filter.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1]; ssr_filter.push_constant.vertical = 0; - if (p_roughness_quality == RS::ENV_SSR_ROUGNESS_QUALITY_LOW) { + if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_LOW) { ssr_filter.push_constant.steps = p_max_steps / 3; ssr_filter.push_constant.increment = 3; - } else if (p_roughness_quality == RS::ENV_SSR_ROUGNESS_QUALITY_MEDIUM) { + } else if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_MEDIUM) { ssr_filter.push_constant.steps = p_max_steps / 2; ssr_filter.push_constant.increment = 2; } else { @@ -1381,28 +1389,28 @@ void EffectsRD::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_depth_mipmaps[depth_index + 1]); + u.append_id(p_depth_mipmaps[depth_index + 1]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(p_depth_mipmaps[depth_index + 2]); + u.append_id(p_depth_mipmaps[depth_index + 2]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(p_depth_mipmaps[depth_index + 3]); + u.append_id(p_depth_mipmaps[depth_index + 3]); uniforms.push_back(u); } if (use_full_mips) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(p_depth_mipmaps[4]); + u.append_id(p_depth_mipmaps[4]); uniforms.push_back(u); } ss_effects.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, use_full_mips ? 6 : 2), 2); @@ -1529,22 +1537,22 @@ void EffectsRD::generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(default_sampler); - u.ids.push_back(p_depth_mipmaps_texture); + u.append_id(default_sampler); + u.append_id(p_depth_mipmaps_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(p_normal_buffer); + u.append_id(p_normal_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; - u.ids.push_back(ss_effects.gather_constants_buffer); + u.append_id(ss_effects.gather_constants_buffer); uniforms.push_back(u); } r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0), 0); @@ -1556,22 +1564,22 @@ void EffectsRD::generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_ao_pong); + u.append_id(p_ao_pong); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 1; - u.ids.push_back(default_sampler); - u.ids.push_back(p_importance_map); + u.append_id(default_sampler); + u.append_id(p_importance_map); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(ssao.importance_map_load_counter); + u.append_id(ssao.importance_map_load_counter); uniforms.push_back(u); } r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1); @@ -1803,15 +1811,15 @@ void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(default_mipmap_sampler); - u.ids.push_back(p_diffuse); + u.append_id(default_mipmap_sampler); + u.append_id(p_diffuse); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 1; - u.ids.push_back(ssil.projection_uniform_buffer); + u.append_id(ssil.projection_uniform_buffer); uniforms.push_back(u); } r_projection_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 3); @@ -1823,22 +1831,22 @@ void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(default_sampler); - u.ids.push_back(p_depth_mipmaps_texture); + u.append_id(default_sampler); + u.append_id(p_depth_mipmaps_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(p_normal_buffer); + u.append_id(p_normal_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; - u.ids.push_back(ss_effects.gather_constants_buffer); + u.append_id(ss_effects.gather_constants_buffer); uniforms.push_back(u); } r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 0); @@ -1850,22 +1858,22 @@ void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_ssil_pong); + u.append_id(p_ssil_pong); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 1; - u.ids.push_back(default_sampler); - u.ids.push_back(p_importance_map); + u.append_id(default_sampler); + u.append_id(p_importance_map); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(ssil.importance_map_load_counter); + u.append_id(ssil.importance_map_load_counter); uniforms.push_back(u); } r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 2), 1); @@ -2032,7 +2040,7 @@ void EffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, u memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id; - roughness.push_constant.roughness = p_roughness; + roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. roughness.push_constant.sample_count = p_sample_count; roughness.push_constant.use_direct_write = p_roughness == 0.0; roughness.push_constant.face_size = p_size; @@ -2060,7 +2068,7 @@ void EffectsRD::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_fra memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); roughness.push_constant.face_id = p_face_id; - roughness.push_constant.roughness = p_roughness; + roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. roughness.push_constant.sample_count = p_sample_count; roughness.push_constant.use_direct_write = p_roughness == 0.0; roughness.push_constant.face_size = p_size; @@ -2123,7 +2131,7 @@ void EffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = i; - u.ids.push_back(p_dest_cubemap[i]); + u.append_id(p_dest_cubemap[i]); uniforms.push_back(u); } if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) { @@ -2367,15 +2375,26 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { copy_modes.push_back("\n"); copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); + copy_modes.push_back("\n#define MULTIVIEW\n"); + copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n"); copy_to_fb.shader.initialize(copy_modes); + if (!RendererCompositorRD::singleton->is_xr_enabled()) { + copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW, false); + copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW_WITH_DEPTH, false); + } + copy_to_fb.shader_version = copy_to_fb.shader.version_create(); //use additive for (int i = 0; i < COPY_TO_FB_MAX; i++) { - copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + if (copy_to_fb.shader.is_variant_enabled(i)) { + copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + } else { + copy_to_fb.pipelines[i].clear(); + } } } @@ -2632,7 +2651,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(ssao.importance_map_load_counter); + u.append_id(ssao.importance_map_load_counter); uniforms.push_back(u); } ssao.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2), 2); @@ -2747,7 +2766,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(filter.coefficient_buffer); + u.append_id(filter.coefficient_buffer); uniforms.push_back(u); } filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.raster_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); @@ -2765,7 +2784,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(filter.coefficient_buffer); + u.append_id(filter.coefficient_buffer); uniforms.push_back(u); } filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); @@ -2902,7 +2921,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(ssil.importance_map_load_counter); + u.append_id(ssil.importance_map_load_counter); uniforms.push_back(u); } ssil.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 2), 2); diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index f5e5b1ace7..eca5e09800 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -203,6 +203,9 @@ private: COPY_TO_FB_COPY, COPY_TO_FB_COPY_PANORAMA_TO_DP, COPY_TO_FB_COPY2, + + COPY_TO_FB_MULTIVIEW, + COPY_TO_FB_MULTIVIEW_WITH_DEPTH, COPY_TO_FB_MAX, }; @@ -893,7 +896,7 @@ public: bool get_prefer_raster_effects(); void fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness); - void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID()); + void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false); void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false); void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index d113fcd4f0..07298e93b7 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -30,6 +30,7 @@ #include "render_forward_clustered.h" #include "core/config/project_settings.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/rendering_server_default.h" @@ -186,12 +187,11 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() { void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) { clear(); - ERR_FAIL_COND_MSG(p_view_count != 1, "Multiple views is currently not supported in this renderer, please use the mobile renderer for VR support"); - msaa = p_msaa; width = p_width; height = p_height; + view_count = p_view_count; color = p_color_buffer; depth = p_depth_buffer; @@ -202,20 +202,25 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c fb.push_back(p_color_buffer); fb.push_back(depth); - color_fb = RD::get_singleton()->framebuffer_create(fb); + color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count); } { Vector<RID> fb; fb.push_back(depth); - depth_fb = RD::get_singleton()->framebuffer_create(fb); + depth_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count); } } else { RD::TextureFormat tf; + if (view_count > 1) { + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + } else { + tf.texture_type = RD::TEXTURE_TYPE_2D; + } tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = p_width; tf.height = p_height; - tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = view_count; // create a layer for every view tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = { @@ -240,13 +245,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c fb.push_back(color_msaa); fb.push_back(depth_msaa); - color_fb = RD::get_singleton()->framebuffer_create(fb); + color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count); } { Vector<RID> fb; fb.push_back(depth_msaa); - depth_fb = RD::get_singleton()->framebuffer_create(fb); + depth_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count); } } } @@ -416,22 +421,23 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p switch (p_pass_mode) { case PASS_MODE_COLOR: { if (element_info.uses_lightmap) { - pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS; + pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS; } else { - pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS; + pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS; } } break; case PASS_MODE_COLOR_TRANSPARENT: { if (element_info.uses_lightmap) { - pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS; + pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS; } else { if (element_info.uses_forward_gi) { pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_FORWARD_GI; } - pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS; + pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS; } } break; case PASS_MODE_COLOR_SPECULAR: { + ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for specular pass"); if (element_info.uses_lightmap) { pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR; } else { @@ -440,21 +446,26 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p } break; case PASS_MODE_SHADOW: case PASS_MODE_DEPTH: { - pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS; + pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS; } break; case PASS_MODE_SHADOW_DP: { + ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for shadow DP pass"); pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_DP; } break; case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: { + ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for depth/roughness pass"); pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS; } break; case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: { + ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for voxel GI pass"); pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI; } break; case PASS_MODE_DEPTH_MATERIAL: { + ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for material pass"); pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL; } break; case PASS_MODE_SDF: { + ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for SDF pass"); pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_SDF; } break; } @@ -604,6 +615,12 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.camera_matrix); RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix); + for (uint32_t v = 0; v < p_render_data->view_count; v++) { + projection = correction * p_render_data->view_projection[v]; + RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]); + RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]); + } + scene_state.ubo.z_far = p_render_data->z_far; scene_state.ubo.z_near = p_render_data->z_near; @@ -824,7 +841,6 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat if (p_index >= (int)scene_state.uniform_buffers.size()) { uint32_t from = scene_state.uniform_buffers.size(); scene_state.uniform_buffers.resize(p_index + 1); - render_pass_uniform_sets.resize(p_index + 1); for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); } @@ -1200,8 +1216,6 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps } void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) { - ERR_FAIL_COND_MSG(p_render_data->view_count != 1, "Multiview is currently not supported in the clustered renderer. Please use the mobile renderer for VR."); - RenderBufferDataForwardClustered *render_buffer = nullptr; if (p_render_data->render_buffers.is_valid()) { render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); @@ -1417,7 +1431,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi); if (needs_pre_resolve) { - RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (parallel)"); + RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (Parallel)"); } else { RENDER_TIMESTAMP("Render Depth Pre-Pass"); } @@ -1434,7 +1448,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID()); bool finish_depth = using_ssao || using_sdfgi || using_voxelgi; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); RD::get_singleton()->draw_command_end_label(); @@ -1444,8 +1458,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RENDER_TIMESTAMP("Resolve Depth Pre-Pass"); - RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass"); + RENDER_TIMESTAMP("Resolve Depth Pre-Pass (MSAA)"); + RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass (MSAA)"); if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) { if (needs_pre_resolve) { RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); @@ -1492,7 +1506,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); if (will_continue_color && using_separate_specular) { // close the specular framebuffer, as it's no longer used @@ -1538,14 +1552,16 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (draw_sky || draw_sky_fog_only) { RENDER_TIMESTAMP("Render Sky"); - CameraMatrix projection = p_render_data->cam_projection; + RD::get_singleton()->draw_command_begin_label("Draw Sky"); + if (p_render_data->reflection_probe.is_valid()) { CameraMatrix correction; correction.set_depth_correction(true); - projection = correction * p_render_data->cam_projection; + CameraMatrix projection = correction * p_render_data->cam_projection; + sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time); + } else { + sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); } - RD::get_singleton()->draw_command_begin_label("Draw Sky"); - sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time); RD::get_singleton()->draw_command_end_label(); } @@ -1562,15 +1578,15 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (using_separate_specular) { if (using_sss) { - RENDER_TIMESTAMP("Sub Surface Scattering"); - RD::get_singleton()->draw_command_begin_label("Process Sub Surface Scattering"); + RENDER_TIMESTAMP("Sub-Surface Scattering"); + RD::get_singleton()->draw_command_begin_label("Process Sub-Surface Scattering"); _process_sss(p_render_data->render_buffers, p_render_data->cam_projection); RD::get_singleton()->draw_command_end_label(); } if (using_ssr) { - RENDER_TIMESTAMP("Screen Space Reflection"); - RD::get_singleton()->draw_command_begin_label("Process Screen Space Reflections"); + RENDER_TIMESTAMP("Screen-Space Reflections"); + RD::get_singleton()->draw_command_begin_label("Process Screen-Space Reflections"); _process_ssr(p_render_data->render_buffers, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED); RD::get_singleton()->draw_command_end_label(); } else { @@ -1590,16 +1606,16 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co _render_buffers_copy_depth_texture(p_render_data); } - RENDER_TIMESTAMP("Render Transparent Pass"); + RENDER_TIMESTAMP("Render 3D Transparent Pass"); - RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); + RD::get_singleton()->draw_command_begin_label("Render 3D Transparent Pass"); rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, true); _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); { - RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR_TRANSPARENT, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold); + RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR_TRANSPARENT, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); } @@ -1618,7 +1634,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Copy framebuffer for SSIL"); if (using_ssil) { - RENDER_TIMESTAMP("Copy Final Framebuffer"); + RENDER_TIMESTAMP("Copy Final Framebuffer (SSIL)"); _copy_framebuffer_to_ssil(p_render_data->render_buffers); } RD::get_singleton()->draw_command_end_label(); @@ -1649,6 +1665,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page RenderDataRD render_data; render_data.cam_projection = p_projection; render_data.cam_transform = p_transform; + render_data.view_projection[0] = p_projection; render_data.z_far = p_zfar; render_data.z_near = 0.0; render_data.cluster_size = 1; @@ -1720,7 +1737,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); + RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect); } @@ -1731,13 +1748,14 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { } void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { - RENDER_TIMESTAMP("Setup Render Collider Heightfield"); + RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); RenderDataRD render_data; render_data.cam_projection = p_cam_projection; render_data.cam_transform = p_cam_transform; + render_data.view_projection[0] = p_cam_projection; render_data.z_near = 0.0; render_data.z_far = p_cam_projection.get_z_far(); render_data.cluster_size = 1; @@ -1769,13 +1787,14 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con } void RenderForwardClustered::_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) { - RENDER_TIMESTAMP("Setup Rendering Material"); + RENDER_TIMESTAMP("Setup Rendering 3D Material"); - RD::get_singleton()->draw_command_begin_label("Render Material"); + RD::get_singleton()->draw_command_begin_label("Render 3D Material"); RenderDataRD render_data; render_data.cam_projection = p_cam_projection; render_data.cam_transform = p_cam_transform; + render_data.view_projection[0] = p_cam_projection; render_data.cluster_size = 1; render_data.cluster_max_elements = 32; render_data.instances = &p_instances; @@ -1795,7 +1814,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); - RENDER_TIMESTAMP("Render Material"); + RENDER_TIMESTAMP("Render 3D Material"); { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set); @@ -1841,7 +1860,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); - RENDER_TIMESTAMP("Render Material"); + RENDER_TIMESTAMP("Render 3D Material"); { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set, true); @@ -1991,11 +2010,9 @@ void RenderForwardClustered::_update_render_base_uniform_set() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 1; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -2008,6 +2025,9 @@ void RenderForwardClustered::_update_render_base_uniform_set() { ids_ptr[9] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); + uniforms.push_back(u); } @@ -2015,7 +2035,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(scene_shader.shadow_sampler); + u.append_id(scene_shader.shadow_sampler); uniforms.push_back(u); } @@ -2042,7 +2062,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { } break; } - u.ids.push_back(sampler); + u.append_id(sampler); uniforms.push_back(u); } @@ -2069,7 +2089,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { } break; } - u.ids.push_back(sampler); + u.append_id(sampler); uniforms.push_back(u); } @@ -2077,14 +2097,14 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_omni_light_buffer()); + u.append_id(get_omni_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_spot_light_buffer()); + u.append_id(get_spot_light_buffer()); uniforms.push_back(u); } @@ -2092,28 +2112,28 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_reflection_probe_buffer()); + u.append_id(get_reflection_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(get_directional_light_buffer()); + u.append_id(get_directional_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.lightmap_buffer); + u.append_id(scene_state.lightmap_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.lightmap_capture_buffer); + u.append_id(scene_state.lightmap_capture_buffer); uniforms.push_back(u); } { @@ -2121,7 +2141,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); - u.ids.push_back(decal_atlas); + u.append_id(decal_atlas); uniforms.push_back(u); } { @@ -2129,14 +2149,14 @@ void RenderForwardClustered::_update_render_base_uniform_set() { u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); - u.ids.push_back(decal_atlas); + u.append_id(decal_atlas); uniforms.push_back(u); } { RD::Uniform u; u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_decal_buffer()); + u.append_id(get_decal_buffer()); uniforms.push_back(u); } @@ -2144,7 +2164,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 14; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2152,7 +2172,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 15; - u.ids.push_back(sdfgi_get_ubo()); + u.append_id(sdfgi_get_ubo()); uniforms.push_back(u); } @@ -2161,9 +2181,6 @@ void RenderForwardClustered::_update_render_base_uniform_set() { } RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) { - //there should always be enough uniform buffers for render passes, otherwise bugs - ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID()); - RenderBufferDataForwardClustered *rb = nullptr; if (p_render_data && p_render_data->render_buffers.is_valid()) { rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); @@ -2177,7 +2194,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(scene_state.uniform_buffers[p_index]); + u.append_id(scene_state.uniform_buffers[p_index]); uniforms.push_back(u); } { @@ -2188,7 +2205,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (instance_buffer == RID()) { instance_buffer = scene_shader.default_vec4_xform_buffer; // any buffer will do since its not used } - u.ids.push_back(instance_buffer); + u.append_id(instance_buffer); uniforms.push_back(u); } { @@ -2196,12 +2213,12 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (p_radiance_texture.is_valid()) { radiance_texture = p_radiance_texture; } else { - radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(radiance_texture); + u.append_id(radiance_texture); uniforms.push_back(u); } @@ -2211,9 +2228,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (ref_texture.is_valid()) { - u.ids.push_back(ref_texture); + u.append_id(ref_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); } uniforms.push_back(u); } @@ -2227,9 +2244,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend texture = shadow_atlas_get_texture(p_render_data->shadow_atlas); } if (!texture.is_valid()) { - texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { @@ -2237,9 +2254,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { - u.ids.push_back(directional_shadow_get_texture()); + u.append_id(directional_shadow_get_texture()); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); } uniforms.push_back(u); } @@ -2247,16 +2264,16 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(scene_state.max_lightmaps); - RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { if (p_render_data && i < p_render_data->lightmaps->size()) { RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]); RID texture = storage->lightmap_get_texture(base); - RID rd_texture = storage->texture_get_rd_texture(texture); - u.ids.write[i] = rd_texture; + RID rd_texture = texture_storage->texture_get_rd_texture(texture); + u.append_id(rd_texture); } else { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } } @@ -2266,17 +2283,16 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(MAX_VOXEL_GI_INSTANCESS); - RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { if (p_render_data && i < (int)p_render_data->voxel_gi_instances->size()) { RID tex = gi.voxel_gi_instance_get_texture((*p_render_data->voxel_gi_instances)[i]); if (!tex.is_valid()) { tex = default_tex; } - u.ids.write[i] = tex; + u.append_id(tex); } else { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } } @@ -2288,7 +2304,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = (p_render_data && p_render_data->cluster_buffer.is_valid()) ? p_render_data->cluster_buffer : scene_shader.default_vec4_xform_buffer; - u.ids.push_back(cb); + u.append_id(cb); uniforms.push_back(u); } @@ -2297,8 +2313,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID dbt = rb ? render_buffers_get_back_depth_texture(p_render_data->render_buffers) : RID(); - RID texture = (dbt.is_valid()) ? dbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); - u.ids.push_back(texture); + RID texture = (dbt.is_valid()) ? dbt : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + u.append_id(texture); uniforms.push_back(u); } { @@ -2306,8 +2322,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID(); - RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + RID texture = bbt.is_valid() ? bbt : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); uniforms.push_back(u); } @@ -2316,8 +2332,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL); - u.ids.push_back(texture); + RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_NORMAL); + u.append_id(texture); uniforms.push_back(u); } @@ -2326,8 +2342,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID aot = rb ? render_buffers_get_ao_texture(p_render_data->render_buffers) : RID(); - RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + RID texture = aot.is_valid() ? aot : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); uniforms.push_back(u); } @@ -2336,8 +2352,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID ambient_buffer = rb ? render_buffers_get_gi_ambient_texture(p_render_data->render_buffers) : RID(); - RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + RID texture = ambient_buffer.is_valid() ? ambient_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); uniforms.push_back(u); } @@ -2346,8 +2362,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 14; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID reflection_buffer = rb ? render_buffers_get_gi_reflection_texture(p_render_data->render_buffers) : RID(); - RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + RID texture = reflection_buffer.is_valid() ? reflection_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); uniforms.push_back(u); } { @@ -2358,9 +2374,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) { t = render_buffers_get_sdfgi_irradiance_probes(p_render_data->render_buffers); } else { - t = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + t = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } - u.ids.push_back(t); + u.append_id(t); uniforms.push_back(u); } { @@ -2368,9 +2384,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 16; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) { - u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_data->render_buffers)); + u.append_id(render_buffers_get_sdfgi_occlusion_texture(p_render_data->render_buffers)); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } uniforms.push_back(u); } @@ -2378,7 +2394,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 17; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(rb ? render_buffers_get_voxel_gi_buffer(p_render_data->render_buffers) : render_buffers_get_default_voxel_gi_buffer()); + u.append_id(rb ? render_buffers_get_voxel_gi_buffer(p_render_data->render_buffers) : render_buffers_get_default_voxel_gi_buffer()); uniforms.push_back(u); } { @@ -2389,12 +2405,12 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (rb && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) { vfog = render_buffers_get_volumetric_fog_texture(p_render_data->render_buffers); if (vfog.is_null()) { - vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + vfog = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); } } else { - vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + vfog = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); } - u.ids.push_back(vfog); + u.append_id(vfog); uniforms.push_back(u); } { @@ -2402,62 +2418,49 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 19; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID ssil = rb ? render_buffers_get_ssil_texture(p_render_data->render_buffers) : RID(); - RID texture = ssil.is_valid() ? ssil : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + RID texture = ssil.is_valid() ? ssil : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); uniforms.push_back(u); } } - if (p_index >= (int)render_pass_uniform_sets.size()) { - render_pass_uniform_sets.resize(p_index + 1); - } - - if (render_pass_uniform_sets[p_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[p_index])) { - RD::get_singleton()->free(render_pass_uniform_sets[p_index]); - } - - render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET); - return render_pass_uniform_sets[p_index]; + return UniformSetCacheRD::get_singleton()->get_cache_vec(scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET, uniforms); } RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) { - if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) { - RD::get_singleton()->free(sdfgi_pass_uniform_set); - } - Vector<RD::Uniform> uniforms; { RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(scene_state.uniform_buffers[0]); + u.append_id(scene_state.uniform_buffers[0]); uniforms.push_back(u); } { RD::Uniform u; u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.instance_buffer[RENDER_LIST_SECONDARY]); + u.append_id(scene_state.instance_buffer[RENDER_LIST_SECONDARY]); uniforms.push_back(u); } { // No radiance texture. - RID radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + RID radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(radiance_texture); + u.append_id(radiance_texture); uniforms.push_back(u); } { // No reflection atlas. - RID ref_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); + RID ref_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(ref_texture); + u.append_id(ref_texture); uniforms.push_back(u); } @@ -2466,8 +2469,8 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); - u.ids.push_back(texture); + RID texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + u.append_id(texture); uniforms.push_back(u); } @@ -2476,8 +2479,8 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); - u.ids.push_back(texture); + RID texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + u.append_id(texture); uniforms.push_back(u); } @@ -2486,10 +2489,10 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(scene_state.max_lightmaps); - RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } uniforms.push_back(u); @@ -2500,10 +2503,10 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(MAX_VOXEL_GI_INSTANCESS); - RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } uniforms.push_back(u); @@ -2514,7 +2517,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = scene_shader.default_vec4_xform_buffer; - u.ids.push_back(cb); + u.append_id(cb); uniforms.push_back(u); } @@ -2524,33 +2527,32 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(p_albedo_texture); + u.append_id(p_albedo_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; - u.ids.push_back(p_emission_texture); + u.append_id(p_emission_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; - u.ids.push_back(p_emission_aniso_texture); + u.append_id(p_emission_aniso_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 12; - u.ids.push_back(p_geom_facing_texture); + u.append_id(p_geom_facing_texture); uniforms.push_back(u); } - sdfgi_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_sdfgi_rd, RENDER_PASS_UNIFORM_SET); - return sdfgi_pass_uniform_set; + return UniformSetCacheRD::get_singleton()->get_cache_vec(scene_shader.default_shader_sdfgi_rd, RENDER_PASS_UNIFORM_SET, uniforms); } RID RenderForwardClustered::_render_buffers_get_normal_texture(RID p_render_buffers) { @@ -2583,7 +2585,7 @@ void RenderForwardClustered::_geometry_instance_mark_dirty(GeometryInstance *p_g void RenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture; - bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha); + bool has_base_alpha = (p_material->shader_data->uses_alpha && !p_material->shader_data->uses_alpha_clip) || has_read_screen_alpha; bool has_blend_alpha = p_material->shader_data->uses_blend_alpha; bool has_alpha = has_base_alpha || has_blend_alpha; @@ -2628,7 +2630,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet SceneShaderForwardClustered::MaterialData *material_shadow = nullptr; void *surface_shadow = nullptr; - if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass) { + if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip) { flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL; material_shadow = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(scene_shader.default_material, RendererStorageRD::SHADER_TYPE_3D); @@ -3218,17 +3220,6 @@ RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) : RenderForwardClustered::~RenderForwardClustered() { directional_shadow_atlas_set_size(0); - //clear base uniform set if still valid - for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) { - if (render_pass_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[i])) { - RD::get_singleton()->free(render_pass_uniform_sets[i]); - } - } - - if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) { - RD::get_singleton()->free(sdfgi_pass_uniform_set); - } - { for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) { RD::get_singleton()->free(scene_state.uniform_buffers[i]); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index f858887bd0..a219b98204 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -107,6 +107,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID color_specular_fb; RID specular_only_fb; int width, height; + uint32_t view_count; RID render_sdfgi_uniform_set; void ensure_specular(); @@ -121,8 +122,6 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _allocate_normal_roughness_texture(RenderBufferDataForwardClustered *rb); RID render_base_uniform_set; - LocalVector<RID> render_pass_uniform_sets; - RID sdfgi_pass_uniform_set; uint64_t lightmap_texture_array_version = 0xFFFFFFFF; @@ -157,6 +156,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { bool reverse_cull = false; PassMode pass_mode = PASS_MODE_COLOR; bool no_gi = false; + uint32_t view_count = 1; RID render_pass_uniform_set; bool force_wireframe = false; Vector2 uv_offset; @@ -168,13 +168,14 @@ class RenderForwardClustered : public RendererSceneRenderRD { uint32_t barrier = RD::BARRIER_MASK_ALL; bool use_directional_soft_shadow = false; - RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { + RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { elements = p_elements; element_info = p_element_info; element_count = p_element_count; reverse_cull = p_reverse_cull; pass_mode = p_pass_mode; no_gi = p_no_gi; + view_count = p_view_count; render_pass_uniform_set = p_render_pass_uniform_set; force_wireframe = p_force_wireframe; uv_offset = p_uv_offset; @@ -221,6 +222,9 @@ class RenderForwardClustered : public RendererSceneRenderRD { float camera_matrix[16]; float inv_camera_matrix[16]; + float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; + float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16]; + float viewport_size[2]; float screen_pixel_size[2]; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 7987a98b0e..2c42366959 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/math/math_defs.h" #include "render_forward_clustered.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" using namespace RendererSceneRenderImplementation; @@ -57,6 +58,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { uses_point_size = false; uses_alpha = false; + uses_alpha_clip = false; uses_blend_alpha = false; uses_depth_pre_pass = false; uses_discard = false; @@ -107,6 +109,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { actions.render_mode_flags["particle_trails"] = &uses_particle_trails; actions.usage_flag_pointers["ALPHA"] = &uses_alpha; + actions.usage_flag_pointers["ALPHA_SCISSOR_THRESHOLD"] = &uses_alpha_clip; actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass; actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss; @@ -149,7 +152,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { print_line(gen_code.defines[i]); } - Map<String, String>::Element * el = gen_code.code.front(); + Map<String, String>::Element *el = gen_code.code.front(); while (el) { print_line("\n**code " + el->key() + ":\n" + el->value()); @@ -282,6 +285,12 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { SHADER_VERSION_LIGHTMAP_COLOR_PASS, SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, SHADER_VERSION_LIGHTMAP_COLOR_PASS, + + SHADER_VERSION_DEPTH_PASS_MULTIVIEW, + SHADER_VERSION_COLOR_PASS_MULTIVIEW, + SHADER_VERSION_COLOR_PASS_MULTIVIEW, + SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, + SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, }; shader_version = shader_version_table[k]; @@ -297,7 +306,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { RD::PipelineDepthStencilState depth_stencil = depth_stencil_state; RD::PipelineMultisampleState multisample_state; - if (k == PIPELINE_VERSION_TRANSPARENT_PASS || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS) { + if (k == PIPELINE_VERSION_TRANSPARENT_PASS || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS || k == PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW) { if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) { multisample_state.enable_alpha_to_coverage = true; } else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) { @@ -310,9 +319,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { if (depth_draw == DEPTH_DRAW_OPAQUE) { depth_stencil.enable_depth_write = false; //alpha does not draw depth } - } else if (k == PIPELINE_VERSION_OPAQUE_PASS || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS) { + } else if (k == PIPELINE_VERSION_OPAQUE_PASS || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS || k == PIPELINE_VERSION_OPAQUE_PASS_MULTIVIEW || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW) { blend_state = blend_state_opaque; - } else if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP) { + } else if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW || k == PIPELINE_VERSION_DEPTH_PASS_DP) { //none, leave empty } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) { blend_state = blend_state_depth_normal_roughness; @@ -501,7 +510,18 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin shader_versions.push_back("\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR + // multiview versions of our shaders + shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_DEPTH_PASS_MULTIVIEW + shader_versions.push_back("\n#define USE_MULTIVIEW\n"); // SHADER_VERSION_COLOR_PASS_MULTIVIEW + shader_versions.push_back("\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW + shader.initialize(shader_versions, p_defines); + + if (!RendererCompositorRD::singleton->is_xr_enabled()) { + shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_MULTIVIEW, false); + shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_MULTIVIEW, false); + shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, false); + } } storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs); @@ -516,7 +536,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix"; actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix"; actions.renames["PROJECTION_MATRIX"] = "projection_matrix"; - actions.renames["INV_PROJECTION_MATRIX"] = "scene_data.inv_projection_matrix"; + actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix"; actions.renames["MODELVIEW_MATRIX"] = "modelview"; actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal"; @@ -557,7 +577,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.renames["RIM"] = "rim"; actions.renames["RIM_TINT"] = "rim_tint"; actions.renames["CLEARCOAT"] = "clearcoat"; - actions.renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; + actions.renames["CLEARCOAT_ROUGHNESS"] = "clearcoat_roughness"; actions.renames["ANISOTROPY"] = "anisotropy"; actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; actions.renames["SSS_STRENGTH"] = "sss_strength"; @@ -587,8 +607,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.renames["CUSTOM3"] = "custom3_attrib"; actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; - // not implemented but need these just in case code is in the shaders - actions.renames["VIEW_INDEX"] = "0"; + actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "0"; actions.renames["VIEW_RIGHT"] = "1"; @@ -607,7 +626,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n"; actions.usage_defines["RIM_TINT"] = "@RIM"; actions.usage_defines["CLEARCOAT"] = "#define LIGHT_CLEARCOAT_USED\n"; - actions.usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT"; + actions.usage_defines["CLEARCOAT_ROUGHNESS"] = "@CLEARCOAT"; actions.usage_defines["ANISOTROPY"] = "#define LIGHT_ANISOTROPY_USED\n"; actions.usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY"; actions.usage_defines["AO"] = "#define AO_USED\n"; @@ -663,20 +682,12 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n"; - bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx"); - - if (!force_blinn) { - actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - } else { - actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; - } + actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; actions.custom_samplers["SCREEN_TEXTURE"] = "material_samplers[3]"; // linear filter with mipmaps actions.custom_samplers["DEPTH_TEXTURE"] = "material_samplers[3]"; actions.custom_samplers["NORMAL_ROUGHNESS_TEXTURE"] = "material_samplers[1]"; // linear filter - actions.render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; - actions.render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; actions.render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; actions.render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; @@ -759,7 +770,7 @@ void fragment() { Vector<RD::Uniform> uniforms; RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(default_vec4_xform_buffer); + u.append_id(default_vec4_xform_buffer); u.binding = 0; uniforms.push_back(u); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 33049fad9c..4398517259 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -55,6 +55,11 @@ public: SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR, SHADER_VERSION_LIGHTMAP_COLOR_PASS, SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, + + SHADER_VERSION_DEPTH_PASS_MULTIVIEW, + SHADER_VERSION_COLOR_PASS_MULTIVIEW, + SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, + SHADER_VERSION_MAX }; @@ -71,6 +76,13 @@ public: PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS, PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR, PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS, + + PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW, + PIPELINE_VERSION_OPAQUE_PASS_MULTIVIEW, + PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW, + PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW, + PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW, + PIPELINE_VERSION_MAX }; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index a623af7533..1789319aaf 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -306,7 +306,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(scene_state.uniform_buffers[p_index]); + u.append_id(scene_state.uniform_buffers[p_index]); uniforms.push_back(u); } @@ -315,12 +315,12 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ if (p_radiance_texture.is_valid()) { radiance_texture = p_radiance_texture; } else { - radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(radiance_texture); + u.append_id(radiance_texture); uniforms.push_back(u); } @@ -330,9 +330,9 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (ref_texture.is_valid()) { - u.ids.push_back(ref_texture); + u.append_id(ref_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); } uniforms.push_back(u); } @@ -346,9 +346,9 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ texture = shadow_atlas_get_texture(p_render_data->shadow_atlas); } if (!texture.is_valid()) { - texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { @@ -356,9 +356,9 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { - u.ids.push_back(directional_shadow_get_texture()); + u.append_id(directional_shadow_get_texture()); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); } uniforms.push_back(u); } @@ -368,16 +368,16 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(scene_state.max_lightmaps); - RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { if (p_render_data && i < p_render_data->lightmaps->size()) { RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]); RID texture = storage->lightmap_get_texture(base); - RID rd_texture = storage->texture_get_rd_texture(texture); - u.ids.write[i] = rd_texture; + RID rd_texture = texture_storage->texture_get_rd_texture(texture); + u.append_id(rd_texture); } else { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } } @@ -390,7 +390,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(MAX_VOXEL_GI_INSTANCESS); - RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + RID default_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { if (i < (int)p_voxel_gi_instances.size()) { RID tex = gi.voxel_gi_instance_get_texture(p_voxel_gi_instances[i]); @@ -411,7 +411,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer; - u.ids.push_back(cb); + u.append_id(cb); uniforms.push_back(u); } */ @@ -421,8 +421,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID dbt = rb ? render_buffers_get_back_depth_texture(p_render_data->render_buffers) : RID(); - RID texture = (dbt.is_valid()) ? dbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); - u.ids.push_back(texture); + RID texture = (dbt.is_valid()) ? dbt : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); + u.append_id(texture); uniforms.push_back(u); } { @@ -430,8 +430,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID(); - RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + RID texture = bbt.is_valid() ? bbt : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(texture); uniforms.push_back(u); } @@ -653,9 +653,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (draw_sky || draw_sky_fog_only) { // !BAS! @TODO See if we can limit doing some things double and maybe even move this into _pre_opaque_render // and change Forward Clustered in the same way as we have here (but without using subpasses) - RENDER_TIMESTAMP("Setup Sky resolution buffers"); + RENDER_TIMESTAMP("Setup Sky Resolution Buffers"); - RD::get_singleton()->draw_command_begin_label("Setup Sky resolution buffers"); + RD::get_singleton()->draw_command_begin_label("Setup Sky Resolution Buffers"); if (p_render_data->reflection_probe.is_valid()) { CameraMatrix correction; @@ -972,9 +972,9 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) { /* */ void RenderForwardMobile::_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) { - RENDER_TIMESTAMP("Setup Rendering Material"); + RENDER_TIMESTAMP("Setup Rendering 3D Material"); - RD::get_singleton()->draw_command_begin_label("Render Material"); + RD::get_singleton()->draw_command_begin_label("Render 3D Material"); _update_render_base_uniform_set(); @@ -997,7 +997,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); - RENDER_TIMESTAMP("Render Material"); + RENDER_TIMESTAMP("Render 3D Material"); { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, 0); @@ -1039,7 +1039,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); - RENDER_TIMESTAMP("Render Material"); + RENDER_TIMESTAMP("Render 3D Material"); { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true, false); @@ -1089,7 +1089,7 @@ void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_ } void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { - RENDER_TIMESTAMP("Setup Render Collider Heightfield"); + RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1145,11 +1145,9 @@ void RenderForwardMobile::_update_render_base_uniform_set() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 1; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -1162,6 +1160,9 @@ void RenderForwardMobile::_update_render_base_uniform_set() { ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); + uniforms.push_back(u); } @@ -1169,7 +1170,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(scene_shader.shadow_sampler); + u.append_id(scene_shader.shadow_sampler); uniforms.push_back(u); } @@ -1196,7 +1197,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { } break; } - u.ids.push_back(sampler); + u.append_id(sampler); uniforms.push_back(u); } @@ -1223,7 +1224,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { } break; } - u.ids.push_back(sampler); + u.append_id(sampler); uniforms.push_back(u); } @@ -1231,14 +1232,14 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_omni_light_buffer()); + u.append_id(get_omni_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_spot_light_buffer()); + u.append_id(get_spot_light_buffer()); uniforms.push_back(u); } @@ -1246,28 +1247,28 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_reflection_probe_buffer()); + u.append_id(get_reflection_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(get_directional_light_buffer()); + u.append_id(get_directional_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.lightmap_buffer); + u.append_id(scene_state.lightmap_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.lightmap_capture_buffer); + u.append_id(scene_state.lightmap_capture_buffer); uniforms.push_back(u); } { @@ -1275,7 +1276,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); - u.ids.push_back(decal_atlas); + u.append_id(decal_atlas); uniforms.push_back(u); } { @@ -1283,14 +1284,14 @@ void RenderForwardMobile::_update_render_base_uniform_set() { u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); - u.ids.push_back(decal_atlas); + u.append_id(decal_atlas); uniforms.push_back(u); } { RD::Uniform u; u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_decal_buffer()); + u.append_id(get_decal_buffer()); uniforms.push_back(u); } @@ -1298,7 +1299,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 14; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2277,7 +2278,7 @@ void RenderForwardMobile::_geometry_instance_mark_dirty(GeometryInstance *p_geom void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture; - bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha); + bool has_base_alpha = ((p_material->shader_data->uses_alpha && !p_material->shader_data->uses_alpha_clip) || has_read_screen_alpha); bool has_blend_alpha = p_material->shader_data->uses_blend_alpha; bool has_alpha = has_base_alpha || has_blend_alpha; @@ -2322,7 +2323,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI SceneShaderForwardMobile::MaterialData *material_shadow = nullptr; void *surface_shadow = nullptr; - if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass) { + if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip) { flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL; material_shadow = (SceneShaderForwardMobile::MaterialData *)storage->material_get_data(scene_shader.default_material, RendererStorageRD::SHADER_TYPE_3D); diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 0b99948063..ed40e08d75 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -60,6 +60,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { uses_point_size = false; uses_alpha = false; + uses_alpha_clip = false; uses_blend_alpha = false; uses_depth_pre_pass = false; uses_discard = false; @@ -109,6 +110,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { actions.render_mode_flags["particle_trails"] = &uses_particle_trails; actions.usage_flag_pointers["ALPHA"] = &uses_alpha; + actions.usage_flag_pointers["ALPHA_SCISSOR_THRESHOLD"] = &uses_alpha_clip; actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass; // actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss; @@ -293,7 +295,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_MULTIVIEW || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW) { blend_state = blend_state_blend; - if (depth_draw == DEPTH_DRAW_OPAQUE) { + if (depth_draw == DEPTH_DRAW_OPAQUE && !uses_alpha_clip) { depth_stencil.enable_depth_write = false; //alpha does not draw depth } } else if (k == SHADER_VERSION_SHADOW_PASS || k == SHADER_VERSION_SHADOW_PASS_MULTIVIEW || k == SHADER_VERSION_SHADOW_PASS_DP) { @@ -545,7 +547,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p actions.renames["RIM"] = "rim"; actions.renames["RIM_TINT"] = "rim_tint"; actions.renames["CLEARCOAT"] = "clearcoat"; - actions.renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; + actions.renames["CLEARCOAT_ROUGHNESS"] = "clearcoat_roughness"; actions.renames["ANISOTROPY"] = "anisotropy"; actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; actions.renames["SSS_STRENGTH"] = "sss_strength"; @@ -594,7 +596,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n"; actions.usage_defines["RIM_TINT"] = "@RIM"; actions.usage_defines["CLEARCOAT"] = "#define LIGHT_CLEARCOAT_USED\n"; - actions.usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT"; + actions.usage_defines["CLEARCOAT_ROUGHNESS"] = "@CLEARCOAT"; actions.usage_defines["ANISOTROPY"] = "#define LIGHT_ANISOTROPY_USED\n"; actions.usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY"; actions.usage_defines["AO"] = "#define AO_USED\n"; @@ -649,15 +651,8 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n"; - bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx"); - if (!force_blinn) { - actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - } else { - actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; - } + actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - actions.render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; - actions.render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; actions.render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; actions.render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; @@ -741,7 +736,7 @@ void fragment() { Vector<RD::Uniform> uniforms; RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(default_vec4_xform_buffer); + u.append_id(default_vec4_xform_buffer); u.binding = 0; uniforms.push_back(u); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 0f3daef371..b30a295fa6 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -358,7 +358,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI bool use_normal; bool use_specular; - bool success = storage->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular); + bool success = canvas_texture_storage->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular); //something odd happened if (!success) { _bind_canvas_texture(p_draw_list, default_canvas_texture, p_base_filter, p_base_repeat, r_last_texture, push_constant, r_texpixel_size); @@ -694,9 +694,9 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend _bind_canvas_texture(p_draw_list, RID(), current_filter, current_repeat, last_texture, push_constant, texpixel_size); - RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3, primitive->point_count) - 1]); + RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3u, primitive->point_count) - 1]); - for (uint32_t j = 0; j < MIN(3, primitive->point_count); j++) { + for (uint32_t j = 0; j < MIN(3u, primitive->point_count); j++) { push_constant.points[j * 2 + 0] = primitive->points[j].x; push_constant.points[j * 2 + 1] = primitive->points[j].y; push_constant.uvs[j * 2 + 0] = primitive->uvs[j].x; @@ -931,7 +931,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 1; - u.ids.push_back(state.canvas_state_buffer); + u.append_id(state.canvas_state_buffer); uniforms.push_back(u); } @@ -939,7 +939,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; - u.ids.push_back(state.lights_uniform_buffer); + u.append_id(state.lights_uniform_buffer); uniforms.push_back(u); } @@ -947,7 +947,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 3; - u.ids.push_back(storage->decal_atlas_get_texture()); + u.append_id(storage->decal_atlas_get_texture()); uniforms.push_back(u); } @@ -955,7 +955,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 4; - u.ids.push_back(state.shadow_texture); + u.append_id(state.shadow_texture); uniforms.push_back(u); } @@ -963,7 +963,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 5; - u.ids.push_back(state.shadow_sampler); + u.append_id(state.shadow_sampler); uniforms.push_back(u); } @@ -977,10 +977,10 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo } else { screen = storage->render_target_get_rd_backbuffer(p_to_render_target); if (screen.is_null()) { //unallocated backbuffer - screen = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + screen = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } } - u.ids.push_back(screen); + u.append_id(screen); uniforms.push_back(u); } @@ -989,17 +989,15 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 7; RID sdf = storage->render_target_get_sdf_texture(p_to_render_target); - u.ids.push_back(sdf); + u.append_id(sdf); uniforms.push_back(u); } { //needs samplers for the material (uses custom textures) create them - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 8; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -1012,6 +1010,9 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 8, ids); + uniforms.push_back(u); } @@ -1019,7 +1020,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 9; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2244,6 +2245,8 @@ void RendererCanvasRenderRD::update() { } RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { + canvas_texture_storage = RendererRD::CanvasTextureStorage::get_singleton(); + texture_storage = RendererRD::TextureStorage::get_singleton(); storage = p_storage; { //create default samplers @@ -2256,7 +2259,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { String global_defines; - uint32_t uniform_max_size = RD::get_singleton()->limit_get(RD::LIMIT_MAX_UNIFORM_BUFFER_SIZE); + uint64_t uniform_max_size = RD::get_singleton()->limit_get(RD::LIMIT_MAX_UNIFORM_BUFFER_SIZE); if (uniform_max_size < 65536) { //Yes, you guessed right, ARM again state.max_lights_per_render = 64; @@ -2567,15 +2570,15 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(storage->get_default_rd_storage_buffer()); + u.append_id(storage->get_default_rd_storage_buffer()); uniforms.push_back(u); } state.default_transforms_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET); } - default_canvas_texture = storage->canvas_texture_allocate(); - storage->canvas_texture_initialize(default_canvas_texture); + default_canvas_texture = canvas_texture_storage->canvas_texture_allocate(); + canvas_texture_storage->canvas_texture_initialize(default_canvas_texture); state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size"); @@ -2695,6 +2698,6 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() { } RD::get_singleton()->free(state.shadow_texture); - storage->free(default_canvas_texture); + canvas_texture_storage->canvas_texture_free(default_canvas_texture); //pipelines don't need freeing, they are all gone after shaders are gone } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 84f64b6fda..c0138c4fe0 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -37,10 +37,14 @@ #include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/shader_compiler.h" class RendererCanvasRenderRD : public RendererCanvasRender { + RendererRD::CanvasTextureStorage *canvas_texture_storage; + RendererRD::TextureStorage *texture_storage; RendererStorageRD *storage; enum { diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index 606527ed24..46ec472121 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -46,7 +46,7 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID for (int i = 0; i < p_amount; i++) { RID texture = storage->render_target_get_texture(p_render_targets[i].render_target); ERR_CONTINUE(texture.is_null()); - RID rd_texture = storage->texture_get_rd_texture(texture); + RID rd_texture = texture_storage->texture_get_rd_texture(texture); ERR_CONTINUE(rd_texture.is_null()); // TODO if keep_3d_linear was set when rendering to this render target we need to add a linear->sRGB conversion in. @@ -56,8 +56,8 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(blit.sampler); - u.ids.push_back(rd_texture); + u.append_id(blit.sampler); + u.append_id(rd_texture); uniforms.push_back(u); RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0); @@ -155,6 +155,8 @@ void RendererCompositorRD::finalize() { memdelete(scene); memdelete(canvas); memdelete(storage); + memdelete(texture_storage); + memdelete(canvas_texture_storage); //only need to erase these, the rest are erased by cascade blit.shader.version_free(blit.shader_version); @@ -165,9 +167,9 @@ void RendererCompositorRD::finalize() { void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) { RD::get_singleton()->prepare_screen_for_drawing(); - RID texture = storage->texture_allocate(); - storage->texture_2d_initialize(texture, p_image); - RID rd_texture = storage->texture_get_rd_texture(texture); + RID texture = texture_storage->texture_allocate(); + texture_storage->texture_2d_initialize(texture, p_image); + RID rd_texture = texture_storage->texture_get_rd_texture(texture); RID uset; { @@ -175,8 +177,8 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(blit.sampler); - u.ids.push_back(rd_texture); + u.append_id(blit.sampler); + u.append_id(rd_texture); uniforms.push_back(u); uset = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0); } @@ -235,12 +237,14 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color RD::get_singleton()->swap_buffers(); - storage->free(texture); + texture_storage->texture_free(texture); } RendererCompositorRD *RendererCompositorRD::singleton = nullptr; RendererCompositorRD::RendererCompositorRD() { + uniform_set_cache = memnew(UniformSetCacheRD); + { String shader_cache_dir = Engine::get_singleton()->get_shader_cache_path(); if (shader_cache_dir.is_empty()) { @@ -281,11 +285,13 @@ RendererCompositorRD::RendererCompositorRD() { singleton = this; time = 0; + canvas_texture_storage = memnew(RendererRD::CanvasTextureStorage); + texture_storage = memnew(RendererRD::TextureStorage); storage = memnew(RendererStorageRD); canvas = memnew(RendererCanvasRenderRD(storage)); back_end = (bool)(int)GLOBAL_GET("rendering/vulkan/rendering/back_end"); - uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); if (back_end || textures_per_stage < 48) { scene = memnew(RendererSceneRenderImplementation::RenderForwardMobile(storage)); @@ -301,5 +307,6 @@ RendererCompositorRD::RendererCompositorRD() { } RendererCompositorRD::~RendererCompositorRD() { + memdelete(uniform_set_cache); ShaderRD::set_shader_cache_dir(String()); } diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 9a992d5819..07df38b2b2 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -39,10 +39,16 @@ #include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h" #include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" class RendererCompositorRD : public RendererCompositor { protected: + UniformSetCacheRD *uniform_set_cache; RendererCanvasRenderRD *canvas; + RendererRD::CanvasTextureStorage *canvas_texture_storage; + RendererRD::TextureStorage *texture_storage; RendererStorageRD *storage; RendererSceneRenderRD *scene; @@ -86,6 +92,8 @@ protected: static uint64_t frame; public: + RendererCanvasTextureStorage *get_canvas_texture_storage() { return canvas_texture_storage; }; + RendererTextureStorage *get_texture_storage() { return texture_storage; }; RendererStorage *get_storage() { return storage; } RendererCanvasRender *get_canvas() { return canvas; } RendererSceneRender *get_scene() { return scene; } diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp index 1a84bafbd0..75202d5abb 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp @@ -40,6 +40,7 @@ const Vector3i RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFF // SDFGI void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, RendererSceneGIRD *p_gi) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); storage = p_gi->storage; gi = p_gi; num_cascades = p_env->sdfgi_cascades; @@ -221,14 +222,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1 + u.append_id(render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1 uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { @@ -236,7 +237,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; for (int j = 0; j < 8; j++) { - u.ids.push_back(render_occlusion[j]); + u.append_id(render_occlusion[j]); } uniforms.push_back(u); } @@ -244,21 +245,21 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; - u.ids.push_back(render_emission); + u.append_id(render_emission); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; - u.ids.push_back(render_emission_aniso); + u.append_id(render_emission_aniso); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; - u.ids.push_back(render_geom_facing); + u.append_id(render_geom_facing); uniforms.push_back(u); } @@ -266,28 +267,28 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; - u.ids.push_back(cascade.sdf_tex); + u.append_id(cascade.sdf_tex); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; - u.ids.push_back(occlusion_data); + u.append_id(occlusion_data); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 10; - u.ids.push_back(cascade.solid_cell_dispatch_buffer); + u.append_id(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 11; - u.ids.push_back(cascade.solid_cell_buffer); + u.append_id(cascade.solid_cell_buffer); uniforms.push_back(u); } @@ -300,42 +301,42 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_geom_facing); + u.append_id(render_geom_facing); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(render_emission); + u.append_id(render_emission); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; - u.ids.push_back(render_emission_aniso); + u.append_id(render_emission_aniso); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 5; - u.ids.push_back(cascade.solid_cell_dispatch_buffer); + u.append_id(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 6; - u.ids.push_back(cascade.solid_cell_buffer); + u.append_id(cascade.solid_cell_buffer); uniforms.push_back(u); } @@ -348,7 +349,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; for (int j = 0; j < 8; j++) { - u.ids.push_back(render_occlusion[j]); + u.append_id(render_occlusion[j]); } uniforms.push_back(u); } @@ -356,7 +357,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(occlusion_data); + u.append_id(occlusion_data); uniforms.push_back(u); } @@ -375,9 +376,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].sdf_tex); + u.append_id(cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -386,70 +387,70 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(cascade.solid_cell_dispatch_buffer); + u.append_id(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(cascade.solid_cell_buffer); + u.append_id(cascade.solid_cell_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.ids.push_back(cascade.light_data); + u.append_id(cascade.light_data); uniforms.push_back(u); } { RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.ids.push_back(cascade.light_aniso_0_tex); + u.append_id(cascade.light_aniso_0_tex); uniforms.push_back(u); } { RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.ids.push_back(cascade.light_aniso_1_tex); + u.append_id(cascade.light_aniso_1_tex); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(cascades_ubo); + u.append_id(cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(cascade.lights_buffer); + u.append_id(cascade.lights_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(lightprobe_texture); + u.append_id(lightprobe_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(occlusion_texture); + u.append_id(occlusion_texture); uniforms.push_back(u); } @@ -463,14 +464,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf[0]); + u.append_id(render_sdf[0]); uniforms.push_back(u); } @@ -483,14 +484,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf_half[0]); + u.append_id(render_sdf_half[0]); uniforms.push_back(u); } @@ -504,19 +505,22 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_sdf[0]); + u.append_id(render_sdf[0]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf[1]); + u.append_id(render_sdf[1]); uniforms.push_back(u); } jump_flood_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); - SWAP(uniforms.write[0].ids.write[0], uniforms.write[1].ids.write[0]); + RID aux0 = uniforms.write[0].get_id(0); + RID aux1 = uniforms.write[1].get_id(0); + uniforms.write[0].set_id(0, aux1); + uniforms.write[1].set_id(0, aux0); jump_flood_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); } //jump flood half uniform set @@ -526,19 +530,22 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_sdf_half[0]); + u.append_id(render_sdf_half[0]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf_half[1]); + u.append_id(render_sdf_half[1]); uniforms.push_back(u); } jump_flood_half_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); - SWAP(uniforms.write[0].ids.write[0], uniforms.write[1].ids.write[0]); + RID aux0 = uniforms.write[0].get_id(0); + RID aux1 = uniforms.write[1].get_id(0); + uniforms.write[0].set_id(0, aux1); + uniforms.write[1].set_id(0, aux0); jump_flood_half_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); } @@ -549,21 +556,21 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size + u.append_id(render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass + u.append_id(render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass uniforms.push_back(u); } @@ -578,7 +585,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { @@ -586,7 +593,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; for (int i = 0; i < 8; i++) { - u.ids.push_back(render_occlusion[i]); + u.append_id(render_occlusion[i]); } uniforms.push_back(u); } @@ -594,7 +601,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(render_geom_facing); + u.append_id(render_geom_facing); uniforms.push_back(u); } @@ -612,9 +619,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].sdf_tex); + u.append_id(cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -625,9 +632,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].light_tex); + u.append_id(cascades[j].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -638,9 +645,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].light_aniso_0_tex); + u.append_id(cascades[j].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -651,9 +658,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].light_aniso_1_tex); + u.append_id(cascades[j].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -662,7 +669,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 6; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -670,14 +677,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 7; - u.ids.push_back(cascades_ubo); + u.append_id(cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; - u.ids.push_back(lightprobe_data); + u.append_id(lightprobe_data); uniforms.push_back(u); } @@ -685,14 +692,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(cascades[i].lightprobe_history_tex); + u.append_id(cascades[i].lightprobe_history_tex); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; - u.ids.push_back(cascades[i].lightprobe_average_tex); + u.append_id(cascades[i].lightprobe_average_tex); uniforms.push_back(u); } @@ -700,14 +707,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; - u.ids.push_back(lightprobe_history_scroll); + u.append_id(lightprobe_history_scroll); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 12; - u.ids.push_back(lightprobe_average_scroll); + u.append_id(lightprobe_average_scroll); uniforms.push_back(u); } { @@ -723,14 +730,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V } else { parent_average = cascades[i - 1].lightprobe_average_tex; //to use something, but it won't be used } - u.ids.push_back(parent_average); + u.append_id(parent_average); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 14; - u.ids.push_back(ambient_texture); + u.append_id(ambient_texture); uniforms.push_back(u); } @@ -934,7 +941,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.ids.push_back(p_sky->radiance); + u.append_id(p_sky->radiance); uniforms.push_back(u); } @@ -942,7 +949,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 1; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -1002,7 +1009,7 @@ void RendererSceneGIRD::SDFGI::store_probes() { push_constant.y_mult = y_mult; // Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces - RENDER_TIMESTAMP("Average Probes"); + RENDER_TIMESTAMP("Average SDFGI Probes"); RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE]); @@ -1102,6 +1109,8 @@ void RendererSceneGIRD::SDFGI::update_cascades() { } void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + if (!debug_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set)) { Vector<RD::Uniform> uniforms; { @@ -1110,9 +1119,9 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < cascades.size()) { - u.ids.push_back(cascades[i].sdf_tex); + u.append_id(cascades[i].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1123,9 +1132,9 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < cascades.size()) { - u.ids.push_back(cascades[i].light_tex); + u.append_id(cascades[i].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1136,9 +1145,9 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < cascades.size()) { - u.ids.push_back(cascades[i].light_aniso_0_tex); + u.append_id(cascades[i].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1149,9 +1158,9 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < cascades.size()) { - u.ids.push_back(cascades[i].light_aniso_1_tex); + u.append_id(cascades[i].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1160,35 +1169,35 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(occlusion_texture); + u.append_id(occlusion_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(cascades_ubo); + u.append_id(cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.ids.push_back(p_texture); + u.append_id(p_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(lightprobe_texture); + u.append_id(lightprobe_texture); uniforms.push_back(u); } debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0); @@ -1273,28 +1282,28 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr RD::Uniform u; u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(cascades_ubo); + u.append_id(cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(lightprobe_texture); + u.append_id(lightprobe_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(occlusion_texture); + u.append_id(occlusion_texture); uniforms.push_back(u); } @@ -1449,7 +1458,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->directional_lights->get(j)); ERR_CONTINUE(!li); - if (storage->light_directional_is_sky_only(li->light)) { + if (storage->light_directional_get_sky_mode(li->light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) { continue; } @@ -1555,14 +1564,14 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, if (cascade_next != cascade) { RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade"); - RENDER_TIMESTAMP(">SDFGI Update SDF"); + RENDER_TIMESTAMP("> SDFGI Update SDF"); //done rendering! must update SDF //clear dispatch indirect data SDFGIShader::PreprocessPushConstant push_constant; memset(&push_constant, 0, sizeof(SDFGIShader::PreprocessPushConstant)); - RENDER_TIMESTAMP("Scroll SDF"); + RENDER_TIMESTAMP("SDFGI Scroll SDF"); //scroll if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) { @@ -1701,7 +1710,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, push_constant.half_size = true; { - RENDER_TIMESTAMP("SDFGI Jump Flood (Half Size)"); + RENDER_TIMESTAMP("SDFGI Jump Flood (Half-Size)"); uint32_t s = cascade_half_size; @@ -1723,7 +1732,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, } } - RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half Size)"); + RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half-Size)"); //continue with optimized jump flood for smaller reads RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); @@ -1759,7 +1768,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, } else { //full size jumpflood - RENDER_TIMESTAMP("SDFGI Jump Flood"); + RENDER_TIMESTAMP("SDFGI Jump Flood (Full-Size)"); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_uniform_set, 0); @@ -1790,7 +1799,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, } } - RENDER_TIMESTAMP("SDFGI Jump Flood Optimized"); + RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Full-Size)"); //continue with optimized jump flood for smaller reads RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); @@ -1882,7 +1891,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, //finalize render and update sdf #endif - RENDER_TIMESTAMP("<SDFGI Update SDF"); + RENDER_TIMESTAMP("< SDFGI Update SDF"); RD::get_singleton()->draw_command_end_label(); } } @@ -1891,7 +1900,7 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32 RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... - RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lighs"); + RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lights"); update_cascades(); @@ -2073,14 +2082,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(storage->voxel_gi_get_octree_buffer(probe)); + u.append_id(storage->voxel_gi_get_octree_buffer(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(storage->voxel_gi_get_data_buffer(probe)); + u.append_id(storage->voxel_gi_get_data_buffer(probe)); uniforms.push_back(u); } @@ -2088,21 +2097,21 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 4; - u.ids.push_back(write_buffer); + u.append_id(write_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -2113,7 +2122,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 3; - u.ids.push_back(gi->voxel_gi_lights_uniform); + u.append_id(gi->voxel_gi_lights_uniform); copy_uniforms.push_back(u); } @@ -2125,7 +2134,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 5; - u.ids.push_back(texture); + u.append_id(texture); copy_uniforms.push_back(u); } mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0); @@ -2138,7 +2147,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; - u.ids.push_back(mipmap.texture); + u.append_id(mipmap.texture); uniforms.push_back(u); } @@ -2213,7 +2222,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 3; - u.ids.push_back(gi->voxel_gi_lights_uniform); + u.append_id(gi->voxel_gi_lights_uniform); uniforms.push_back(u); } @@ -2221,56 +2230,56 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; - u.ids.push_back(dmap.albedo); + u.append_id(dmap.albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; - u.ids.push_back(dmap.normal); + u.append_id(dmap.normal); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; - u.ids.push_back(dmap.orm); + u.append_id(dmap.orm); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 8; - u.ids.push_back(dmap.fb_depth); + u.append_id(dmap.fb_depth); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; - u.ids.push_back(dmap.texture); + u.append_id(dmap.texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 12; - u.ids.push_back(dmap.depth); + u.append_id(dmap.depth); uniforms.push_back(u); } @@ -2286,14 +2295,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; - u.ids.push_back(dynamic_maps[dynamic_maps.size() - 1].texture); + u.append_id(dynamic_maps[dynamic_maps.size() - 1].texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; - u.ids.push_back(dynamic_maps[dynamic_maps.size() - 1].depth); + u.append_id(dynamic_maps[dynamic_maps.size() - 1].depth); uniforms.push_back(u); } @@ -2302,14 +2311,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; - u.ids.push_back(dmap.texture); + u.append_id(dmap.texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; - u.ids.push_back(dmap.depth); + u.append_id(dmap.depth); uniforms.push_back(u); } } @@ -2318,14 +2327,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -2334,7 +2343,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; - u.ids.push_back(mipmaps[dmap.mipmap].texture); + u.append_id(mipmaps[dmap.mipmap].texture); uniforms.push_back(u); } } @@ -2379,7 +2388,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RID light = p_scene_render->light_instance_get_base_light(light_instance); l.type = storage->light_get_type(light); - if (l.type == RS::LIGHT_DIRECTIONAL && storage->light_directional_is_sky_only(light)) { + if (l.type == RS::LIGHT_DIRECTIONAL && storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) { light_count--; continue; } @@ -2447,7 +2456,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c passes = 1; //only re-blitting is necessary } int wg_size = 64; - int wg_limit_x = RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); + int64_t wg_limit_x = (int64_t)RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); for (int pass = 0; pass < passes; pass++) { if (p_update_light_instances) { @@ -2470,9 +2479,9 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c push_constant.cell_offset = mipmaps[i].cell_offset; push_constant.cell_count = mipmaps[i].cell_count; - int wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1; + int64_t wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1; while (wg_todo) { - int wg_count = MIN(wg_todo, wg_limit_x); + int64_t wg_count = MIN(wg_todo, wg_limit_x); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant)); RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1); wg_todo -= wg_count; @@ -2491,9 +2500,9 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c push_constant.cell_offset = mipmaps[i].cell_offset; push_constant.cell_count = mipmaps[i].cell_count; - int wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1; + int64_t wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1; while (wg_todo) { - int wg_count = MIN(wg_todo, wg_limit_x); + int64_t wg_count = MIN(wg_todo, wg_limit_x); RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant)); RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1); wg_todo -= wg_count; @@ -2747,21 +2756,21 @@ void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(storage->voxel_gi_get_data_buffer(probe)); + u.append_id(storage->voxel_gi_get_data_buffer(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 3; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -2801,6 +2810,8 @@ RendererSceneGIRD::~RendererSceneGIRD() { } void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + storage = p_storage; /* GI */ @@ -2918,14 +2929,14 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 1; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -3017,6 +3028,8 @@ RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironme } void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + r_voxel_gi_instances_used = 0; // feels a little dirty to use our container this way but.... @@ -3079,7 +3092,7 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra } if (texture == RID()) { - texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); } if (texture != rb->gi.voxel_gi_textures[i]) { @@ -3115,6 +3128,8 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra } void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + RD::get_singleton()->draw_command_begin_label("GI Render"); RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); @@ -3178,9 +3193,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex); + u.append_id(rb->sdfgi->cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3191,9 +3206,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.ids.push_back(rb->sdfgi->cascades[j].light_tex); + u.append_id(rb->sdfgi->cascades[j].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3204,9 +3219,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_0_tex); + u.append_id(rb->sdfgi->cascades[j].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3217,9 +3232,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_1_tex); + u.append_id(rb->sdfgi->cascades[j].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3229,9 +3244,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 5; if (rb->sdfgi) { - u.ids.push_back(rb->sdfgi->occlusion_texture); + u.append_id(rb->sdfgi->occlusion_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } uniforms.push_back(u); } @@ -3239,14 +3254,14 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 6; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 7; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -3254,7 +3269,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(rb->ambient_buffer); + u.append_id(rb->ambient_buffer); uniforms.push_back(u); } @@ -3262,7 +3277,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; - u.ids.push_back(rb->reflection_buffer); + u.append_id(rb->reflection_buffer); uniforms.push_back(u); } @@ -3271,9 +3286,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 11; if (rb->sdfgi) { - u.ids.push_back(rb->sdfgi->lightprobe_texture); + u.append_id(rb->sdfgi->lightprobe_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); } uniforms.push_back(u); } @@ -3281,36 +3296,36 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 12; - u.ids.push_back(rb->depth_texture); + u.append_id(rb->depth_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 13; - u.ids.push_back(p_normal_roughness_buffer); + u.append_id(p_normal_roughness_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 14; - RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(buffer); + RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + u.append_id(buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 15; - u.ids.push_back(sdfgi_ubo); + u.append_id(sdfgi_ubo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 16; - u.ids.push_back(rb->gi.voxel_gi_buffer); + u.append_id(rb->gi.voxel_gi_buffer); uniforms.push_back(u); } { @@ -3318,7 +3333,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 17; for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) { - u.ids.push_back(rb->gi.voxel_gi_textures[i]); + u.append_id(rb->gi.voxel_gi_textures[i]); } uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h index 25f0dca3b7..d51b1bf691 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h @@ -45,6 +45,7 @@ #include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/voxel_gi.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -250,8 +251,6 @@ private: float cos_spot_angle; float inv_spot_attenuation; float radius; - - float shadow_color[4]; }; struct DirectLightPushConstant { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 948340f469..f5258d7923 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1666,8 +1666,8 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { if (i == 1) { // next 2 are half size - tf.width = MAX(1, tf.width >> 1); - tf.height = MAX(1, tf.height >> 1); + tf.width = MAX(1u, tf.width >> 1); + tf.height = MAX(1u, tf.height >> 1); } } @@ -1980,7 +1980,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb rb->ssr.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); } - if (ssr_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED && !rb->ssr.blur_radius[0].is_valid()) { + if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED && !rb->ssr.blur_radius[0].is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8_UNORM; tf.width = rb->internal_width / 2; @@ -2490,7 +2490,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.exposure_texture = rb->luminance.current; tonemap.auto_exposure_grey = env->auto_exp_scale; } else { - tonemap.exposure_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } if (can_use_effects && env && env->glow_enabled) { @@ -2506,15 +2506,15 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.glow_texture = rb->blur[1].texture; if (env->glow_map.is_valid()) { tonemap.glow_map_strength = env->glow_map_strength; - tonemap.glow_map = storage->texture_get_rd_texture(env->glow_map); + tonemap.glow_map = texture_storage->texture_get_rd_texture(env->glow_map); } else { tonemap.glow_map_strength = 0.0f; - tonemap.glow_map = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } } else { - tonemap.glow_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - tonemap.glow_map = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } if (rb->screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) { @@ -2536,7 +2536,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.use_color_correction = false; tonemap.use_1d_color_correction = false; - tonemap.color_correction_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); if (can_use_effects && env) { tonemap.use_bcs = env->adjustments_enabled; @@ -2546,7 +2546,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende if (env->adjustments_enabled && env->color_correction.is_valid()) { tonemap.use_color_correction = true; tonemap.use_1d_color_correction = env->use_1d_color_correction; - tonemap.color_correction_texture = storage->texture_get_rd_texture(env->color_correction); + tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(env->color_correction); } } @@ -2606,14 +2606,14 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr } tonemap.use_glow = false; - tonemap.glow_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - tonemap.glow_map = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.glow_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); + tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); tonemap.use_auto_exposure = false; - tonemap.exposure_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); tonemap.use_color_correction = false; tonemap.use_1d_color_correction = false; - tonemap.color_correction_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); + tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); if (can_use_effects && env) { tonemap.use_bcs = env->adjustments_enabled; @@ -2623,7 +2623,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr if (env->adjustments_enabled && env->color_correction.is_valid()) { tonemap.use_color_correction = true; tonemap.use_1d_color_correction = env->use_1d_color_correction; - tonemap.color_correction_texture = storage->texture_get_rd_texture(env->color_correction); + tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(env->color_correction); } } @@ -2656,7 +2656,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID RID shadow_atlas_texture = shadow_atlas_get_texture(p_shadow_atlas); if (shadow_atlas_texture.is_null()) { - shadow_atlas_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); + shadow_atlas_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); } Size2 rtsize = storage->render_target_get_size(rb->render_target); @@ -2716,7 +2716,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) { if (p_occlusion_buffer.is_valid()) { Size2 rtsize = storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(storage->texture_get_rd_texture(p_occlusion_buffer), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false); + effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false); } } } @@ -3286,7 +3286,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const RS::LightType type = storage->light_get_type(base); switch (type) { case RS::LIGHT_DIRECTIONAL: { - if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_is_sky_only(base)) { + if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_get_sky_mode(base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) { continue; } @@ -3316,43 +3316,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.size = 1.0 - Math::cos(Math::deg2rad(size)); //angle to cosine offset - Color shadow_col = storage->light_get_shadow_color(base).to_linear(); - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS) { - light_data.shadow_color1[0] = 1.0; - light_data.shadow_color1[1] = 0.0; - light_data.shadow_color1[2] = 0.0; - light_data.shadow_color1[3] = 1.0; - light_data.shadow_color2[0] = 0.0; - light_data.shadow_color2[1] = 1.0; - light_data.shadow_color2[2] = 0.0; - light_data.shadow_color2[3] = 1.0; - light_data.shadow_color3[0] = 0.0; - light_data.shadow_color3[1] = 0.0; - light_data.shadow_color3[2] = 1.0; - light_data.shadow_color3[3] = 1.0; - light_data.shadow_color4[0] = 1.0; - light_data.shadow_color4[1] = 1.0; - light_data.shadow_color4[2] = 0.0; - light_data.shadow_color4[3] = 1.0; - - } else { - light_data.shadow_color1[0] = shadow_col.r; - light_data.shadow_color1[1] = shadow_col.g; - light_data.shadow_color1[2] = shadow_col.b; - light_data.shadow_color1[3] = 1.0; - light_data.shadow_color2[0] = shadow_col.r; - light_data.shadow_color2[1] = shadow_col.g; - light_data.shadow_color2[2] = shadow_col.b; - light_data.shadow_color2[3] = 1.0; - light_data.shadow_color3[0] = shadow_col.r; - light_data.shadow_color3[1] = shadow_col.g; - light_data.shadow_color3[2] = shadow_col.b; - light_data.shadow_color3[3] = 1.0; - light_data.shadow_color4[0] = shadow_col.r; - light_data.shadow_color4[1] = shadow_col.g; - light_data.shadow_color4[2] = shadow_col.b; - light_data.shadow_color4[3] = 1.0; + WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet."); } light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base); @@ -3440,8 +3405,22 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const continue; } + const real_t distance = camera_plane.distance_to(li->transform.origin); + + if (storage->light_is_distance_fade_enabled(li->light)) { + const float fade_begin = storage->light_get_distance_fade_begin(li->light); + const float fade_length = storage->light_get_distance_fade_length(li->light); + + if (distance > fade_begin) { + if (distance > fade_begin + fade_length) { + // Out of range, don't draw this light to improve performance. + continue; + } + } + } + cluster.omni_light_sort[cluster.omni_light_count].instance = li; - cluster.omni_light_sort[cluster.omni_light_count].depth = camera_plane.distance_to(li->transform.origin); + cluster.omni_light_sort[cluster.omni_light_count].depth = distance; cluster.omni_light_count++; } break; case RS::LIGHT_SPOT: { @@ -3449,8 +3428,22 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const continue; } + const real_t distance = camera_plane.distance_to(li->transform.origin); + + if (storage->light_is_distance_fade_enabled(li->light)) { + const float fade_begin = storage->light_get_distance_fade_begin(li->light); + const float fade_length = storage->light_get_distance_fade_length(li->light); + + if (distance > fade_begin) { + if (distance > fade_begin + fade_length) { + // Out of range, don't draw this light to improve performance. + continue; + } + } + } + cluster.spot_light_sort[cluster.spot_light_count].instance = li; - cluster.spot_light_sort[cluster.spot_light_count].depth = camera_plane.distance_to(li->transform.origin); + cluster.spot_light_sort[cluster.spot_light_count].depth = distance; cluster.spot_light_count++; } break; } @@ -3494,7 +3487,24 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION); - float energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI; + // Reuse fade begin, fade length and distance for shadow LOD determination later. + float fade_begin = 0.0; + float fade_length = 0.0; + real_t distance = 0.0; + + float fade = 1.0; + if (storage->light_is_distance_fade_enabled(li->light)) { + fade_begin = storage->light_get_distance_fade_begin(li->light); + fade_length = storage->light_get_distance_fade_length(li->light); + distance = camera_plane.distance_to(li->transform.origin); + + if (distance > fade_begin) { + // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player. + fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length); + } + } + + float energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade; light_data.color[0] = linear_col.r * energy; light_data.color[1] = linear_col.g * energy; @@ -3555,7 +3565,17 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.projector_rect[3] = 0; } - if (shadow_atlas && shadow_atlas->shadow_owners.has(li->self)) { + const bool needs_shadow = shadow_atlas && shadow_atlas->shadow_owners.has(li->self); + + bool in_shadow_range = true; + if (needs_shadow && storage->light_is_distance_fade_enabled(li->light)) { + if (distance > storage->light_get_distance_fade_shadow(li->light)) { + // Out of range, don't draw shadows to improve performance. + in_shadow_range = false; + } + } + + if (needs_shadow && in_shadow_range) { // fill in the shadow information light_data.shadow_enabled = true; @@ -4064,7 +4084,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e return; } - RENDER_TIMESTAMP(">Volumetric Fog"); + RENDER_TIMESTAMP("> Volumetric Fog"); RD::get_singleton()->draw_command_begin_label("Volumetric Fog"); if (env && env->volumetric_fog_enabled && !rb->volumetric_fog) { @@ -4126,7 +4146,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(rb->volumetric_fog->fog_map); + u.append_id(rb->volumetric_fog->fog_map); uniforms.push_back(u); } @@ -4136,7 +4156,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e if (p_fog_volumes.size() > 0) { RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes"); - RENDER_TIMESTAMP("Render Fog Volumes"); + RENDER_TIMESTAMP("Render FogVolumes"); VolumetricFogShader::VolumeUBO params; @@ -4191,7 +4211,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 1; - u.ids.push_back(rb->volumetric_fog->emissive_map); + u.append_id(rb->volumetric_fog->emissive_map); uniforms.push_back(u); } @@ -4199,7 +4219,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; - u.ids.push_back(volumetric_fog.volume_ubo); + u.append_id(volumetric_fog.volume_ubo); uniforms.push_back(u); } @@ -4211,7 +4231,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 3; - u.ids.push_back(rb->volumetric_fog->density_map); + u.append_id(rb->volumetric_fog->density_map); uniforms.push_back(u); } @@ -4223,7 +4243,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 4; - u.ids.push_back(rb->volumetric_fog->light_map); + u.append_id(rb->volumetric_fog->light_map); uniforms.push_back(u); } @@ -4344,9 +4364,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.binding = 1; ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); } else { - u.ids.push_back(shadow_atlas->depth); + u.append_id(shadow_atlas->depth); } uniforms.push_back(u); @@ -4358,9 +4378,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; if (directional_shadow.depth.is_valid()) { - u.ids.push_back(directional_shadow.depth); + u.append_id(directional_shadow.depth); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); } uniforms.push_back(u); copy_uniforms.push_back(u); @@ -4370,7 +4390,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; - u.ids.push_back(get_omni_light_buffer()); + u.append_id(get_omni_light_buffer()); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4378,7 +4398,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 4; - u.ids.push_back(get_spot_light_buffer()); + u.append_id(get_spot_light_buffer()); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4387,7 +4407,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 5; - u.ids.push_back(get_directional_light_buffer()); + u.append_id(get_directional_light_buffer()); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4396,7 +4416,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 6; - u.ids.push_back(rb->cluster_builder->get_cluster_buffer()); + u.append_id(rb->cluster_builder->get_cluster_buffer()); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4405,7 +4425,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 7; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4414,7 +4434,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; - u.ids.push_back(rb->volumetric_fog->light_density_map); + u.append_id(rb->volumetric_fog->light_density_map); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4423,7 +4443,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(rb->volumetric_fog->fog_map); + u.append_id(rb->volumetric_fog->fog_map); uniforms.push_back(u); } @@ -4431,7 +4451,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(rb->volumetric_fog->prev_light_density_map); + u.append_id(rb->volumetric_fog->prev_light_density_map); copy_uniforms.push_back(u); } @@ -4439,7 +4459,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; - u.ids.push_back(shadow_sampler); + u.append_id(shadow_sampler); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4448,7 +4468,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 11; - u.ids.push_back(render_buffers_get_voxel_gi_buffer(p_render_buffers)); + u.append_id(render_buffers_get_voxel_gi_buffer(p_render_buffers)); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4458,7 +4478,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 12; for (int i = 0; i < RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES; i++) { - u.ids.push_back(rb->gi.voxel_gi_textures[i]); + u.append_id(rb->gi.voxel_gi_textures[i]); } uniforms.push_back(u); copy_uniforms.push_back(u); @@ -4467,7 +4487,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 13; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4475,7 +4495,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 14; - u.ids.push_back(volumetric_fog.params_ubo); + u.append_id(volumetric_fog.params_ubo); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4483,7 +4503,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 15; - u.ids.push_back(rb->volumetric_fog->prev_light_density_map); + u.append_id(rb->volumetric_fog->prev_light_density_map); uniforms.push_back(u); } { @@ -4494,7 +4514,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 16; - u.ids.push_back(rb->volumetric_fog->density_map); + u.append_id(rb->volumetric_fog->density_map); uniforms.push_back(u); } { @@ -4505,7 +4525,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 17; - u.ids.push_back(rb->volumetric_fog->light_map); + u.append_id(rb->volumetric_fog->light_map); uniforms.push_back(u); } @@ -4517,7 +4537,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 18; - u.ids.push_back(rb->volumetric_fog->emissive_map); + u.append_id(rb->volumetric_fog->emissive_map); uniforms.push_back(u); } @@ -4525,9 +4545,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 19; - RID radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + RID radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); RID sky_texture = env->sky.is_valid() ? sky.sky_get_radiance_texture_rd(env->sky) : RID(); - u.ids.push_back(sky_texture.is_valid() ? sky_texture : radiance_texture); + u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture); uniforms.push_back(u); } @@ -4535,7 +4555,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); - SWAP(uniforms.write[7].ids.write[0], uniforms.write[8].ids.write[0]); + RID aux7 = uniforms.write[7].get_id(0); + RID aux8 = uniforms.write[8].get_id(0); + + uniforms.write[7].set_id(0, aux8); + uniforms.write[8].set_id(0, aux7); rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, 0), 0); } @@ -4550,7 +4574,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; - u.ids.push_back(gi.sdfgi_ubo); + u.append_id(gi.sdfgi_ubo); uniforms.push_back(u); } @@ -4558,7 +4582,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - u.ids.push_back(rb->sdfgi->ambient_texture); + u.append_id(rb->sdfgi->ambient_texture); uniforms.push_back(u); } @@ -4566,7 +4590,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.ids.push_back(rb->sdfgi->occlusion_texture); + u.append_id(rb->sdfgi->occlusion_texture); uniforms.push_back(u); } @@ -4730,7 +4754,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER); - RENDER_TIMESTAMP("<Volumetric Fog"); + RENDER_TIMESTAMP("< Volumetric Fog"); RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_command_end_label(); @@ -4819,7 +4843,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool bool render_gi = p_render_data->render_buffers.is_valid() && p_use_gi; if (render_shadows && render_gi) { - RENDER_TIMESTAMP("Render GI + Render Shadows (parallel)"); + RENDER_TIMESTAMP("Render GI + Render Shadows (Parallel)"); } else if (render_shadows) { RENDER_TIMESTAMP("Render Shadows"); } else if (render_gi) { @@ -5576,6 +5600,7 @@ uint32_t RendererSceneRenderRD::get_max_elements() const { } RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { + texture_storage = RendererRD::TextureStorage::get_singleton(); storage = p_storage; singleton = this; } @@ -5699,11 +5724,9 @@ void fog() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 1; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -5716,6 +5739,8 @@ void fog() { ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); uniforms.push_back(u); } @@ -5723,7 +5748,7 @@ void fog() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 09c828ba37..e302db2631 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -41,6 +41,7 @@ #include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -92,6 +93,7 @@ class RendererSceneRenderRD : public RendererSceneRender { friend RendererSceneGIRD; protected: + RendererRD::TextureStorage *texture_storage; RendererStorageRD *storage; double time; double time_step = 0; @@ -428,7 +430,7 @@ private: bool glow_bicubic_upscale = false; bool glow_high_quality = false; - RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGNESS_QUALITY_LOW; + RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW; mutable RID_Owner<RendererSceneEnvironmentRD, true> environment_owner; @@ -678,10 +680,6 @@ private: float shadow_range_begin[4]; float shadow_split_offsets[4]; float shadow_matrices[4][16]; - float shadow_color1[4]; - float shadow_color2[4]; - float shadow_color3[4]; - float shadow_color4[4]; float uv_scale1[2]; float uv_scale2[2]; float uv_scale3[2]; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index b44ae6cf8d..44da9e40f8 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -33,6 +33,7 @@ #include "core/math/math_defs.h" #include "renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_server_default.h" //////////////////////////////////////////////////////////////////////////////// @@ -362,8 +363,8 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6, j, 1, RD::TEXTURE_SLICE_CUBEMAP); - mmw = MAX(1, mmw >> 1); - mmh = MAX(1, mmh >> 1); + mmw = MAX(1u, mmw >> 1); + mmh = MAX(1u, mmh >> 1); } layers.push_back(layer); @@ -390,8 +391,8 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, j, 1, RD::TEXTURE_SLICE_CUBEMAP); - mmw = MAX(1, mmw >> 1); - mmh = MAX(1, mmh >> 1); + mmw = MAX(1u, mmw >> 1); + mmh = MAX(1u, mmh >> 1); } layers.push_back(layer); @@ -432,8 +433,8 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR } } - mmw = MAX(1, mmw >> 1); - mmh = MAX(1, mmh >> 1); + mmw = MAX(1u, mmw >> 1); + mmh = MAX(1u, mmh >> 1); } } } @@ -621,6 +622,8 @@ void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) { } RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) { return texture_uniform_sets[p_version]; } @@ -630,9 +633,9 @@ RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextu u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; if (radiance.is_valid() && p_version <= SKY_TEXTURE_SET_QUARTER_RES) { - u.ids.push_back(radiance); + u.append_id(radiance); } else { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } uniforms.push_back(u); } @@ -642,15 +645,15 @@ RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextu u.binding = 1; // half res if (half_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) { if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(reflection.layers[0].views[1]); + u.append_id(reflection.layers[0].views[1]); } else { - u.ids.push_back(half_res_pass); + u.append_id(half_res_pass); } } else { if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); } else { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } uniforms.push_back(u); @@ -661,15 +664,15 @@ RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextu u.binding = 2; // quarter res if (quarter_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) { if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(reflection.layers[0].views[2]); + u.append_id(reflection.layers[0].views[2]); } else { - u.ids.push_back(quarter_res_pass); + u.append_id(quarter_res_pass); } } else { if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); } else { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } uniforms.push_back(u); @@ -793,6 +796,7 @@ RendererSceneSkyRD::RendererSceneSkyRD() { } void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); storage = p_storage; { @@ -918,11 +922,9 @@ void sky() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 0; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -935,6 +937,9 @@ void sky() { ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 0, ids); + uniforms.push_back(u); } @@ -942,7 +947,7 @@ void sky() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -950,7 +955,7 @@ void sky() { RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(sky_scene_state.uniform_buffer); + u.append_id(sky_scene_state.uniform_buffer); uniforms.push_back(u); } @@ -958,7 +963,7 @@ void sky() { RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(sky_scene_state.directional_light_buffer); + u.append_id(sky_scene_state.directional_light_buffer); uniforms.push_back(u); } @@ -971,8 +976,8 @@ void sky() { RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - RID vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); - u.ids.push_back(vfog); + RID vfog = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); + u.append_id(vfog); uniforms.push_back(u); } @@ -1005,21 +1010,21 @@ void sky() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } @@ -1162,14 +1167,14 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b ERR_CONTINUE(base.is_null()); RS::LightType type = storage->light_get_type(base); - if (type == RS::LIGHT_DIRECTIONAL) { + if (type == RS::LIGHT_DIRECTIONAL && storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) { SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count]; Transform3D light_transform = li->transform; Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); sky_light_data.direction[0] = world_direction.x; sky_light_data.direction[1] = world_direction.y; - sky_light_data.direction[2] = -world_direction.z; + sky_light_data.direction[2] = world_direction.z; float sign = storage->light_is_negative(base) ? -1 : 1; sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index e3829eb5ed..9076fc5bb8 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -35,1114 +35,13 @@ #include "core/io/resource_loader.h" #include "core/math/math_defs.h" #include "renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_server_globals.h" #include "servers/rendering/shader_language.h" -bool RendererStorageRD::can_create_resources_async() const { - return true; -} - -Ref<Image> RendererStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { - Ref<Image> image = p_image->duplicate(); - - switch (p_image->get_format()) { - case Image::FORMAT_L8: { - r_format.format = RD::DATA_FORMAT_R8_UNORM; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; //luminance - case Image::FORMAT_LA8: { - r_format.format = RD::DATA_FORMAT_R8G8_UNORM; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_G; - } break; //luminance-alpha - case Image::FORMAT_R8: { - r_format.format = RD::DATA_FORMAT_R8_UNORM; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - case Image::FORMAT_RG8: { - r_format.format = RD::DATA_FORMAT_R8G8_UNORM; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - case Image::FORMAT_RGB8: { - //this format is not mandatory for specification, check if supported first - if (false && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT) && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_SRGB, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_R8G8B8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8_SRGB; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - - } break; - case Image::FORMAT_RGBA8: { - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - } break; - case Image::FORMAT_RGBA4444: { - r_format.format = RD::DATA_FORMAT_B4G4R4A4_UNORM_PACK16; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_B; //needs swizzle - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - } break; - case Image::FORMAT_RGB565: { - r_format.format = RD::DATA_FORMAT_B5G6R5_UNORM_PACK16; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - } break; - case Image::FORMAT_RF: { - r_format.format = RD::DATA_FORMAT_R32_SFLOAT; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; //float - case Image::FORMAT_RGF: { - r_format.format = RD::DATA_FORMAT_R32G32_SFLOAT; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - case Image::FORMAT_RGBF: { - //this format is not mandatory for specification, check if supported first - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R32G32B32_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - image->convert(Image::FORMAT_RGBAF); - } - - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - case Image::FORMAT_RGBAF: { - r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - - } break; - case Image::FORMAT_RH: { - r_format.format = RD::DATA_FORMAT_R16_SFLOAT; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - - } break; //half float - case Image::FORMAT_RGH: { - r_format.format = RD::DATA_FORMAT_R16G16_SFLOAT; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - - } break; - case Image::FORMAT_RGBH: { - //this format is not mandatory for specification, check if supported first - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16B16_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_R16G16B16_SFLOAT; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->convert(Image::FORMAT_RGBAH); - } - - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - case Image::FORMAT_RGBAH: { - r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - - } break; - case Image::FORMAT_RGBE9995: { - r_format.format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32; -#ifndef _MSC_VER -#warning TODO need to make a function in Image to swap bits for this -#endif - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_IDENTITY; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_IDENTITY; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_IDENTITY; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_IDENTITY; - } break; - case Image::FORMAT_DXT1: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_BC1_RGB_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - - } break; //s3tc bc1 - case Image::FORMAT_DXT3: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC2_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC2_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_BC2_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - - } break; //bc2 - case Image::FORMAT_DXT5: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC3_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC3_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_BC3_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - } break; //bc3 - case Image::FORMAT_RGTC_R: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC4_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC4_UNORM_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8_UNORM; - image->decompress(); - image->convert(Image::FORMAT_R8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - - } break; - case Image::FORMAT_RGTC_RG: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC5_UNORM_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8_UNORM; - image->decompress(); - image->convert(Image::FORMAT_RG8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - - } break; - case Image::FORMAT_BPTC_RGBA: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC7_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_BC7_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - - } break; //btpc bc7 - case Image::FORMAT_BPTC_RGBF: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->decompress(); - image->convert(Image::FORMAT_RGBAH); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; //float bc6h - case Image::FORMAT_BPTC_RGBFU: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - image->decompress(); - image->convert(Image::FORMAT_RGBAH); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; //unsigned float bc6hu - case Image::FORMAT_ETC2_R11: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8_UNORM; - image->decompress(); - image->convert(Image::FORMAT_R8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - - } break; //etc2 - case Image::FORMAT_ETC2_R11S: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8_SNORM; - image->decompress(); - image->convert(Image::FORMAT_R8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; //signed: {} break; NOT srgb. - case Image::FORMAT_ETC2_RG11: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8_UNORM; - image->decompress(); - image->convert(Image::FORMAT_RG8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - case Image::FORMAT_ETC2_RG11S: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8_SNORM; - image->decompress(); - image->convert(Image::FORMAT_RG8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - case Image::FORMAT_ETC: - case Image::FORMAT_ETC2_RGB8: { - //ETC2 is backwards compatible with ETC1, and all modern platforms support it - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - - } break; - case Image::FORMAT_ETC2_RGBA8: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - } break; - case Image::FORMAT_ETC2_RGB8A1: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; - } break; - case Image::FORMAT_ETC2_RA_AS_RG: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - case Image::FORMAT_DXT5_RA_AS_RG: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC3_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { - r_format.format = RD::DATA_FORMAT_BC3_UNORM_BLOCK; - r_format.format_srgb = RD::DATA_FORMAT_BC3_SRGB_BLOCK; - } else { - //not supported, reconvert - r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; - image->decompress(); - image->convert(Image::FORMAT_RGBA8); - } - r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; - r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A; - r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; - r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; - } break; - - default: { - } - } - - return image; -} - -RID RendererStorageRD::texture_allocate() { - return texture_owner.allocate_rid(); -} - -void RendererStorageRD::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) { - ERR_FAIL_COND(p_image.is_null()); - ERR_FAIL_COND(p_image->is_empty()); - - TextureToRDFormat ret_format; - Ref<Image> image = _validate_texture_format(p_image, ret_format); - - Texture texture; - - texture.type = Texture::TYPE_2D; - - texture.width = p_image->get_width(); - texture.height = p_image->get_height(); - texture.layers = 1; - texture.mipmaps = p_image->get_mipmap_count() + 1; - texture.depth = 1; - texture.format = p_image->get_format(); - texture.validated_format = image->get_format(); - - texture.rd_type = RD::TEXTURE_TYPE_2D; - texture.rd_format = ret_format.format; - texture.rd_format_srgb = ret_format.format_srgb; - - RD::TextureFormat rd_format; - RD::TextureView rd_view; - { //attempt register - rd_format.format = texture.rd_format; - rd_format.width = texture.width; - rd_format.height = texture.height; - rd_format.depth = 1; - rd_format.array_layers = 1; - rd_format.mipmaps = texture.mipmaps; - rd_format.texture_type = texture.rd_type; - rd_format.samples = RD::TEXTURE_SAMPLES_1; - rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { - rd_format.shareable_formats.push_back(texture.rd_format); - rd_format.shareable_formats.push_back(texture.rd_format_srgb); - } - } - { - rd_view.swizzle_r = ret_format.swizzle_r; - rd_view.swizzle_g = ret_format.swizzle_g; - rd_view.swizzle_b = ret_format.swizzle_b; - rd_view.swizzle_a = ret_format.swizzle_a; - } - Vector<uint8_t> data = image->get_data(); //use image data - Vector<Vector<uint8_t>> data_slices; - data_slices.push_back(data); - texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND(texture.rd_texture.is_null()); - if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { - rd_view.format_override = texture.rd_format_srgb; - texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); - if (texture.rd_texture_srgb.is_null()) { - RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); - } - } - - //used for 2D, overridable - texture.width_2d = texture.width; - texture.height_2d = texture.height; - texture.is_render_target = false; - texture.rd_view = rd_view; - texture.is_proxy = false; - - texture_owner.initialize_rid(p_texture, texture); -} - -void RendererStorageRD::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { - ERR_FAIL_COND(p_layers.size() == 0); - - ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6); - ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0)); - - TextureToRDFormat ret_format; - Vector<Ref<Image>> images; - { - int valid_width = 0; - int valid_height = 0; - bool valid_mipmaps = false; - Image::Format valid_format = Image::FORMAT_MAX; - - for (int i = 0; i < p_layers.size(); i++) { - ERR_FAIL_COND(p_layers[i]->is_empty()); - - if (i == 0) { - valid_width = p_layers[i]->get_width(); - valid_height = p_layers[i]->get_height(); - valid_format = p_layers[i]->get_format(); - valid_mipmaps = p_layers[i]->has_mipmaps(); - } else { - ERR_FAIL_COND(p_layers[i]->get_width() != valid_width); - ERR_FAIL_COND(p_layers[i]->get_height() != valid_height); - ERR_FAIL_COND(p_layers[i]->get_format() != valid_format); - ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps); - } - - images.push_back(_validate_texture_format(p_layers[i], ret_format)); - } - } - - Texture texture; - - texture.type = Texture::TYPE_LAYERED; - texture.layered_type = p_layered_type; - - texture.width = p_layers[0]->get_width(); - texture.height = p_layers[0]->get_height(); - texture.layers = p_layers.size(); - texture.mipmaps = p_layers[0]->get_mipmap_count() + 1; - texture.depth = 1; - texture.format = p_layers[0]->get_format(); - texture.validated_format = images[0]->get_format(); - - switch (p_layered_type) { - case RS::TEXTURE_LAYERED_2D_ARRAY: { - texture.rd_type = RD::TEXTURE_TYPE_2D_ARRAY; - } break; - case RS::TEXTURE_LAYERED_CUBEMAP: { - texture.rd_type = RD::TEXTURE_TYPE_CUBE; - } break; - case RS::TEXTURE_LAYERED_CUBEMAP_ARRAY: { - texture.rd_type = RD::TEXTURE_TYPE_CUBE_ARRAY; - } break; - } - - texture.rd_format = ret_format.format; - texture.rd_format_srgb = ret_format.format_srgb; - - RD::TextureFormat rd_format; - RD::TextureView rd_view; - { //attempt register - rd_format.format = texture.rd_format; - rd_format.width = texture.width; - rd_format.height = texture.height; - rd_format.depth = 1; - rd_format.array_layers = texture.layers; - rd_format.mipmaps = texture.mipmaps; - rd_format.texture_type = texture.rd_type; - rd_format.samples = RD::TEXTURE_SAMPLES_1; - rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { - rd_format.shareable_formats.push_back(texture.rd_format); - rd_format.shareable_formats.push_back(texture.rd_format_srgb); - } - } - { - rd_view.swizzle_r = ret_format.swizzle_r; - rd_view.swizzle_g = ret_format.swizzle_g; - rd_view.swizzle_b = ret_format.swizzle_b; - rd_view.swizzle_a = ret_format.swizzle_a; - } - Vector<Vector<uint8_t>> data_slices; - for (int i = 0; i < images.size(); i++) { - Vector<uint8_t> data = images[i]->get_data(); //use image data - data_slices.push_back(data); - } - texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND(texture.rd_texture.is_null()); - if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { - rd_view.format_override = texture.rd_format_srgb; - texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); - if (texture.rd_texture_srgb.is_null()) { - RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); - } - } - - //used for 2D, overridable - texture.width_2d = texture.width; - texture.height_2d = texture.height; - texture.is_render_target = false; - texture.rd_view = rd_view; - texture.is_proxy = false; - - texture_owner.initialize_rid(p_texture, texture); -} - -void RendererStorageRD::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { - ERR_FAIL_COND(p_data.size() == 0); - Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); - if (verr != Image::VALIDATE_3D_OK) { - ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr)); - } - - TextureToRDFormat ret_format; - Image::Format validated_format = Image::FORMAT_MAX; - Vector<uint8_t> all_data; - uint32_t mipmap_count = 0; - Vector<Texture::BufferSlice3D> slices; - { - Vector<Ref<Image>> images; - uint32_t all_data_size = 0; - images.resize(p_data.size()); - for (int i = 0; i < p_data.size(); i++) { - TextureToRDFormat f; - images.write[i] = _validate_texture_format(p_data[i], f); - if (i == 0) { - ret_format = f; - validated_format = images[0]->get_format(); - } - - all_data_size += images[i]->get_data().size(); - } - - all_data.resize(all_data_size); //consolidate all data here - uint32_t offset = 0; - Size2i prev_size; - for (int i = 0; i < p_data.size(); i++) { - uint32_t s = images[i]->get_data().size(); - - memcpy(&all_data.write[offset], images[i]->get_data().ptr(), s); - { - Texture::BufferSlice3D slice; - slice.size.width = images[i]->get_width(); - slice.size.height = images[i]->get_height(); - slice.offset = offset; - slice.buffer_size = s; - slices.push_back(slice); - } - offset += s; - - Size2i img_size(images[i]->get_width(), images[i]->get_height()); - if (img_size != prev_size) { - mipmap_count++; - } - prev_size = img_size; - } - } - - Texture texture; - - texture.type = Texture::TYPE_3D; - texture.width = p_width; - texture.height = p_height; - texture.depth = p_depth; - texture.mipmaps = mipmap_count; - texture.format = p_data[0]->get_format(); - texture.validated_format = validated_format; - - texture.buffer_size_3d = all_data.size(); - texture.buffer_slices_3d = slices; - - texture.rd_type = RD::TEXTURE_TYPE_3D; - texture.rd_format = ret_format.format; - texture.rd_format_srgb = ret_format.format_srgb; - - RD::TextureFormat rd_format; - RD::TextureView rd_view; - { //attempt register - rd_format.format = texture.rd_format; - rd_format.width = texture.width; - rd_format.height = texture.height; - rd_format.depth = texture.depth; - rd_format.array_layers = 1; - rd_format.mipmaps = texture.mipmaps; - rd_format.texture_type = texture.rd_type; - rd_format.samples = RD::TEXTURE_SAMPLES_1; - rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; - if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { - rd_format.shareable_formats.push_back(texture.rd_format); - rd_format.shareable_formats.push_back(texture.rd_format_srgb); - } - } - { - rd_view.swizzle_r = ret_format.swizzle_r; - rd_view.swizzle_g = ret_format.swizzle_g; - rd_view.swizzle_b = ret_format.swizzle_b; - rd_view.swizzle_a = ret_format.swizzle_a; - } - Vector<Vector<uint8_t>> data_slices; - data_slices.push_back(all_data); //one slice - - texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); - ERR_FAIL_COND(texture.rd_texture.is_null()); - if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { - rd_view.format_override = texture.rd_format_srgb; - texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); - if (texture.rd_texture_srgb.is_null()) { - RD::get_singleton()->free(texture.rd_texture); - ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); - } - } - - //used for 2D, overridable - texture.width_2d = texture.width; - texture.height_2d = texture.height; - texture.is_render_target = false; - texture.rd_view = rd_view; - texture.is_proxy = false; - - texture_owner.initialize_rid(p_texture, texture); -} - -void RendererStorageRD::texture_proxy_initialize(RID p_texture, RID p_base) { - Texture *tex = texture_owner.get_or_null(p_base); - ERR_FAIL_COND(!tex); - Texture proxy_tex = *tex; - - proxy_tex.rd_view.format_override = tex->rd_format; - proxy_tex.rd_texture = RD::get_singleton()->texture_create_shared(proxy_tex.rd_view, tex->rd_texture); - if (proxy_tex.rd_texture_srgb.is_valid()) { - proxy_tex.rd_view.format_override = tex->rd_format_srgb; - proxy_tex.rd_texture_srgb = RD::get_singleton()->texture_create_shared(proxy_tex.rd_view, tex->rd_texture); - } - proxy_tex.proxy_to = p_base; - proxy_tex.is_render_target = false; - proxy_tex.is_proxy = true; - proxy_tex.proxies.clear(); - - texture_owner.initialize_rid(p_texture, proxy_tex); - - tex->proxies.push_back(p_texture); -} - -void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { - ERR_FAIL_COND(p_image.is_null() || p_image->is_empty()); - - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - ERR_FAIL_COND(tex->is_render_target); - ERR_FAIL_COND(p_image->get_width() != tex->width || p_image->get_height() != tex->height); - ERR_FAIL_COND(p_image->get_format() != tex->format); - - if (tex->type == Texture::TYPE_LAYERED) { - ERR_FAIL_INDEX(p_layer, tex->layers); - } - -#ifdef TOOLS_ENABLED - tex->image_cache_2d.unref(); -#endif - TextureToRDFormat f; - Ref<Image> validated = _validate_texture_format(p_image, f); - - RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data()); -} - -void RendererStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) { - _texture_2d_update(p_texture, p_image, p_layer, false); -} - -void RendererStorageRD::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - ERR_FAIL_COND(tex->type != Texture::TYPE_3D); - Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data); - if (verr != Image::VALIDATE_3D_OK) { - ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr)); - } - - Vector<uint8_t> all_data; - { - Vector<Ref<Image>> images; - uint32_t all_data_size = 0; - images.resize(p_data.size()); - for (int i = 0; i < p_data.size(); i++) { - Ref<Image> image = p_data[i]; - if (image->get_format() != tex->validated_format) { - image = image->duplicate(); - image->convert(tex->validated_format); - } - all_data_size += images[i]->get_data().size(); - images.push_back(image); - } - - all_data.resize(all_data_size); //consolidate all data here - uint32_t offset = 0; - - for (int i = 0; i < p_data.size(); i++) { - uint32_t s = images[i]->get_data().size(); - memcpy(&all_data.write[offset], images[i]->get_data().ptr(), s); - offset += s; - } - } - - RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data); -} - -void RendererStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - ERR_FAIL_COND(!tex->is_proxy); - Texture *proxy_to = texture_owner.get_or_null(p_proxy_to); - ERR_FAIL_COND(!proxy_to); - ERR_FAIL_COND(proxy_to->is_proxy); - - if (tex->proxy_to.is_valid()) { - //unlink proxy - if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) { - RD::get_singleton()->free(tex->rd_texture); - tex->rd_texture = RID(); - } - if (RD::get_singleton()->texture_is_valid(tex->rd_texture_srgb)) { - RD::get_singleton()->free(tex->rd_texture_srgb); - tex->rd_texture_srgb = RID(); - } - Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to); - ERR_FAIL_COND(!prev_tex); - prev_tex->proxies.erase(p_texture); - } - - *tex = *proxy_to; - - tex->proxy_to = p_proxy_to; - tex->is_render_target = false; - tex->is_proxy = true; - tex->proxies.clear(); - proxy_to->proxies.push_back(p_texture); - - tex->rd_view.format_override = tex->rd_format; - tex->rd_texture = RD::get_singleton()->texture_create_shared(tex->rd_view, proxy_to->rd_texture); - if (tex->rd_texture_srgb.is_valid()) { - tex->rd_view.format_override = tex->rd_format_srgb; - tex->rd_texture_srgb = RD::get_singleton()->texture_create_shared(tex->rd_view, proxy_to->rd_texture); - } -} - -//these two APIs can be used together or in combination with the others. -void RendererStorageRD::texture_2d_placeholder_initialize(RID p_texture) { - //this could be better optimized to reuse an existing image , done this way - //for now to get it working - Ref<Image> image; - image.instantiate(); - image->create(4, 4, false, Image::FORMAT_RGBA8); - image->fill(Color(1, 0, 1, 1)); - - texture_2d_initialize(p_texture, image); -} - -void RendererStorageRD::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) { - //this could be better optimized to reuse an existing image , done this way - //for now to get it working - Ref<Image> image; - image.instantiate(); - image->create(4, 4, false, Image::FORMAT_RGBA8); - image->fill(Color(1, 0, 1, 1)); - - Vector<Ref<Image>> images; - if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) { - images.push_back(image); - } else { - //cube - for (int i = 0; i < 6; i++) { - images.push_back(image); - } - } - - texture_2d_layered_initialize(p_texture, images, p_layered_type); -} - -void RendererStorageRD::texture_3d_placeholder_initialize(RID p_texture) { - //this could be better optimized to reuse an existing image , done this way - //for now to get it working - Ref<Image> image; - image.instantiate(); - image->create(4, 4, false, Image::FORMAT_RGBA8); - image->fill(Color(1, 0, 1, 1)); - - Vector<Ref<Image>> images; - //cube - for (int i = 0; i < 4; i++) { - images.push_back(image); - } - - texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, images); -} - -Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND_V(!tex, Ref<Image>()); - -#ifdef TOOLS_ENABLED - if (tex->image_cache_2d.is_valid() && !tex->is_render_target) { - return tex->image_cache_2d; - } -#endif - Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0); - ERR_FAIL_COND_V(data.size() == 0, Ref<Image>()); - Ref<Image> image; - image.instantiate(); - image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); - ERR_FAIL_COND_V(image->is_empty(), Ref<Image>()); - if (tex->format != tex->validated_format) { - image->convert(tex->format); - } - -#ifdef TOOLS_ENABLED - if (Engine::get_singleton()->is_editor_hint() && !tex->is_render_target) { - tex->image_cache_2d = image; - } -#endif - - return image; -} - -Ref<Image> RendererStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND_V(!tex, Ref<Image>()); - - Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, p_layer); - ERR_FAIL_COND_V(data.size() == 0, Ref<Image>()); - Ref<Image> image; - image.instantiate(); - image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); - ERR_FAIL_COND_V(image->is_empty(), Ref<Image>()); - if (tex->format != tex->validated_format) { - image->convert(tex->format); - } - - return image; -} - -Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>()); - ERR_FAIL_COND_V(tex->type != Texture::TYPE_3D, Vector<Ref<Image>>()); - - Vector<uint8_t> all_data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0); - - ERR_FAIL_COND_V(all_data.size() != (int)tex->buffer_size_3d, Vector<Ref<Image>>()); - - Vector<Ref<Image>> ret; - - for (int i = 0; i < tex->buffer_slices_3d.size(); i++) { - const Texture::BufferSlice3D &bs = tex->buffer_slices_3d[i]; - ERR_FAIL_COND_V(bs.offset >= (uint32_t)all_data.size(), Vector<Ref<Image>>()); - ERR_FAIL_COND_V(bs.offset + bs.buffer_size > (uint32_t)all_data.size(), Vector<Ref<Image>>()); - Vector<uint8_t> sub_region = all_data.slice(bs.offset, bs.offset + bs.buffer_size); - - Ref<Image> img; - img.instantiate(); - img->create(bs.size.width, bs.size.height, false, tex->validated_format, sub_region); - ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>()); - if (tex->format != tex->validated_format) { - img->convert(tex->format); - } - - ret.push_back(img); - } - - return ret; -} - -void RendererStorageRD::texture_replace(RID p_texture, RID p_by_texture) { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - ERR_FAIL_COND(tex->proxy_to.is_valid()); //can't replace proxy - Texture *by_tex = texture_owner.get_or_null(p_by_texture); - ERR_FAIL_COND(!by_tex); - ERR_FAIL_COND(by_tex->proxy_to.is_valid()); //can't replace proxy - - if (tex == by_tex) { - return; - } - - if (tex->rd_texture_srgb.is_valid()) { - RD::get_singleton()->free(tex->rd_texture_srgb); - } - RD::get_singleton()->free(tex->rd_texture); - - if (tex->canvas_texture) { - memdelete(tex->canvas_texture); - tex->canvas_texture = nullptr; - } - - Vector<RID> proxies_to_update = tex->proxies; - Vector<RID> proxies_to_redirect = by_tex->proxies; - - *tex = *by_tex; - - tex->proxies = proxies_to_update; //restore proxies, so they can be updated - - if (tex->canvas_texture) { - tex->canvas_texture->diffuse = p_texture; //update - } - - for (int i = 0; i < proxies_to_update.size(); i++) { - texture_proxy_update(proxies_to_update[i], p_texture); - } - for (int i = 0; i < proxies_to_redirect.size(); i++) { - texture_proxy_update(proxies_to_redirect[i], p_texture); - } - //delete last, so proxies can be updated - texture_owner.free(p_by_texture); - - if (decal_atlas.textures.has(p_texture)) { - //belongs to decal atlas.. - - decal_atlas.dirty = true; //mark it dirty since it was most likely modified - } -} - -void RendererStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - ERR_FAIL_COND(tex->type != Texture::TYPE_2D); - tex->width_2d = p_width; - tex->height_2d = p_height; -} - -void RendererStorageRD::texture_set_path(RID p_texture, const String &p_path) { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - tex->path = p_path; -} - -String RendererStorageRD::texture_get_path(RID p_texture) const { - return String(); -} - -void RendererStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - tex->detect_3d_callback_ud = p_userdata; - tex->detect_3d_callback = p_callback; -} - -void RendererStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - tex->detect_normal_callback_ud = p_userdata; - tex->detect_normal_callback = p_callback; -} - -void RendererStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) { - Texture *tex = texture_owner.get_or_null(p_texture); - ERR_FAIL_COND(!tex); - tex->detect_roughness_callback_ud = p_userdata; - tex->detect_roughness_callback = p_callback; -} - -void RendererStorageRD::texture_debug_usage(List<RS::TextureInfo> *r_info) { -} - -void RendererStorageRD::texture_set_proxy(RID p_proxy, RID p_base) { -} - -void RendererStorageRD::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { -} - -Size2 RendererStorageRD::texture_size_with_proxy(RID p_proxy) { - return texture_2d_get_size(p_proxy); -} - /* CANVAS TEXTURE */ -void RendererStorageRD::CanvasTexture::clear_sets() { - if (cleared_cache) { - return; - } - for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) { - for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) { - if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j])) { - RD::get_singleton()->free(uniform_sets[i][j]); - uniform_sets[i][j] = RID(); - } - } - } - cleared_cache = true; -} - -RendererStorageRD::CanvasTexture::~CanvasTexture() { - clear_sets(); -} - void RendererStorageRD::sampler_rd_configure_custom(float p_mipmap_bias) { for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) { for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) { @@ -1237,149 +136,6 @@ void RendererStorageRD::sampler_rd_configure_custom(float p_mipmap_bias) { } } -RID RendererStorageRD::canvas_texture_allocate() { - return canvas_texture_owner.allocate_rid(); -} -void RendererStorageRD::canvas_texture_initialize(RID p_rid) { - canvas_texture_owner.initialize_rid(p_rid); -} - -void RendererStorageRD::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; - } - - ct->clear_sets(); -} - -void RendererStorageRD::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; - ct->clear_sets(); -} - -void RendererStorageRD::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; - ct->clear_sets(); -} - -void RendererStorageRD::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; - ct->clear_sets(); -} - -bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) { - CanvasTexture *ct = nullptr; - - Texture *t = texture_owner.get_or_null(p_texture); - - if (t) { - //regular texture - if (!t->canvas_texture) { - t->canvas_texture = memnew(CanvasTexture); - t->canvas_texture->diffuse = p_texture; - } - - ct = t->canvas_texture; - } else { - ct = canvas_texture_owner.get_or_null(p_texture); - } - - if (!ct) { - return false; //invalid texture RID - } - - RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter; - ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false); - - RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat; - ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false); - - RID uniform_set = ct->uniform_sets[filter][repeat]; - if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) { - //create and update - Vector<RD::Uniform> uniforms; - { //diffuse - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 0; - - t = texture_owner.get_or_null(ct->diffuse); - if (!t) { - u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); - ct->size_cache = Size2i(1, 1); - } else { - u.ids.push_back(t->rd_texture); - ct->size_cache = Size2i(t->width_2d, t->height_2d); - } - uniforms.push_back(u); - } - { //normal - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 1; - - t = texture_owner.get_or_null(ct->normal_map); - if (!t) { - u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL)); - ct->use_normal_cache = false; - } else { - u.ids.push_back(t->rd_texture); - ct->use_normal_cache = true; - } - uniforms.push_back(u); - } - { //specular - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 2; - - t = texture_owner.get_or_null(ct->specular); - if (!t) { - u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); - ct->use_specular_cache = false; - } else { - u.ids.push_back(t->rd_texture); - ct->use_specular_cache = true; - } - uniforms.push_back(u); - } - { //sampler - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 3; - u.ids.push_back(sampler_rd_get_default(filter, repeat)); - uniforms.push_back(u); - } - - uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set); - ct->uniform_sets[filter][repeat] = uniform_set; - ct->cleared_cache = false; - } - - r_uniform_set = uniform_set; - r_size = ct->size_cache; - r_specular_shininess = ct->specular_color; - r_use_normal = ct->use_normal_cache; - r_use_specular = ct->use_specular_cache; - - return true; -} - /* SHADER API */ RID RendererStorageRD::shader_allocate() { @@ -1487,7 +243,7 @@ void RendererStorageRD::shader_set_default_texture_param(RID p_shader, const Str Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND(!shader); - if (p_texture.is_valid() && texture_owner.owns(p_texture)) { + if (p_texture.is_valid() && RendererRD::TextureStorage::get_singleton()->owns_texture(p_texture)) { if (!shader->default_texture_parameter.has(p_name)) { shader->default_texture_parameter[p_name] = Map<int, RID>(); } @@ -2642,11 +1398,12 @@ RendererStorageRD::MaterialData::~MaterialData() { } void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { - RendererStorageRD *singleton = (RendererStorageRD *)RendererStorage::base_singleton; + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + #ifdef TOOLS_ENABLED - Texture *roughness_detect_texture = nullptr; + RendererRD::Texture *roughness_detect_texture = nullptr; RS::TextureDetectRoughnessChannel roughness_channel = RS::TEXTURE_DETECT_ROUGHNESS_R; - Texture *normal_detect_texture = nullptr; + RendererRD::Texture *normal_detect_texture = nullptr; #endif bool uses_global_textures = false; @@ -2732,19 +1489,19 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari switch (p_texture_uniforms[i].hint) { case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_BLACK); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK); } break; case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_ANISO); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_ANISO); } break; case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_NORMAL); } break; case ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_NORMAL); } break; default: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } break; } } break; @@ -2753,27 +1510,27 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari switch (p_texture_uniforms[i].hint) { case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); } break; default: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_CUBEMAP_WHITE); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE); } break; } } break; case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK); } break; case ShaderLanguage::TYPE_ISAMPLER3D: case ShaderLanguage::TYPE_USAMPLER3D: case ShaderLanguage::TYPE_SAMPLER3D: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_3D_WHITE); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); } break; case ShaderLanguage::TYPE_ISAMPLER2DARRAY: case ShaderLanguage::TYPE_USAMPLER2DARRAY: case ShaderLanguage::TYPE_SAMPLER2DARRAY: { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } break; default: { @@ -2795,7 +1552,7 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari bool srgb = p_use_linear_color && (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO || p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO); for (int j = 0; j < textures.size(); j++) { - Texture *tex = singleton->texture_owner.get_or_null(textures[j]); + RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(textures[j]); if (tex) { rd_texture = (srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; @@ -2817,7 +1574,7 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari #endif } if (rd_texture.is_null()) { - rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE); + rd_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } #ifdef TOOLS_ENABLED if (roughness_detect_texture && normal_detect_texture && !normal_detect_texture->path.is_empty()) { @@ -2933,7 +1690,7 @@ bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<St RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; - u.ids.push_back(uniform_buffer); + u.append_id(uniform_buffer); uniforms.push_back(u); } @@ -2946,10 +1703,10 @@ bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<St u.binding = 1 + k; if (array_size > 0) { for (int j = 0; j < array_size; j++) { - u.ids.push_back(textures[k++]); + u.append_id(textures[k++]); } } else { - u.ids.push_back(textures[k++]); + u.append_id(textures[k++]); } uniforms.push_back(u); } @@ -3155,7 +1912,7 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(s->vertex_buffer); + u.append_id(s->vertex_buffer); uniforms.push_back(u); } { @@ -3163,9 +1920,9 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; if (s->skin_buffer.is_valid()) { - u.ids.push_back(s->skin_buffer); + u.append_id(s->skin_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -3174,9 +1931,9 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; if (s->blend_shape_buffer.is_valid()) { - u.ids.push_back(s->blend_shape_buffer); + u.append_id(s->blend_shape_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -3618,7 +2375,7 @@ void RendererStorageRD::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, RD::Uniform u; u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(s.vertex_buffer); + u.append_id(s.vertex_buffer); uniforms.push_back(u); } { @@ -3626,9 +2383,9 @@ void RendererStorageRD::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; if (mi->blend_weights_buffer.is_valid()) { - u.ids.push_back(mi->blend_weights_buffer); + u.append_id(mi->blend_weights_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -4946,6 +3703,8 @@ void RendererStorageRD::particles_set_canvas_sdf_collision(RID p_particles, bool } void RendererStorageRD::_particles_process(Particles *p_particles, double p_delta) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + if (p_particles->particles_material_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_particles->particles_material_uniform_set)) { Vector<RD::Uniform> uniforms; @@ -4953,14 +3712,14 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(p_particles->frame_params_buffer); + u.append_id(p_particles->frame_params_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(p_particles->particle_buffer); + u.append_id(p_particles->particle_buffer); uniforms.push_back(u); } @@ -4969,9 +3728,9 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; if (p_particles->emission_storage_buffer.is_valid()) { - u.ids.push_back(p_particles->emission_storage_buffer); + u.append_id(p_particles->emission_storage_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -4984,9 +3743,9 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt if (sub_emitter->emission_buffer == nullptr) { //no emission buffer, allocate emission buffer _particles_allocate_emission_buffer(sub_emitter); } - u.ids.push_back(sub_emitter->emission_storage_buffer); + u.append_id(sub_emitter->emission_storage_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -5248,16 +4007,16 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt for (uint32_t i = 0; i < ParticlesFrameParams::MAX_3D_TEXTURES; i++) { RID rd_tex; if (i < collision_3d_textures_used) { - Texture *t = texture_owner.get_or_null(collision_3d_textures[i]); - if (t && t->type == Texture::TYPE_3D) { + RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(collision_3d_textures[i]); + if (t && t->type == RendererRD::Texture::TYPE_3D) { rd_tex = t->rd_texture; } } if (rd_tex == RID()) { - rd_tex = default_rd_textures[DEFAULT_RD_TEXTURE_3D_WHITE]; + rd_tex = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); } - u.ids.push_back(rd_tex); + u.append_id(rd_tex); } uniforms.push_back(u); } @@ -5266,9 +4025,9 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; if (collision_heightmap_texture.is_valid()) { - u.ids.push_back(collision_heightmap_texture); + u.append_id(collision_heightmap_texture); } else { - u.ids.push_back(default_rd_textures[DEFAULT_RD_TEXTURE_BLACK]); + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); } uniforms.push_back(u); } @@ -5402,7 +4161,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(particles->particles_sort_buffer); + u.append_id(particles->particles_sort_buffer); uniforms.push_back(u); } @@ -5522,14 +4281,14 @@ void RendererStorageRD::_particles_update_buffers(Particles *particles) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(particles->particle_buffer); + u.append_id(particles->particle_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(particles->particle_instance_buffer); + u.append_id(particles->particle_instance_buffer); uniforms.push_back(u); } @@ -5627,9 +4386,9 @@ void RendererStorageRD::update_particles() { u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; if (particles->trail_bind_pose_buffer.is_valid()) { - u.ids.push_back(particles->trail_bind_pose_buffer); + u.append_id(particles->trail_bind_pose_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -5712,6 +4471,21 @@ void RendererStorageRD::update_particles() { total_amount *= particles->trail_bind_poses.size(); } + // Affect 2D only. + if (particles->use_local_coords) { + // In local mode, particle positions are calculated locally (relative to the node position) + // and they're also drawn locally. + // It works as expected, so we just pass an identity transform. + store_transform(Transform3D(), copy_push_constant.inv_emission_transform); + } else { + // In global mode, particle positions are calculated globally (relative to the canvas origin) + // but they're drawn locally. + // So, we need to pass the inverse of the emission transform to bring the + // particles to local coordinates before drawing. + Transform3D inv = particles->emission_transform.affine_inverse(); + store_transform(inv, copy_push_constant.inv_emission_transform); + } + copy_push_constant.total_particles = total_amount; copy_push_constant.frame_remainder = particles->interpolate ? particles->frame_remainder : 0.0; copy_push_constant.align_mode = particles->transform_align; @@ -6300,7 +5074,7 @@ void RendererStorageRD::skeleton_allocate_data(RID p_skeleton, int p_bones, bool RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(skeleton->buffer); + u.append_id(skeleton->buffer); uniforms.push_back(u); } skeleton->uniform_set_mi = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON); @@ -6540,12 +5314,6 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) { light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } -void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { - Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND(!light); - light->shadow_color = p_color; -} - void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) { Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); @@ -6585,6 +5353,16 @@ void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } +void RendererStorageRD::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) { + Light *light = light_owner.get_or_null(p_light); + ERR_FAIL_COND(!light); + + light->distance_fade = p_enabled; + light->distance_fade_begin = p_begin; + light->distance_fade_shadow = p_shadow; + light->distance_fade_length = p_length; +} + void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); @@ -6657,18 +5435,18 @@ bool RendererStorageRD::light_directional_get_blend_splits(RID p_light) const { return light->directional_blend_splits; } -void RendererStorageRD::light_directional_set_sky_only(RID p_light, bool p_sky_only) { +void RendererStorageRD::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) { Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); - light->directional_sky_only = p_sky_only; + light->directional_sky_mode = p_mode; } -bool RendererStorageRD::light_directional_is_sky_only(RID p_light) const { +RS::LightDirectionalSkyMode RendererStorageRD::light_directional_get_sky_mode(RID p_light) const { const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, false); + ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY); - return light->directional_sky_only; + return light->directional_sky_mode; } RS::LightDirectionalShadowMode RendererStorageRD::light_directional_get_shadow_mode(RID p_light) { @@ -6972,9 +5750,9 @@ void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, return; } - ERR_FAIL_COND(p_texture.is_valid() && !texture_owner.owns(p_texture)); + ERR_FAIL_COND(p_texture.is_valid() && !RendererRD::TextureStorage::get_singleton()->owns_texture(p_texture)); - if (decal->textures[p_type].is_valid() && texture_owner.owns(decal->textures[p_type])) { + if (decal->textures[p_type].is_valid() && RendererRD::TextureStorage::get_singleton()->owns_texture(decal->textures[p_type])) { texture_remove_from_decal_atlas(decal->textures[p_type]); } @@ -7121,21 +5899,21 @@ void RendererStorageRD::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(voxel_gi->octree_buffer); + u.append_id(voxel_gi->octree_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(voxel_gi->data_buffer); + u.append_id(voxel_gi->data_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(shared_tex); + u.append_id(shared_tex); uniforms.push_back(u); } @@ -7379,6 +6157,8 @@ void RendererStorageRD::lightmap_initialize(RID p_lightmap) { } void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + Lightmap *lm = lightmap_owner.get_or_null(p_lightmap); ERR_FAIL_COND(!lm); @@ -7386,17 +6166,17 @@ void RendererStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool //erase lightmap users if (lm->light_texture.is_valid()) { - Texture *t = texture_owner.get_or_null(lm->light_texture); + RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(lm->light_texture); if (t) { t->lightmap_users.erase(p_lightmap); } } - Texture *t = texture_owner.get_or_null(p_light); + RendererRD::Texture *t = RendererRD::TextureStorage::get_singleton()->get_texture(p_light); lm->light_texture = p_light; lm->uses_spherical_harmonics = p_uses_spherical_haromics; - RID default_2d_array = default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE]; + RID default_2d_array = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); if (!t) { if (using_lightmap_array) { if (lm->array_index >= 0) { @@ -7574,9 +6354,9 @@ void RendererStorageRD::_clear_render_target(RenderTarget *rt) { void RendererStorageRD::_update_render_target(RenderTarget *rt) { if (rt->texture.is_null()) { //create a placeholder until updated - rt->texture = texture_allocate(); - texture_2d_placeholder_initialize(rt->texture); - Texture *tex = texture_owner.get_or_null(rt->texture); + rt->texture = RendererRD::TextureStorage::get_singleton()->texture_allocate(); + RendererRD::TextureStorage::get_singleton()->texture_2d_placeholder_initialize(rt->texture); + RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture); tex->is_render_target = true; } @@ -7623,7 +6403,7 @@ void RendererStorageRD::_update_render_target(RenderTarget *rt) { { //update texture - Texture *tex = texture_owner.get_or_null(rt->texture); + RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture); //free existing textures if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) { @@ -7659,7 +6439,7 @@ void RendererStorageRD::_update_render_target(RenderTarget *rt) { Vector<RID> proxies = tex->proxies; //make a copy, since update may change it for (int i = 0; i < proxies.size(); i++) { - texture_proxy_update(proxies[i], rt->texture); + RendererRD::TextureStorage::get_singleton()->texture_proxy_update(proxies[i], rt->texture); } } } @@ -7983,33 +6763,36 @@ void RendererStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(rt->sdf_buffer_write); + u.append_id(rt->sdf_buffer_write); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(rt->sdf_buffer_read); + u.append_id(rt->sdf_buffer_read); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(rt->sdf_buffer_process[0]); + u.append_id(rt->sdf_buffer_process[0]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; - u.ids.push_back(rt->sdf_buffer_process[1]); + u.append_id(rt->sdf_buffer_process[1]); uniforms.push_back(u); } rt->sdf_buffer_process_uniform_sets[0] = RD::get_singleton()->uniform_set_create(uniforms, rt_sdf.shader.version_get_shader(rt_sdf.shader_version, 0), 0); - SWAP(uniforms.write[2].ids.write[0], uniforms.write[3].ids.write[0]); + RID aux2 = uniforms.write[2].get_id(0); + RID aux3 = uniforms.write[3].get_id(0); + uniforms.write[2].set_id(0, aux3); + uniforms.write[3].set_id(0, aux2); rt->sdf_buffer_process_uniform_sets[1] = RD::get_singleton()->uniform_set_create(uniforms, rt_sdf.shader.version_get_shader(rt_sdf.shader_version, 0), 0); } } @@ -8319,6 +7102,21 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const { return RS::INSTANCE_NONE; } +void RendererStorageRD::decal_atlas_remove_texture(RID p_texture) { + if (decal_atlas.textures.has(p_texture)) { + decal_atlas.textures.erase(p_texture); + //there is not much a point of making it dirty, just let it be. + } +} + +void RendererStorageRD::decal_atlas_mark_dirty_on_texture(RID p_texture) { + if (decal_atlas.textures.has(p_texture)) { + //belongs to decal atlas.. + + decal_atlas.dirty = true; //mark it dirty since it was most likely modified + } +} + void RendererStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) { if (!decal_atlas.textures.has(p_texture)) { DecalAtlas::Texture t; @@ -8384,7 +7182,7 @@ void RendererStorageRD::_update_decal_atlas() { while ((K = decal_atlas.textures.next(K))) { DecalAtlas::SortItem &si = itemsv.write[idx]; - Texture *src_tex = texture_owner.get_or_null(*K); + RendererRD::Texture *src_tex = RendererRD::TextureStorage::get_singleton()->get_texture(*K); si.size.width = (src_tex->width / border) + 1; si.size.height = (src_tex->height / border) + 1; @@ -8533,7 +7331,7 @@ void RendererStorageRD::_update_decal_atlas() { const RID *K = nullptr; while ((K = decal_atlas.textures.next(K))) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); - Texture *src_tex = texture_owner.get_or_null(*K); + RendererRD::Texture *src_tex = RendererRD::TextureStorage::get_singleton()->get_texture(*K); effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); } @@ -9243,47 +8041,10 @@ bool RendererStorageRD::has_os_feature(const String &p_feature) const { } bool RendererStorageRD::free(RID p_rid) { - if (texture_owner.owns(p_rid)) { - Texture *t = texture_owner.get_or_null(p_rid); - - ERR_FAIL_COND_V(!t, false); - ERR_FAIL_COND_V(t->is_render_target, false); - - if (RD::get_singleton()->texture_is_valid(t->rd_texture_srgb)) { - //erase this first, as it's a dependency of the one below - RD::get_singleton()->free(t->rd_texture_srgb); - } - if (RD::get_singleton()->texture_is_valid(t->rd_texture)) { - RD::get_singleton()->free(t->rd_texture); - } - - if (t->is_proxy && t->proxy_to.is_valid()) { - Texture *proxy_to = texture_owner.get_or_null(t->proxy_to); - if (proxy_to) { - proxy_to->proxies.erase(p_rid); - } - } - - if (decal_atlas.textures.has(p_rid)) { - decal_atlas.textures.erase(p_rid); - //there is not much a point of making it dirty, just let it be. - } - - for (int i = 0; i < t->proxies.size(); i++) { - Texture *p = texture_owner.get_or_null(t->proxies[i]); - ERR_CONTINUE(!p); - p->proxy_to = RID(); - p->rd_texture = RID(); - p->rd_texture_srgb = RID(); - } - - if (t->canvas_texture) { - memdelete(t->canvas_texture); - } - texture_owner.free(p_rid); - - } else if (canvas_texture_owner.owns(p_rid)) { - canvas_texture_owner.free(p_rid); + if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) { + RendererRD::TextureStorage::get_singleton()->texture_free(p_rid); + } else if (RendererRD::CanvasTextureStorage::get_singleton()->owns_canvas_texture(p_rid)) { + RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_free(p_rid); } else if (shader_owner.owns(p_rid)) { Shader *shader = shader_owner.get_or_null(p_rid); //make material unreference this @@ -9345,7 +8106,7 @@ bool RendererStorageRD::free(RID p_rid) { } else if (decal_owner.owns(p_rid)) { Decal *decal = decal_owner.get_or_null(p_rid); for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) { - if (decal->textures[i].is_valid() && texture_owner.owns(decal->textures[i])) { + if (decal->textures[i].is_valid() && RendererRD::TextureStorage::get_singleton()->owns_texture(decal->textures[i])) { texture_remove_from_decal_atlas(decal->textures[i]); } } @@ -9399,7 +8160,7 @@ bool RendererStorageRD::free(RID p_rid) { _clear_render_target(rt); if (rt->texture.is_valid()) { - Texture *tex = texture_owner.get_or_null(rt->texture); + RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture); tex->is_render_target = false; free(rt->texture); } @@ -9482,14 +8243,15 @@ RendererStorageRD *RendererStorageRD::base_singleton = nullptr; RendererStorageRD::RendererStorageRD() { base_singleton = this; + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + for (int i = 0; i < SHADER_TYPE_MAX; i++) { shader_data_request_func[i] = nullptr; } static_assert(sizeof(GlobalVariables::Value) == 16); - global_variables.buffer_size = GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size"); - global_variables.buffer_size = MAX(4096, global_variables.buffer_size); + global_variables.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size); memset(global_variables.buffer_values, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size); global_variables.buffer_usage = memnew_arr(GlobalVariables::ValueUsage, global_variables.buffer_size); @@ -9497,8 +8259,7 @@ RendererStorageRD::RendererStorageRD() { memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size); - { //create default textures - + { // default atlas texture RD::TextureFormat tformat; tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; tformat.width = 4; @@ -9508,18 +8269,6 @@ RendererStorageRD::RendererStorageRD() { Vector<uint8_t> pv; pv.resize(16 * 4); - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 255); - pv.set(i * 4 + 1, 255); - pv.set(i * 4 + 2, 255); - pv.set(i * 4 + 3, 255); - } - - { - Vector<Vector<uint8_t>> vpv; - vpv.push_back(pv); - default_rd_textures[DEFAULT_RD_TEXTURE_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } for (int i = 0; i < 16; i++) { pv.set(i * 4 + 0, 0); @@ -9529,211 +8278,12 @@ RendererStorageRD::RendererStorageRD() { } { + //take the chance and initialize decal atlas to something Vector<Vector<uint8_t>> vpv; vpv.push_back(pv); - default_rd_textures[DEFAULT_RD_TEXTURE_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - - //take the chance and initialize decal atlas to something decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); decal_atlas.texture_srgb = decal_atlas.texture; } - - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 128); - pv.set(i * 4 + 1, 128); - pv.set(i * 4 + 2, 255); - pv.set(i * 4 + 3, 255); - } - - { - Vector<Vector<uint8_t>> vpv; - vpv.push_back(pv); - default_rd_textures[DEFAULT_RD_TEXTURE_NORMAL] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } - - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 255); - pv.set(i * 4 + 1, 128); - pv.set(i * 4 + 2, 255); - pv.set(i * 4 + 3, 255); - } - - { - Vector<Vector<uint8_t>> vpv; - vpv.push_back(pv); - default_rd_textures[DEFAULT_RD_TEXTURE_ANISO] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } - - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 0); - pv.set(i * 4 + 1, 0); - pv.set(i * 4 + 2, 0); - pv.set(i * 4 + 3, 0); - } - - default_rd_textures[DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER] = RD::get_singleton()->texture_buffer_create(16, RD::DATA_FORMAT_R8G8B8A8_UNORM, pv); - - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 0); - pv.set(i * 4 + 1, 0); - pv.set(i * 4 + 2, 0); - pv.set(i * 4 + 3, 0); - } - - { - tformat.format = RD::DATA_FORMAT_R8G8B8A8_UINT; - Vector<Vector<uint8_t>> vpv; - vpv.push_back(pv); - default_rd_textures[DEFAULT_RD_TEXTURE_2D_UINT] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } - } - - { //create default cubemap - - RD::TextureFormat tformat; - tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - tformat.width = 4; - tformat.height = 4; - tformat.array_layers = 6; - tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY; - - Vector<uint8_t> pv; - pv.resize(16 * 4); - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 0); - pv.set(i * 4 + 1, 0); - pv.set(i * 4 + 2, 0); - pv.set(i * 4 + 3, 0); - } - - { - Vector<Vector<uint8_t>> vpv; - for (int i = 0; i < 6; i++) { - vpv.push_back(pv); - } - default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } - } - - { //create default cubemap array - - RD::TextureFormat tformat; - tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - tformat.width = 4; - tformat.height = 4; - tformat.array_layers = 6; - tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_CUBE; - - Vector<uint8_t> pv; - pv.resize(16 * 4); - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 0); - pv.set(i * 4 + 1, 0); - pv.set(i * 4 + 2, 0); - pv.set(i * 4 + 3, 0); - } - - { - Vector<Vector<uint8_t>> vpv; - for (int i = 0; i < 6; i++) { - vpv.push_back(pv); - } - default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } - } - - { //create default cubemap white array - - RD::TextureFormat tformat; - tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - tformat.width = 4; - tformat.height = 4; - tformat.array_layers = 6; - tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_CUBE; - - Vector<uint8_t> pv; - pv.resize(16 * 4); - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 255); - pv.set(i * 4 + 1, 255); - pv.set(i * 4 + 2, 255); - pv.set(i * 4 + 3, 255); - } - - { - Vector<Vector<uint8_t>> vpv; - for (int i = 0; i < 6; i++) { - vpv.push_back(pv); - } - default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } - } - - { //create default 3D - - RD::TextureFormat tformat; - tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - tformat.width = 4; - tformat.height = 4; - tformat.depth = 4; - tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_3D; - - Vector<uint8_t> pv; - pv.resize(64 * 4); - for (int i = 0; i < 64; i++) { - pv.set(i * 4 + 0, 0); - pv.set(i * 4 + 1, 0); - pv.set(i * 4 + 2, 0); - pv.set(i * 4 + 3, 0); - } - - { - Vector<Vector<uint8_t>> vpv; - vpv.push_back(pv); - default_rd_textures[DEFAULT_RD_TEXTURE_3D_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } - for (int i = 0; i < 64; i++) { - pv.set(i * 4 + 0, 255); - pv.set(i * 4 + 1, 255); - pv.set(i * 4 + 2, 255); - pv.set(i * 4 + 3, 255); - } - - { - Vector<Vector<uint8_t>> vpv; - vpv.push_back(pv); - default_rd_textures[DEFAULT_RD_TEXTURE_3D_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } - } - - { //create default array - - RD::TextureFormat tformat; - tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - tformat.width = 4; - tformat.height = 4; - tformat.array_layers = 1; - tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; - - Vector<uint8_t> pv; - pv.resize(16 * 4); - for (int i = 0; i < 16; i++) { - pv.set(i * 4 + 0, 255); - pv.set(i * 4 + 1, 255); - pv.set(i * 4 + 2, 255); - pv.set(i * 4 + 3, 255); - } - - { - Vector<Vector<uint8_t>> vpv; - vpv.push_back(pv); - default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); - } } //default samplers @@ -9940,7 +8490,7 @@ RendererStorageRD::RendererStorageRD() { using_lightmap_array = true; // high end if (using_lightmap_array) { - uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); if (textures_per_stage <= 256) { lightmap_textures.resize(32); @@ -9949,7 +8499,7 @@ RendererStorageRD::RendererStorageRD() { } for (int i = 0; i < lightmap_textures.size(); i++) { - lightmap_textures.write[i] = default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE]; + lightmap_textures.write[i] = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } } @@ -10049,11 +8599,9 @@ void process() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 1; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -10066,6 +8614,8 @@ void process() { ids_ptr[9] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); uniforms.push_back(u); } @@ -10073,7 +8623,7 @@ void process() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(global_variables_get_storage_buffer()); + u.append_id(global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -10142,7 +8692,7 @@ void process() { RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); uniforms.push_back(u); } skeleton_shader.default_skeleton_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON); @@ -10156,11 +8706,6 @@ RendererStorageRD::~RendererStorageRD() { memdelete_arr(global_variables.buffer_dirty_regions); RD::get_singleton()->free(global_variables.buffer); - //def textures - for (int i = 0; i < DEFAULT_RD_TEXTURE_MAX; i++) { - RD::get_singleton()->free(default_rd_textures[i]); - } - //def samplers for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) { for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) { diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index ee4d18210a..872dd41fe5 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -41,9 +41,12 @@ #include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/skeleton.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h" +#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/shader_compiler.h" + class RendererStorageRD : public RendererStorage { public: static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) { @@ -179,22 +182,6 @@ public: typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *); static void _material_uniform_set_erased(void *p_material); - enum DefaultRDTexture { - DEFAULT_RD_TEXTURE_WHITE, - DEFAULT_RD_TEXTURE_BLACK, - DEFAULT_RD_TEXTURE_NORMAL, - DEFAULT_RD_TEXTURE_ANISO, - DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER, - DEFAULT_RD_TEXTURE_CUBEMAP_BLACK, - DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK, - DEFAULT_RD_TEXTURE_CUBEMAP_WHITE, - DEFAULT_RD_TEXTURE_3D_WHITE, - DEFAULT_RD_TEXTURE_3D_BLACK, - DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE, - DEFAULT_RD_TEXTURE_2D_UINT, - DEFAULT_RD_TEXTURE_MAX - }; - enum DefaultRDBuffer { DEFAULT_RD_BUFFER_VERTEX, DEFAULT_RD_BUFFER_NORMAL, @@ -212,113 +199,8 @@ public: }; private: - /* CANVAS TEXTURE API (2D) */ - - 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; - RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; - - Size2i size_cache = Size2i(1, 1); - bool use_normal_cache = false; - bool use_specular_cache = false; - bool cleared_cache = true; - void clear_sets(); - ~CanvasTexture(); - }; - - RID_Owner<CanvasTexture, true> canvas_texture_owner; - /* TEXTURE API */ - struct Texture { - enum Type { - TYPE_2D, - TYPE_LAYERED, - TYPE_3D - }; - - Type type; - RS::TextureLayeredType layered_type = RS::TEXTURE_LAYERED_2D_ARRAY; - - RenderingDevice::TextureType rd_type; - RID rd_texture; - RID rd_texture_srgb; - RenderingDevice::DataFormat rd_format; - RenderingDevice::DataFormat rd_format_srgb; - - RD::TextureView rd_view; - - Image::Format format; - Image::Format validated_format; - - int width; - int height; - int depth; - int layers; - int mipmaps; - - int height_2d; - int width_2d; - - struct BufferSlice3D { - Size2i size; - uint32_t offset = 0; - uint32_t buffer_size = 0; - }; - Vector<BufferSlice3D> buffer_slices_3d; - uint32_t buffer_size_3d = 0; - - bool is_render_target; - bool is_proxy; - - Ref<Image> image_cache_2d; - String path; - - RID proxy_to; - Vector<RID> proxies; - Set<RID> lightmap_users; - - RS::TextureDetectCallback detect_3d_callback = nullptr; - void *detect_3d_callback_ud = nullptr; - - RS::TextureDetectCallback detect_normal_callback = nullptr; - void *detect_normal_callback_ud = nullptr; - RS::TextureDetectRoughnessCallback detect_roughness_callback = nullptr; - void *detect_roughness_callback_ud = nullptr; - - CanvasTexture *canvas_texture = nullptr; - }; - - struct TextureToRDFormat { - RD::DataFormat format; - RD::DataFormat format_srgb; - RD::TextureSwizzle swizzle_r; - RD::TextureSwizzle swizzle_g; - RD::TextureSwizzle swizzle_b; - RD::TextureSwizzle swizzle_a; - TextureToRDFormat() { - format = RD::DATA_FORMAT_MAX; - format_srgb = RD::DATA_FORMAT_MAX; - swizzle_r = RD::TEXTURE_SWIZZLE_R; - swizzle_g = RD::TEXTURE_SWIZZLE_G; - swizzle_b = RD::TEXTURE_SWIZZLE_B; - swizzle_a = RD::TEXTURE_SWIZZLE_A; - } - }; - - //textures can be created from threads, so this RID_Owner is thread safe - mutable RID_Owner<Texture, true> texture_owner; - - Ref<Image> _validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format); - - RID default_rd_textures[DEFAULT_RD_TEXTURE_MAX]; RID default_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; RID custom_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; RID default_rd_storage_buffer; @@ -852,6 +734,8 @@ private: uint32_t lifetime_split; uint32_t lifetime_reverse; uint32_t copy_mode_2d; + + float inv_emission_transform[16]; }; enum { @@ -1023,7 +907,6 @@ private: RS::LightType type; float param[RS::LIGHT_PARAM_MAX]; Color color = Color(1, 1, 1, 1); - Color shadow_color; RID projector; bool shadow = false; bool negative = false; @@ -1031,10 +914,14 @@ private: RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC; uint32_t max_sdfgi_cascade = 2; uint32_t cull_mask = 0xFFFFFFFF; + bool distance_fade = false; + real_t distance_fade_begin = 40.0; + real_t distance_fade_shadow = 50.0; + real_t distance_fade_length = 10.0; RS::LightOmniShadowMode omni_shadow_mode = RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; bool directional_blend_splits = false; - bool directional_sky_only = false; + RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY; uint64_t version = 0; Dependency dependency; @@ -1303,52 +1190,6 @@ private: EffectsRD *effects = nullptr; public: - virtual bool can_create_resources_async() const; - - /* TEXTURE API */ - - virtual RID texture_allocate(); - - virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image); - virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type); - virtual void texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); //all slices, then all the mipmaps, must be coherent - virtual void texture_proxy_initialize(RID p_texture, RID p_base); - - virtual void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate); - - virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0); - virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data); - virtual void texture_proxy_update(RID p_texture, RID p_proxy_to); - - //these two APIs can be used together or in combination with the others. - virtual void texture_2d_placeholder_initialize(RID p_texture); - virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type); - virtual void texture_3d_placeholder_initialize(RID p_texture); - - virtual Ref<Image> texture_2d_get(RID p_texture) const; - virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const; - virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const; - - virtual void texture_replace(RID p_texture, RID p_by_texture); - virtual void texture_set_size_override(RID p_texture, int p_width, int p_height); - - virtual void texture_set_path(RID p_texture, const String &p_path); - virtual String texture_get_path(RID p_texture) const; - - virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata); - virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata); - virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata); - - virtual void texture_debug_usage(List<RS::TextureInfo> *r_info); - - virtual void texture_set_proxy(RID p_proxy, RID p_base); - virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable); - - virtual Size2 texture_size_with_proxy(RID p_proxy); - - virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false); - virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false); - RID decal_atlas_get_texture() const; RID decal_atlas_get_texture_srgb() const; _FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) { @@ -1362,33 +1203,6 @@ public: //internal usage - _FORCE_INLINE_ RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) { - if (p_texture.is_null()) { - return RID(); - } - Texture *tex = texture_owner.get_or_null(p_texture); - - if (!tex) { - return RID(); - } - return (p_srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; - } - - _FORCE_INLINE_ Size2i texture_2d_get_size(RID p_texture) { - if (p_texture.is_null()) { - return Size2i(); - } - Texture *tex = texture_owner.get_or_null(p_texture); - - if (!tex) { - return Size2i(); - } - return Size2i(tex->width_2d, tex->height_2d); - } - - _FORCE_INLINE_ RID texture_rd_get_default(DefaultRDTexture p_texture) { - return default_rd_textures[p_texture]; - } _FORCE_INLINE_ RID sampler_rd_get_default(RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat) { return default_rd_samplers[p_filter][p_repeat]; } @@ -1400,19 +1214,6 @@ public: void sampler_rd_set_default(float p_mipmap_bias); - /* CANVAS TEXTURE API */ - - RID canvas_texture_allocate(); - void canvas_texture_initialize(RID p_canvas_texture); - - virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture); - virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess); - - virtual void canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter); - virtual void canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat); - - bool canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular); - /* SHADER API */ RID shader_allocate(); @@ -1759,7 +1560,7 @@ public: RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(multimesh->buffer); + u.append_id(multimesh->buffer); uniforms.push_back(u); multimesh->uniform_set_3d = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set); } @@ -1774,7 +1575,7 @@ public: RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(multimesh->buffer); + u.append_id(multimesh->buffer); uniforms.push_back(u); multimesh->uniform_set_2d = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set); } @@ -1812,7 +1613,7 @@ public: RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(skeleton->buffer); + u.append_id(skeleton->buffer); uniforms.push_back(u); skeleton->uniform_set_3d = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set); } @@ -1835,10 +1636,10 @@ public: void light_set_color(RID p_light, const Color &p_color); void light_set_param(RID p_light, RS::LightParam p_param, float p_value); void light_set_shadow(RID p_light, bool p_enabled); - void light_set_shadow_color(RID p_light, const Color &p_color); void light_set_projector(RID p_light, RID p_texture); void light_set_negative(RID p_light, bool p_enable); void light_set_cull_mask(RID p_light, uint32_t p_mask); + void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length); void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled); void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode); void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade); @@ -1848,8 +1649,8 @@ public: void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode); void light_directional_set_blend_splits(RID p_light, bool p_enable); bool light_directional_get_blend_splits(RID p_light) const; - void light_directional_set_sky_only(RID p_light, bool p_sky_only); - bool light_directional_is_sky_only(RID p_light) const; + void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode); + RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const; RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light); RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light); @@ -1883,18 +1684,31 @@ public: return light->color; } - _FORCE_INLINE_ Color light_get_shadow_color(RID p_light) { + _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, Color()); + ERR_FAIL_COND_V(!light, 0); - return light->shadow_color; + return light->cull_mask; } - _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { + _FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) { const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, 0); + return light->distance_fade; + } - return light->cull_mask; + _FORCE_INLINE_ float light_get_distance_fade_begin(RID p_light) { + const Light *light = light_owner.get_or_null(p_light); + return light->distance_fade_begin; + } + + _FORCE_INLINE_ float light_get_distance_fade_shadow(RID p_light) { + const Light *light = light_owner.get_or_null(p_light); + return light->distance_fade_shadow; + } + + _FORCE_INLINE_ float light_get_distance_fade_length(RID p_light) { + const Light *light = light_owner.get_or_null(p_light); + return light->distance_fade_length; } _FORCE_INLINE_ bool light_has_shadow(RID p_light) const { @@ -1908,7 +1722,7 @@ public: const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); - return texture_owner.owns(light->projector); + return light_owner.owns(light->projector); } _FORCE_INLINE_ bool light_is_negative(RID p_light) const { @@ -1992,6 +1806,12 @@ public: virtual void decal_set_fade(RID p_decal, float p_above, float p_below); virtual void decal_set_normal_fade(RID p_decal, float p_fade); + void decal_atlas_mark_dirty_on_texture(RID p_texture); + void decal_atlas_remove_texture(RID p_texture); + + virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false); + virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false); + _FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) { const Decal *decal = decal_owner.get_or_null(p_decal); return decal->extents; @@ -2249,7 +2069,7 @@ public: RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(particles->particle_instance_buffer); + u.append_id(particles->particle_instance_buffer); uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl index 2f1f9c4765..9787c9879d 100644 --- a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl @@ -4,7 +4,20 @@ #VERSION_DEFINES +#ifdef MULTIVIEW +#ifdef has_VK_KHR_multiview +#extension GL_EXT_multiview : enable +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#endif //MULTIVIEW + +#ifdef MULTIVIEW +layout(location = 0) out vec3 uv_interp; +#else layout(location = 0) out vec2 uv_interp; +#endif layout(push_constant, std430) uniform Params { vec4 section; @@ -19,9 +32,11 @@ params; void main() { vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); - uv_interp = base_arr[gl_VertexIndex]; - - vec2 vpos = uv_interp; + uv_interp.xy = base_arr[gl_VertexIndex]; +#ifdef MULTIVIEW + uv_interp.z = ViewIndex; +#endif + vec2 vpos = uv_interp.xy; if (params.use_section) { vpos = params.section.xy + vpos * params.section.zw; } @@ -39,6 +54,15 @@ void main() { #VERSION_DEFINES +#ifdef MULTIVIEW +#ifdef has_VK_KHR_multiview +#extension GL_EXT_multiview : enable +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#endif //MULTIVIEW + layout(push_constant, std430) uniform Params { vec4 section; vec2 pixel_size; @@ -52,12 +76,25 @@ layout(push_constant, std430) uniform Params { } params; +#ifdef MULTIVIEW +layout(location = 0) in vec3 uv_interp; +#else layout(location = 0) in vec2 uv_interp; +#endif +#ifdef MULTIVIEW +layout(set = 0, binding = 0) uniform sampler2DArray source_color; +#ifdef MODE_TWO_SOURCES +layout(set = 1, binding = 0) uniform sampler2DArray source_depth; +layout(location = 1) out float depth; +#endif /* MODE_TWO_SOURCES */ +#else layout(set = 0, binding = 0) uniform sampler2D source_color; #ifdef MODE_TWO_SOURCES layout(set = 1, binding = 0) uniform sampler2D source_color2; -#endif +#endif /* MODE_TWO_SOURCES */ +#endif /* MULTIVIEW */ + layout(location = 0) out vec4 frag_color; vec3 linear_to_srgb(vec3 color) { @@ -68,9 +105,14 @@ vec3 linear_to_srgb(vec3 color) { } void main() { +#ifdef MULTIVIEW + vec3 uv = uv_interp; +#else vec2 uv = uv_interp; +#endif #ifdef MODE_PANORAMA_TO_DP + // Note, multiview and panorama should not be mixed at this time //obtain normal from dual paraboloid uv #define M_PI 3.14159265359 @@ -98,10 +140,20 @@ void main() { uv = 1.0 - uv; } #endif + +#ifdef MULTIVIEW + vec4 color = textureLod(source_color, uv, 0.0); +#ifdef MODE_TWO_SOURCES + // In multiview our 2nd input will be our depth map + depth = textureLod(source_depth, uv, 0.0).r; +#endif /* MODE_TWO_SOURCES */ + +#else vec4 color = textureLod(source_color, uv, 0.0); #ifdef MODE_TWO_SOURCES color += textureLod(source_color2, uv, 0.0); -#endif +#endif /* MODE_TWO_SOURCES */ +#endif /* MULTIVIEW */ if (params.force_luminance) { color.rgb = vec3(max(max(color.r, color.g), color.b)); } diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 52787bb204..61c8488a05 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -76,10 +76,6 @@ struct DirectionalLightData { highp mat4 shadow_matrix2; highp mat4 shadow_matrix3; highp mat4 shadow_matrix4; - mediump vec4 shadow_color1; - mediump vec4 shadow_color2; - mediump vec4 shadow_color3; - mediump vec4 shadow_color4; highp vec2 uv_scale1; highp vec2 uv_scale2; highp vec2 uv_scale3; diff --git a/servers/rendering/renderer_rd/shaders/particles_copy.glsl b/servers/rendering/renderer_rd/shaders/particles_copy.glsl index b991880cd9..afbd5a9caa 100644 --- a/servers/rendering/renderer_rd/shaders/particles_copy.glsl +++ b/servers/rendering/renderer_rd/shaders/particles_copy.glsl @@ -61,6 +61,8 @@ layout(push_constant, std430) uniform Params { uint lifetime_split; bool lifetime_reverse; bool copy_mode_2d; + + mat4 inv_emission_transform; } params; @@ -199,6 +201,12 @@ void main() { txform = txform * trail_bind_poses.data[part_ofs]; } + if (params.copy_mode_2d) { + // In global mode, bring 2D particles to local coordinates + // as they will be drawn with the node position as origin. + txform = params.inv_emission_transform * txform; + } + txform = transpose(txform); } else { txform = mat4(vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)); //zero scale, becomes invisible diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 5d65b00bee..f9cee011d2 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -99,6 +99,18 @@ layout(location = 8) out float dp_clip; layout(location = 9) out flat uint instance_index_interp; +#ifdef USE_MULTIVIEW +#ifdef has_VK_KHR_multiview +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +// !BAS! This needs to become an input once we implement our fallback! +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#else // USE_MULTIVIEW +// Set to zero, not supported in non stereo +#define ViewIndex 0 +#endif //USE_MULTIVIEW + invariant gl_Position; #GLOBALS @@ -244,7 +256,13 @@ void main() { vec4 position; #endif +#ifdef USE_MULTIVIEW + mat4 projection_matrix = scene_data.projection_matrix_view[ViewIndex]; + mat4 inv_projection_matrix = scene_data.inv_projection_matrix_view[ViewIndex]; +#else mat4 projection_matrix = scene_data.projection_matrix; + mat4 inv_projection_matrix = scene_data.inv_projection_matrix; +#endif //USE_MULTIVIEW //using world coordinates #if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) @@ -421,10 +439,26 @@ layout(location = 8) in float dp_clip; layout(location = 9) in flat uint instance_index_interp; +#ifdef USE_MULTIVIEW +#ifdef has_VK_KHR_multiview +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +// !BAS! This needs to become an input once we implement our fallback! +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#else // USE_MULTIVIEW +// Set to zero, not supported in non stereo +#define ViewIndex 0 +#endif //USE_MULTIVIEW + //defines to keep compatibility with vertex #define world_matrix instances.data[instance_index].transform +#ifdef USE_MULTIVIEW +#define projection_matrix scene_data.projection_matrix_view[ViewIndex] +#else #define projection_matrix scene_data.projection_matrix +#endif #if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE) //both required for transmittance to be enabled @@ -478,8 +512,8 @@ layout(location = 0) out vec4 frag_color; #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) -/* Make a default specular mode SPECULAR_SCHLICK_GGX. */ -#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) && !defined(SPECULAR_PHONG) && !defined(SPECULAR_TOON) +// Default to SPECULAR_SCHLICK_GGX. +#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) #define SPECULAR_SCHLICK_GGX #endif @@ -589,7 +623,7 @@ void main() { float rim = 0.0; float rim_tint = 0.0; float clearcoat = 0.0; - float clearcoat_gloss = 0.0; + float clearcoat_roughness = 0.0; float anisotropy = 0.0; vec2 anisotropy_flow = vec2(1.0, 0.0); vec4 fog = vec4(0.0); @@ -912,7 +946,17 @@ void main() { #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) if (scene_data.use_reflection_cubemap) { +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); + vec3 ref_vec = reflect(-view, bent_normal); +#else vec3 ref_vec = reflect(-view, normal); +#endif + float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; #ifdef USE_RADIANCE_CUBEMAP_ARRAY @@ -954,6 +998,36 @@ void main() { #if defined(CUSTOM_IRRADIANCE_USED) ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); #endif + +#ifdef LIGHT_CLEARCOAT_USED + + if (scene_data.use_reflection_cubemap) { + vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map + float NoV = max(dot(n, view), 0.0001); + vec3 ref_vec = reflect(-view, n); + // The clear coat layer assumes an IOR of 1.5 (4% reflectance) + float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV)); + float attenuation = 1.0 - Fc; + ambient_light *= attenuation; + specular_light *= attenuation; + + float horizon = min(1.0 + dot(ref_vec, normal), 1.0); + ref_vec = scene_data.radiance_inverse_xform * ref_vec; + float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; +#ifdef USE_RADIANCE_CUBEMAP_ARRAY + + float lod, blend; + blend = modf(roughness_lod, lod); + vec3 clearcoat_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb; + clearcoat_light = mix(clearcoat_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend); + +#else + vec3 clearcoat_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness_lod).rgb; + +#endif //USE_RADIANCE_CUBEMAP_ARRAY + specular_light += clearcoat_light * horizon * horizon * Fc * scene_data.ambient_light_color_energy.a; + } +#endif #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) //radiance @@ -1202,8 +1276,16 @@ void main() { if (!bool(reflections.data[reflection_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } - - reflection_process(reflection_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); +#else + vec3 bent_normal = normal; +#endif + reflection_process(reflection_index, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } } @@ -1555,10 +1637,11 @@ void main() { rim, rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - binormal, tangent, anisotropy, + binormal, + tangent, anisotropy, #endif diffuse_light, specular_light); @@ -1626,7 +1709,7 @@ void main() { rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED tangent, binormal, anisotropy, @@ -1698,10 +1781,11 @@ void main() { rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, + binormal, anisotropy, #endif diffuse_light, specular_light); } @@ -1904,7 +1988,7 @@ void main() { frag_color = vec4(albedo, alpha); #else frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha); - //frag_color = vec4(1.0); +//frag_color = vec4(1.0); #endif //USE_NO_SHADING // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl index 084e2a0673..2e31503669 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl @@ -2,6 +2,7 @@ #define ROUGHNESS_MAX_LOD 5 #define MAX_VOXEL_GI_INSTANCES 8 +#define MAX_VIEWS 2 #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) @@ -12,10 +13,14 @@ #endif +#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview) +#extension GL_EXT_multiview : enable +#endif + #include "cluster_data_inc.glsl" #include "decal_data_inc.glsl" -#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) +#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) #ifndef NORMAL_USED #define NORMAL_USED #endif @@ -169,10 +174,13 @@ sdfgi; layout(set = 1, binding = 0, std140) uniform SceneData { mat4 projection_matrix; mat4 inv_projection_matrix; - mat4 camera_matrix; mat4 inv_camera_matrix; + // only used for multiview + mat4 projection_matrix_view[MAX_VIEWS]; + mat4 inv_projection_matrix_view[MAX_VIEWS]; + vec2 viewport_size; vec2 screen_pixel_size; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 16f77fb91a..bd1c2b5758 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -1,55 +1,29 @@ // Functions related to lighting -// This returns the G_GGX function divided by 2 cos_theta_m, where in practice cos_theta_m is either N.L or N.V. -// We're dividing this factor off because the overall term we'll end up looks like -// (see, for example, the first unnumbered equation in B. Burley, "Physically Based Shading at Disney", SIGGRAPH 2012): -// -// F(L.V) D(N.H) G(N.L) G(N.V) / (4 N.L N.V) -// -// We're basically regouping this as -// -// F(L.V) D(N.H) [G(N.L)/(2 N.L)] [G(N.V) / (2 N.V)] -// -// and thus, this function implements the [G(N.m)/(2 N.m)] part with m = L or V. -// -// The contents of the D and G (G1) functions (GGX) are taken from -// E. Heitz, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", J. Comp. Graph. Tech. 3 (2) (2014). -// Eqns 71-72 and 85-86 (see also Eqns 43 and 80). - -float G_GGX_2cos(float cos_theta_m, float alpha) { - // Schlick's approximation - // C. Schlick, "An Inexpensive BRDF Model for Physically-based Rendering", Computer Graphics Forum. 13 (3): 233 (1994) - // Eq. (19), although see Heitz (2014) the about the problems with his derivation. - // It nevertheless approximates GGX well with k = alpha/2. - float k = 0.5 * alpha; - return 0.5 / (cos_theta_m * (1.0 - k) + k); - - // float cos2 = cos_theta_m * cos_theta_m; - // float sin2 = (1.0 - cos2); - // return 1.0 / (cos_theta_m + sqrt(cos2 + alpha * alpha * sin2)); -} - float D_GGX(float cos_theta_m, float alpha) { - float alpha2 = alpha * alpha; - float d = 1.0 + (alpha2 - 1.0) * cos_theta_m * cos_theta_m; - return alpha2 / (M_PI * d * d); + float a = cos_theta_m * alpha; + float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); + return k * k * (1.0 / M_PI); } -float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { - float cos2 = cos_theta_m * cos_theta_m; - float sin2 = (1.0 - cos2); - float s_x = alpha_x * cos_phi; - float s_y = alpha_y * sin_phi; - return 1.0 / max(cos_theta_m + sqrt(cos2 + (s_x * s_x + s_y * s_y) * sin2), 0.001); +// From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX +float V_GGX(float NdotL, float NdotV, float alpha) { + return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, alpha); } float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { - float cos2 = cos_theta_m * cos_theta_m; - float sin2 = (1.0 - cos2); - float r_x = cos_phi / alpha_x; - float r_y = sin_phi / alpha_y; - float d = cos2 + sin2 * (r_x * r_x + r_y * r_y); - return 1.0 / max(M_PI * alpha_x * alpha_y * d * d, 0.001); + float alpha2 = alpha_x * alpha_y; + highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * cos_theta_m); + highp float v2 = dot(v, v); + float w2 = alpha2 / v2; + float D = alpha2 * w2 * w2 * (1.0 / M_PI); + return D; +} + +float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) { + float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV)); + float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL)); + return 0.5 / (Lambda_V + Lambda_L); } float SchlickFresnel(float u) { @@ -58,14 +32,6 @@ float SchlickFresnel(float u) { return m2 * m2 * m; // pow(m,5) } -float GTR1(float NdotH, float a) { - if (a >= 1.0) - return 1.0 / M_PI; - float a2 = a * a; - float t = 1.0 + (a2 - 1.0) * NdotH * NdotH; - return (a2 - 1.0) / (M_PI * log(a2) * t); -} - vec3 F0(float metallic, float specular, vec3 albedo) { float dielectric = 0.16 * specular * specular; // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; @@ -87,7 +53,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float rim, float rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - float clearcoat, float clearcoat_gloss, + float clearcoat, float clearcoat_roughness, vec3 vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED vec3 B, vec3 T, float anisotropy, @@ -113,13 +79,13 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float NdotL = min(A + dot(N, L), 1.0); float cNdotL = max(NdotL, 0.0); // clamped NdotL float NdotV = dot(N, V); - float cNdotV = max(NdotV, 0.0); + float cNdotV = max(NdotV, 1e-4); -#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) +#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) vec3 H = normalize(V + L); #endif -#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) +#if defined(SPECULAR_SCHLICK_GGX) float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); #endif @@ -203,26 +169,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte // D -#if defined(SPECULAR_BLINN) - - //normalized blinn - float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; - float blinn = pow(cNdotH, shininess); - blinn *= (shininess + 2.0) * (1.0 / (8.0 * M_PI)); - - specular_light += light_color * attenuation * specular_amount * blinn * f0 * orms_unpacked.w; - -#elif defined(SPECULAR_PHONG) - - vec3 R = normalize(-reflect(L, N)); - float cRdotV = clamp(A + dot(R, V), 0.0, 1.0); - float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; - float phong = pow(cRdotV, shininess); - phong *= (shininess + 1.0) * (1.0 / (8.0 * M_PI)); - - specular_light += light_color * attenuation * specular_amount * phong * f0 * orms_unpacked.w; - -#elif defined(SPECULAR_TOON) +#if defined(SPECULAR_TOON) vec3 R = normalize(-reflect(L, N)); float RdotV = dot(R, V); @@ -236,24 +183,21 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #elif defined(SPECULAR_SCHLICK_GGX) // shlick+ggx as default - + float alpha_ggx = roughness * roughness; #if defined(LIGHT_ANISOTROPY_USED) - float alpha_ggx = roughness * roughness; float aspect = sqrt(1.0 - anisotropy * 0.9); float ax = alpha_ggx / aspect; float ay = alpha_ggx * aspect; float XdotH = dot(T, H); float YdotH = dot(B, H); float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); - float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH); - -#else - float alpha_ggx = roughness * roughness; + float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); +#else // LIGHT_ANISOTROPY_USED float D = D_GGX(cNdotH, alpha_ggx); - float G = G_GGX_2cos(cNdotL, alpha_ggx) * G_GGX_2cos(cNdotV, alpha_ggx); -#endif - // F + float G = V_GGX(cNdotL, cNdotV, alpha_ggx); +#endif // LIGHT_ANISOTROPY_USED + // F float cLdotH5 = SchlickFresnel(cLdotH); vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0); @@ -263,18 +207,23 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #endif #if defined(LIGHT_CLEARCOAT_USED) + // Clearcoat ignores normal_map, use vertex normal instead + float ccNdotL = max(min(A + dot(vertex_normal, L), 1.0), 0.0); + float ccNdotH = clamp(A + dot(vertex_normal, H), 0.0, 1.0); + float ccNdotV = max(dot(vertex_normal, V), 1e-4); #if !defined(SPECULAR_SCHLICK_GGX) float cLdotH5 = SchlickFresnel(cLdotH); #endif - float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss)); + float Dr = D_GGX(ccNdotH, mix(0.001, 0.1, clearcoat_roughness)); + float Gr = 0.25 / (cLdotH * cLdotH); float Fr = mix(.04, 1.0, cLdotH5); - float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25); - - float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; + float clearcoat_specular_brdf_NL = clearcoat * Gr * Fr * Dr * cNdotL; specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; -#endif + // TODO: Clearcoat adds light to the scene right now (it is non-energy conserving), both diffuse and specular need to be scaled by (1.0 - FR) + // but to do so we need to rearrange this entire function +#endif // LIGHT_CLEARCOAT_USED } #ifdef USE_SHADOW_TO_OPACITY @@ -587,7 +536,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float rim, float rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - float clearcoat, float clearcoat_gloss, + float clearcoat, float clearcoat_roughness, vec3 vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED vec3 binormal, vec3 tangent, float anisotropy, @@ -711,7 +660,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v rim * omni_attenuation, rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, @@ -827,7 +776,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float rim, float rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - float clearcoat, float clearcoat_gloss, + float clearcoat, float clearcoat_roughness, vec3 vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED vec3 binormal, vec3 tangent, float anisotropy, @@ -912,7 +861,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v rim * spot_attenuation, rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 4d6a3b5864..0fcf449659 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -511,8 +511,8 @@ layout(location = 0) out mediump vec4 frag_color; #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) -/* Make a default specular mode SPECULAR_SCHLICK_GGX. */ -#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) && !defined(SPECULAR_PHONG) && !defined(SPECULAR_TOON) +// Default to SPECULAR_SCHLICK_GGX. +#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) #define SPECULAR_SCHLICK_GGX #endif @@ -596,7 +596,7 @@ void main() { float rim = 0.0; float rim_tint = 0.0; float clearcoat = 0.0; - float clearcoat_gloss = 0.0; + float clearcoat_roughness = 0.0; float anisotropy = 0.0; vec2 anisotropy_flow = vec2(1.0, 0.0); vec4 fog = vec4(0.0); @@ -874,7 +874,16 @@ void main() { #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) if (scene_data.use_reflection_cubemap) { +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); + vec3 ref_vec = reflect(-view, bent_normal); +#else vec3 ref_vec = reflect(-view, normal); +#endif float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; #ifdef USE_RADIANCE_CUBEMAP_ARRAY @@ -917,7 +926,35 @@ void main() { #if defined(CUSTOM_IRRADIANCE_USED) ambient_light = mix(specular_light, custom_irradiance.rgb, custom_irradiance.a); #endif // CUSTOM_IRRADIANCE_USED +#ifdef LIGHT_CLEARCOAT_USED + + if (scene_data.use_reflection_cubemap) { + vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map + float NoV = max(dot(n, view), 0.0001); + vec3 ref_vec = reflect(-view, n); + // The clear coat layer assumes an IOR of 1.5 (4% reflectance) + float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV)); + float attenuation = 1.0 - Fc; + ambient_light *= attenuation; + specular_light *= attenuation; + + float horizon = min(1.0 + dot(ref_vec, normal), 1.0); + ref_vec = scene_data.radiance_inverse_xform * ref_vec; + float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; +#ifdef USE_RADIANCE_CUBEMAP_ARRAY + + float lod, blend; + blend = modf(roughness_lod, lod); + vec3 clearcoat_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb; + clearcoat_light = mix(clearcoat_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend); +#else + vec3 clearcoat_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness_lod).rgb; + +#endif //USE_RADIANCE_CUBEMAP_ARRAY + specular_light += clearcoat_light * horizon * horizon * Fc * scene_data.ambient_light_color_energy.a; + } +#endif #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) //radiance @@ -1002,13 +1039,27 @@ void main() { if (reflection_index == 0xFF) { break; } - - reflection_process(reflection_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); +#else + vec3 bent_normal = normal; +#endif + reflection_process(reflection_index, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } if (reflection_accum.a > 0.0) { specular_light = reflection_accum.rgb / reflection_accum.a; } + +#if !defined(USE_LIGHTMAP) + if (ambient_accum.a > 0.0) { + ambient_light = ambient_accum.rgb / ambient_accum.a; + } +#endif } //Reflection probes // finalize ambient light here @@ -1079,7 +1130,6 @@ void main() { float depth_z = -vertex.z; vec4 pssm_coord; - vec3 shadow_color = vec3(0.0); vec3 light_dir = directional_lights.data[i].direction; #define BIAS_FUNC(m_var, m_idx) \ @@ -1105,9 +1155,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color1.rgb; - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); @@ -1125,8 +1172,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color2.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); @@ -1144,9 +1189,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color3.rgb; - } else { vec4 v = vec4(vertex, 1.0); @@ -1164,12 +1206,9 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color4.rgb; } if (directional_lights.data[i].blend_splits) { - vec3 shadow_color_blend = vec3(0.0); float pssm_blend; float shadow2; @@ -1190,7 +1229,6 @@ void main() { } pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); - shadow_color_blend = directional_lights.data[i].shadow_color2.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 2) @@ -1208,8 +1246,6 @@ void main() { } pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); - - shadow_color_blend = directional_lights.data[i].shadow_color3.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 3) @@ -1226,7 +1262,6 @@ void main() { } pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); - shadow_color_blend = directional_lights.data[i].shadow_color4.rgb; } else { pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) } @@ -1234,7 +1269,6 @@ void main() { pssm_blend = sqrt(pssm_blend); shadow = mix(shadow, shadow2, pssm_blend); - shadow_color = mix(shadow_color, shadow_color_blend, pssm_blend); } shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance @@ -1368,7 +1402,7 @@ void main() { rim, rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, @@ -1415,10 +1449,11 @@ void main() { rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, + binormal, anisotropy, #endif diffuse_light, specular_light); } @@ -1459,10 +1494,11 @@ void main() { rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, + binormal, anisotropy, #endif diffuse_light, specular_light); } diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl index 541c0b0603..7a624c3b95 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -7,7 +7,7 @@ #include "decal_data_inc.glsl" -#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) +#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) #ifndef NORMAL_USED #define NORMAL_USED #endif diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index 5bda15236c..b95fad650e 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl @@ -70,8 +70,6 @@ struct Light { float cos_spot_angle; float inv_spot_attenuation; float radius; - - vec4 shadow_color; }; layout(set = 0, binding = 9, std140) buffer restrict readonly Lights { diff --git a/servers/rendering/renderer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/sky.glsl index b258e89c66..5b4594da99 100644 --- a/servers/rendering/renderer_rd/shaders/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/sky.glsl @@ -180,12 +180,11 @@ void main() { cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projections[ViewIndex].x)) / params.projections[ViewIndex].y; cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projections[ViewIndex].z)) / params.projections[ViewIndex].w; cube_normal = mat3(params.orientation) * cube_normal; - cube_normal.z = -cube_normal.z; cube_normal = normalize(cube_normal); vec2 uv = uv_interp * 0.5 + 0.5; - vec2 panorama_coords = vec2(atan(cube_normal.x, cube_normal.z), acos(cube_normal.y)); + vec2 panorama_coords = vec2(atan(cube_normal.x, -cube_normal.z), acos(cube_normal.y)); if (panorama_coords.x < 0.0) { panorama_coords.x += M_PI * 2.0; @@ -200,13 +199,11 @@ void main() { vec4 custom_fog = vec4(0.0); #ifdef USE_CUBEMAP_PASS - vec3 inverted_cube_normal = cube_normal; - inverted_cube_normal.z *= -1.0; #ifdef USES_HALF_RES_COLOR - half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier; + half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) * params.luminance_multiplier; #endif #ifdef USES_QUARTER_RES_COLOR - quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier; + quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) * params.luminance_multiplier; #endif #else #ifdef USES_HALF_RES_COLOR diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl index 7a0cea421e..347fd13b28 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl @@ -382,7 +382,6 @@ void main() { float depth_z = -view_pos.z; vec4 pssm_coord; - vec3 shadow_color = directional_lights.data[i].shadow_color1.rgb; vec3 light_dir = directional_lights.data[i].direction; vec4 v = vec4(view_pos, 1.0); float z_range; @@ -413,7 +412,7 @@ void main() { shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance - shadow_attenuation = mix(shadow_color, vec3(1.0), shadow); + shadow_attenuation = mix(vec3(0.0), vec3(1.0), shadow); } total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g); diff --git a/servers/rendering/renderer_rd/storage_rd/SCsub b/servers/rendering/renderer_rd/storage_rd/SCsub new file mode 100644 index 0000000000..86681f9c74 --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.servers_sources, "*.cpp") diff --git a/servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.cpp new file mode 100644 index 0000000000..3299b93ee2 --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.cpp @@ -0,0 +1,235 @@ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ + +#include "canvas_texture_storage.h" +#include "texture_storage.h" + +// Until we move things into their own storage classes, also include our old class +#include "servers/rendering/renderer_rd/renderer_storage_rd.h" + +using namespace RendererRD; + +/////////////////////////////////////////////////////////////////////////// +// CanvasTexture + +void CanvasTexture::clear_sets() { + if (cleared_cache) { + return; + } + for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) { + for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) { + if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j])) { + RD::get_singleton()->free(uniform_sets[i][j]); + uniform_sets[i][j] = RID(); + } + } + } + cleared_cache = true; +} + +CanvasTexture::~CanvasTexture() { + clear_sets(); +} + +/////////////////////////////////////////////////////////////////////////// +// CanvasTextureStorage + +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); + ERR_FAIL_NULL(ct); + + 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; + } + + ct->clear_sets(); +} + +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); + ERR_FAIL_NULL(ct); + + 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; + ct->clear_sets(); +} + +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); + ERR_FAIL_NULL(ct); + + ct->texture_filter = p_filter; + ct->clear_sets(); +} + +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); + ERR_FAIL_NULL(ct); + ct->texture_repeat = p_repeat; + ct->clear_sets(); +} + +bool CanvasTextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) { + RendererStorageRD *storage = RendererStorageRD::base_singleton; + + CanvasTexture *ct = nullptr; + TextureStorage *texture_storage = TextureStorage::get_singleton(); + Texture *t = texture_storage->get_texture(p_texture); + + // TODO once we have our texture storage split off we'll look into moving this code into canvas_texture + + if (t) { + //regular texture + if (!t->canvas_texture) { + t->canvas_texture = memnew(CanvasTexture); + t->canvas_texture->diffuse = p_texture; + } + + ct = t->canvas_texture; + } else { + ct = get_canvas_texture(p_texture); + } + + if (!ct) { + return false; //invalid texture RID + } + + RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter; + ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false); + + RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat; + ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false); + + RID uniform_set = ct->uniform_sets[filter][repeat]; + if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) { + //create and update + Vector<RD::Uniform> uniforms; + { //diffuse + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 0; + + t = texture_storage->get_texture(ct->diffuse); + if (!t) { + u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); + ct->size_cache = Size2i(1, 1); + } else { + u.append_id(t->rd_texture); + ct->size_cache = Size2i(t->width_2d, t->height_2d); + } + uniforms.push_back(u); + } + { //normal + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 1; + + t = texture_storage->get_texture(ct->normal_map); + if (!t) { + u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL)); + ct->use_normal_cache = false; + } else { + u.append_id(t->rd_texture); + ct->use_normal_cache = true; + } + uniforms.push_back(u); + } + { //specular + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 2; + + t = texture_storage->get_texture(ct->specular); + if (!t) { + u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); + ct->use_specular_cache = false; + } else { + u.append_id(t->rd_texture); + ct->use_specular_cache = true; + } + uniforms.push_back(u); + } + { //sampler + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 3; + u.append_id(storage->sampler_rd_get_default(filter, repeat)); + uniforms.push_back(u); + } + + uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set); + ct->uniform_sets[filter][repeat] = uniform_set; + ct->cleared_cache = false; + } + + r_uniform_set = uniform_set; + r_size = ct->size_cache; + r_specular_shininess = ct->specular_color; + r_use_normal = ct->use_normal_cache; + r_use_specular = ct->use_specular_cache; + + return true; +} diff --git a/servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h b/servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h new file mode 100644 index 0000000000..6d3868edd5 --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h @@ -0,0 +1,90 @@ +/*************************************************************************/ +/* 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_RD_H +#define CANVAS_TEXTURE_STORAGE_RD_H + +#include "core/templates/rid_owner.h" +#include "servers/rendering/storage/canvas_texture_storage.h" + +namespace RendererRD { + +class CanvasTexture { +public: + 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; + RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; + + Size2i size_cache = Size2i(1, 1); + bool use_normal_cache = false; + bool use_specular_cache = false; + bool cleared_cache = true; + + void clear_sets(); + ~CanvasTexture(); +}; + +class CanvasTextureStorage : public RendererCanvasTextureStorage { +private: + static CanvasTextureStorage *singleton; + + RID_Owner<RendererRD::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; + + bool canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular); +}; + +} // namespace RendererRD + +#endif // !CANVAS_TEXTURE_STORAGE_RD_H diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp new file mode 100644 index 0000000000..acdaaae7a4 --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -0,0 +1,1420 @@ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ + +#include "texture_storage.h" + +// only include until we have DecalStorage sorted +#include "servers/rendering/renderer_rd/renderer_storage_rd.h" + +using namespace RendererRD; + +/////////////////////////////////////////////////////////////////////////// +// Texture + +void Texture::cleanup() { + if (RD::get_singleton()->texture_is_valid(rd_texture_srgb)) { + //erase this first, as it's a dependency of the one below + RD::get_singleton()->free(rd_texture_srgb); + } + if (RD::get_singleton()->texture_is_valid(rd_texture)) { + RD::get_singleton()->free(rd_texture); + } + if (canvas_texture) { + memdelete(canvas_texture); + } +} + +/////////////////////////////////////////////////////////////////////////// +// TextureStorage + +TextureStorage *TextureStorage::singleton = nullptr; + +TextureStorage *TextureStorage::get_singleton() { + return singleton; +} + +TextureStorage::TextureStorage() { + singleton = this; + + { //create default textures + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = 4; + tformat.height = 4; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.texture_type = RD::TEXTURE_TYPE_2D; + + Vector<uint8_t> pv; + pv.resize(16 * 4); + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 255); + pv.set(i * 4 + 1, 255); + pv.set(i * 4 + 2, 255); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 0); + pv.set(i * 4 + 1, 0); + pv.set(i * 4 + 2, 0); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 128); + pv.set(i * 4 + 1, 128); + pv.set(i * 4 + 2, 255); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_NORMAL] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 255); + pv.set(i * 4 + 1, 128); + pv.set(i * 4 + 2, 255); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_ANISO] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 0); + pv.set(i * 4 + 1, 0); + pv.set(i * 4 + 2, 0); + pv.set(i * 4 + 3, 0); + } + + default_rd_textures[DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER] = RD::get_singleton()->texture_buffer_create(16, RD::DATA_FORMAT_R8G8B8A8_UNORM, pv); + + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 0); + pv.set(i * 4 + 1, 0); + pv.set(i * 4 + 2, 0); + pv.set(i * 4 + 3, 0); + } + + { + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UINT; + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_2D_UINT] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + } + + { //create default cubemap + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = 4; + tformat.height = 4; + tformat.array_layers = 6; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.texture_type = RD::TEXTURE_TYPE_CUBE_ARRAY; + + Vector<uint8_t> pv; + pv.resize(16 * 4); + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 0); + pv.set(i * 4 + 1, 0); + pv.set(i * 4 + 2, 0); + pv.set(i * 4 + 3, 0); + } + + { + Vector<Vector<uint8_t>> vpv; + for (int i = 0; i < 6; i++) { + vpv.push_back(pv); + } + default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + } + + { //create default cubemap array + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = 4; + tformat.height = 4; + tformat.array_layers = 6; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.texture_type = RD::TEXTURE_TYPE_CUBE; + + Vector<uint8_t> pv; + pv.resize(16 * 4); + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 0); + pv.set(i * 4 + 1, 0); + pv.set(i * 4 + 2, 0); + pv.set(i * 4 + 3, 0); + } + + { + Vector<Vector<uint8_t>> vpv; + for (int i = 0; i < 6; i++) { + vpv.push_back(pv); + } + default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + } + + { //create default cubemap white array + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = 4; + tformat.height = 4; + tformat.array_layers = 6; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.texture_type = RD::TEXTURE_TYPE_CUBE; + + Vector<uint8_t> pv; + pv.resize(16 * 4); + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 255); + pv.set(i * 4 + 1, 255); + pv.set(i * 4 + 2, 255); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + for (int i = 0; i < 6; i++) { + vpv.push_back(pv); + } + default_rd_textures[DEFAULT_RD_TEXTURE_CUBEMAP_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + } + + { //create default 3D + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = 4; + tformat.height = 4; + tformat.depth = 4; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.texture_type = RD::TEXTURE_TYPE_3D; + + Vector<uint8_t> pv; + pv.resize(64 * 4); + for (int i = 0; i < 64; i++) { + pv.set(i * 4 + 0, 0); + pv.set(i * 4 + 1, 0); + pv.set(i * 4 + 2, 0); + pv.set(i * 4 + 3, 0); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_3D_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + for (int i = 0; i < 64; i++) { + pv.set(i * 4 + 0, 255); + pv.set(i * 4 + 1, 255); + pv.set(i * 4 + 2, 255); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_3D_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + } + + { //create default array + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = 4; + tformat.height = 4; + tformat.array_layers = 1; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + + Vector<uint8_t> pv; + pv.resize(16 * 4); + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 255); + pv.set(i * 4 + 1, 255); + pv.set(i * 4 + 2, 255); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + } +} + +TextureStorage::~TextureStorage() { + singleton = nullptr; + + //def textures + for (int i = 0; i < DEFAULT_RD_TEXTURE_MAX; i++) { + texture_free(default_rd_textures[i]); + } +} + +bool TextureStorage::can_create_resources_async() const { + return true; +} + +RID TextureStorage::texture_allocate() { + return texture_owner.allocate_rid(); +} + +void TextureStorage::texture_free(RID p_texture) { + Texture *t = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!t); + ERR_FAIL_COND(t->is_render_target); + + t->cleanup(); + + if (t->is_proxy && t->proxy_to.is_valid()) { + Texture *proxy_to = texture_owner.get_or_null(t->proxy_to); + if (proxy_to) { + proxy_to->proxies.erase(p_texture); + } + } + + RendererStorageRD::base_singleton->decal_atlas_remove_texture(p_texture); + + for (int i = 0; i < t->proxies.size(); i++) { + Texture *p = texture_owner.get_or_null(t->proxies[i]); + ERR_CONTINUE(!p); + p->proxy_to = RID(); + p->rd_texture = RID(); + p->rd_texture_srgb = RID(); + } + + texture_owner.free(p_texture); +} + +void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) { + TextureToRDFormat ret_format; + Ref<Image> image = _validate_texture_format(p_image, ret_format); + + Texture texture; + + texture.type = Texture::TYPE_2D; + + texture.width = p_image->get_width(); + texture.height = p_image->get_height(); + texture.layers = 1; + texture.mipmaps = p_image->get_mipmap_count() + 1; + texture.depth = 1; + texture.format = p_image->get_format(); + texture.validated_format = image->get_format(); + + texture.rd_type = RD::TEXTURE_TYPE_2D; + texture.rd_format = ret_format.format; + texture.rd_format_srgb = ret_format.format_srgb; + + RD::TextureFormat rd_format; + RD::TextureView rd_view; + { //attempt register + rd_format.format = texture.rd_format; + rd_format.width = texture.width; + rd_format.height = texture.height; + rd_format.depth = 1; + rd_format.array_layers = 1; + rd_format.mipmaps = texture.mipmaps; + rd_format.texture_type = texture.rd_type; + rd_format.samples = RD::TEXTURE_SAMPLES_1; + rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_format.shareable_formats.push_back(texture.rd_format); + rd_format.shareable_formats.push_back(texture.rd_format_srgb); + } + } + { + rd_view.swizzle_r = ret_format.swizzle_r; + rd_view.swizzle_g = ret_format.swizzle_g; + rd_view.swizzle_b = ret_format.swizzle_b; + rd_view.swizzle_a = ret_format.swizzle_a; + } + Vector<uint8_t> data = image->get_data(); //use image data + Vector<Vector<uint8_t>> data_slices; + data_slices.push_back(data); + texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); + ERR_FAIL_COND(texture.rd_texture.is_null()); + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_view.format_override = texture.rd_format_srgb; + texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); + if (texture.rd_texture_srgb.is_null()) { + RD::get_singleton()->free(texture.rd_texture); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); + } + } + + //used for 2D, overridable + texture.width_2d = texture.width; + texture.height_2d = texture.height; + texture.is_render_target = false; + texture.rd_view = rd_view; + texture.is_proxy = false; + + texture_owner.initialize_rid(p_texture, texture); +} + +void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { + ERR_FAIL_COND(p_layers.size() == 0); + + ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6); + ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0)); + + TextureToRDFormat ret_format; + Vector<Ref<Image>> images; + { + int valid_width = 0; + int valid_height = 0; + bool valid_mipmaps = false; + Image::Format valid_format = Image::FORMAT_MAX; + + for (int i = 0; i < p_layers.size(); i++) { + ERR_FAIL_COND(p_layers[i]->is_empty()); + + if (i == 0) { + valid_width = p_layers[i]->get_width(); + valid_height = p_layers[i]->get_height(); + valid_format = p_layers[i]->get_format(); + valid_mipmaps = p_layers[i]->has_mipmaps(); + } else { + ERR_FAIL_COND(p_layers[i]->get_width() != valid_width); + ERR_FAIL_COND(p_layers[i]->get_height() != valid_height); + ERR_FAIL_COND(p_layers[i]->get_format() != valid_format); + ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps); + } + + images.push_back(_validate_texture_format(p_layers[i], ret_format)); + } + } + + Texture texture; + + texture.type = Texture::TYPE_LAYERED; + texture.layered_type = p_layered_type; + + texture.width = p_layers[0]->get_width(); + texture.height = p_layers[0]->get_height(); + texture.layers = p_layers.size(); + texture.mipmaps = p_layers[0]->get_mipmap_count() + 1; + texture.depth = 1; + texture.format = p_layers[0]->get_format(); + texture.validated_format = images[0]->get_format(); + + switch (p_layered_type) { + case RS::TEXTURE_LAYERED_2D_ARRAY: { + texture.rd_type = RD::TEXTURE_TYPE_2D_ARRAY; + } break; + case RS::TEXTURE_LAYERED_CUBEMAP: { + texture.rd_type = RD::TEXTURE_TYPE_CUBE; + } break; + case RS::TEXTURE_LAYERED_CUBEMAP_ARRAY: { + texture.rd_type = RD::TEXTURE_TYPE_CUBE_ARRAY; + } break; + } + + texture.rd_format = ret_format.format; + texture.rd_format_srgb = ret_format.format_srgb; + + RD::TextureFormat rd_format; + RD::TextureView rd_view; + { //attempt register + rd_format.format = texture.rd_format; + rd_format.width = texture.width; + rd_format.height = texture.height; + rd_format.depth = 1; + rd_format.array_layers = texture.layers; + rd_format.mipmaps = texture.mipmaps; + rd_format.texture_type = texture.rd_type; + rd_format.samples = RD::TEXTURE_SAMPLES_1; + rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_format.shareable_formats.push_back(texture.rd_format); + rd_format.shareable_formats.push_back(texture.rd_format_srgb); + } + } + { + rd_view.swizzle_r = ret_format.swizzle_r; + rd_view.swizzle_g = ret_format.swizzle_g; + rd_view.swizzle_b = ret_format.swizzle_b; + rd_view.swizzle_a = ret_format.swizzle_a; + } + Vector<Vector<uint8_t>> data_slices; + for (int i = 0; i < images.size(); i++) { + Vector<uint8_t> data = images[i]->get_data(); //use image data + data_slices.push_back(data); + } + texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); + ERR_FAIL_COND(texture.rd_texture.is_null()); + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_view.format_override = texture.rd_format_srgb; + texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); + if (texture.rd_texture_srgb.is_null()) { + RD::get_singleton()->free(texture.rd_texture); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); + } + } + + //used for 2D, overridable + texture.width_2d = texture.width; + texture.height_2d = texture.height; + texture.is_render_target = false; + texture.rd_view = rd_view; + texture.is_proxy = false; + + texture_owner.initialize_rid(p_texture, texture); +} + +void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { + ERR_FAIL_COND(p_data.size() == 0); + + Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); + if (verr != Image::VALIDATE_3D_OK) { + ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr)); + } + + TextureToRDFormat ret_format; + Image::Format validated_format = Image::FORMAT_MAX; + Vector<uint8_t> all_data; + uint32_t mipmap_count = 0; + Vector<Texture::BufferSlice3D> slices; + { + Vector<Ref<Image>> images; + uint32_t all_data_size = 0; + images.resize(p_data.size()); + for (int i = 0; i < p_data.size(); i++) { + TextureToRDFormat f; + images.write[i] = _validate_texture_format(p_data[i], f); + if (i == 0) { + ret_format = f; + validated_format = images[0]->get_format(); + } + + all_data_size += images[i]->get_data().size(); + } + + all_data.resize(all_data_size); //consolidate all data here + uint32_t offset = 0; + Size2i prev_size; + for (int i = 0; i < p_data.size(); i++) { + uint32_t s = images[i]->get_data().size(); + + memcpy(&all_data.write[offset], images[i]->get_data().ptr(), s); + { + Texture::BufferSlice3D slice; + slice.size.width = images[i]->get_width(); + slice.size.height = images[i]->get_height(); + slice.offset = offset; + slice.buffer_size = s; + slices.push_back(slice); + } + offset += s; + + Size2i img_size(images[i]->get_width(), images[i]->get_height()); + if (img_size != prev_size) { + mipmap_count++; + } + prev_size = img_size; + } + } + + Texture texture; + + texture.type = Texture::TYPE_3D; + texture.width = p_width; + texture.height = p_height; + texture.depth = p_depth; + texture.mipmaps = mipmap_count; + texture.format = p_data[0]->get_format(); + texture.validated_format = validated_format; + + texture.buffer_size_3d = all_data.size(); + texture.buffer_slices_3d = slices; + + texture.rd_type = RD::TEXTURE_TYPE_3D; + texture.rd_format = ret_format.format; + texture.rd_format_srgb = ret_format.format_srgb; + + RD::TextureFormat rd_format; + RD::TextureView rd_view; + { //attempt register + rd_format.format = texture.rd_format; + rd_format.width = texture.width; + rd_format.height = texture.height; + rd_format.depth = texture.depth; + rd_format.array_layers = 1; + rd_format.mipmaps = texture.mipmaps; + rd_format.texture_type = texture.rd_type; + rd_format.samples = RD::TEXTURE_SAMPLES_1; + rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_format.shareable_formats.push_back(texture.rd_format); + rd_format.shareable_formats.push_back(texture.rd_format_srgb); + } + } + { + rd_view.swizzle_r = ret_format.swizzle_r; + rd_view.swizzle_g = ret_format.swizzle_g; + rd_view.swizzle_b = ret_format.swizzle_b; + rd_view.swizzle_a = ret_format.swizzle_a; + } + Vector<Vector<uint8_t>> data_slices; + data_slices.push_back(all_data); //one slice + + texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); + ERR_FAIL_COND(texture.rd_texture.is_null()); + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_view.format_override = texture.rd_format_srgb; + texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); + if (texture.rd_texture_srgb.is_null()) { + RD::get_singleton()->free(texture.rd_texture); + ERR_FAIL_COND(texture.rd_texture_srgb.is_null()); + } + } + + //used for 2D, overridable + texture.width_2d = texture.width; + texture.height_2d = texture.height; + texture.is_render_target = false; + texture.rd_view = rd_view; + texture.is_proxy = false; + + texture_owner.initialize_rid(p_texture, texture); +} + +void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) { + Texture *tex = texture_owner.get_or_null(p_base); + ERR_FAIL_COND(!tex); + Texture proxy_tex = *tex; + + proxy_tex.rd_view.format_override = tex->rd_format; + proxy_tex.rd_texture = RD::get_singleton()->texture_create_shared(proxy_tex.rd_view, tex->rd_texture); + if (proxy_tex.rd_texture_srgb.is_valid()) { + proxy_tex.rd_view.format_override = tex->rd_format_srgb; + proxy_tex.rd_texture_srgb = RD::get_singleton()->texture_create_shared(proxy_tex.rd_view, tex->rd_texture); + } + proxy_tex.proxy_to = p_base; + proxy_tex.is_render_target = false; + proxy_tex.is_proxy = true; + proxy_tex.proxies.clear(); + + texture_owner.initialize_rid(p_texture, proxy_tex); + + tex->proxies.push_back(p_texture); +} + +void TextureStorage::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { + ERR_FAIL_COND(p_image.is_null() || p_image->is_empty()); + + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + ERR_FAIL_COND(tex->is_render_target); + ERR_FAIL_COND(p_image->get_width() != tex->width || p_image->get_height() != tex->height); + ERR_FAIL_COND(p_image->get_format() != tex->format); + + if (tex->type == Texture::TYPE_LAYERED) { + ERR_FAIL_INDEX(p_layer, tex->layers); + } + +#ifdef TOOLS_ENABLED + tex->image_cache_2d.unref(); +#endif + TextureToRDFormat f; + Ref<Image> validated = _validate_texture_format(p_image, f); + + RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data()); +} + +void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) { + _texture_2d_update(p_texture, p_image, p_layer, false); +} + +void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + ERR_FAIL_COND(tex->type != Texture::TYPE_3D); + + Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data); + if (verr != Image::VALIDATE_3D_OK) { + ERR_FAIL_MSG(Image::get_3d_image_validation_error_text(verr)); + } + + Vector<uint8_t> all_data; + { + Vector<Ref<Image>> images; + uint32_t all_data_size = 0; + images.resize(p_data.size()); + for (int i = 0; i < p_data.size(); i++) { + Ref<Image> image = p_data[i]; + if (image->get_format() != tex->validated_format) { + image = image->duplicate(); + image->convert(tex->validated_format); + } + all_data_size += images[i]->get_data().size(); + images.push_back(image); + } + + all_data.resize(all_data_size); //consolidate all data here + uint32_t offset = 0; + + for (int i = 0; i < p_data.size(); i++) { + uint32_t s = images[i]->get_data().size(); + memcpy(&all_data.write[offset], images[i]->get_data().ptr(), s); + offset += s; + } + } + + RD::get_singleton()->texture_update(tex->rd_texture, 0, all_data); +} + +void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + ERR_FAIL_COND(!tex->is_proxy); + Texture *proxy_to = texture_owner.get_or_null(p_proxy_to); + ERR_FAIL_COND(!proxy_to); + ERR_FAIL_COND(proxy_to->is_proxy); + + if (tex->proxy_to.is_valid()) { + //unlink proxy + if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) { + RD::get_singleton()->free(tex->rd_texture); + tex->rd_texture = RID(); + } + if (RD::get_singleton()->texture_is_valid(tex->rd_texture_srgb)) { + RD::get_singleton()->free(tex->rd_texture_srgb); + tex->rd_texture_srgb = RID(); + } + Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to); + ERR_FAIL_COND(!prev_tex); + prev_tex->proxies.erase(p_texture); + } + + *tex = *proxy_to; + + tex->proxy_to = p_proxy_to; + tex->is_render_target = false; + tex->is_proxy = true; + tex->proxies.clear(); + proxy_to->proxies.push_back(p_texture); + + tex->rd_view.format_override = tex->rd_format; + tex->rd_texture = RD::get_singleton()->texture_create_shared(tex->rd_view, proxy_to->rd_texture); + if (tex->rd_texture_srgb.is_valid()) { + tex->rd_view.format_override = tex->rd_format_srgb; + tex->rd_texture_srgb = RD::get_singleton()->texture_create_shared(tex->rd_view, proxy_to->rd_texture); + } +} + +//these two APIs can be used together or in combination with the others. +void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) { + //this could be better optimized to reuse an existing image , done this way + //for now to get it working + Ref<Image> image; + image.instantiate(); + image->create(4, 4, false, Image::FORMAT_RGBA8); + image->fill(Color(1, 0, 1, 1)); + + texture_2d_initialize(p_texture, image); +} + +void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) { + //this could be better optimized to reuse an existing image , done this way + //for now to get it working + Ref<Image> image; + image.instantiate(); + image->create(4, 4, false, Image::FORMAT_RGBA8); + image->fill(Color(1, 0, 1, 1)); + + Vector<Ref<Image>> images; + if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) { + images.push_back(image); + } else { + //cube + for (int i = 0; i < 6; i++) { + images.push_back(image); + } + } + + texture_2d_layered_initialize(p_texture, images, p_layered_type); +} + +void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) { + //this could be better optimized to reuse an existing image , done this way + //for now to get it working + Ref<Image> image; + image.instantiate(); + image->create(4, 4, false, Image::FORMAT_RGBA8); + image->fill(Color(1, 0, 1, 1)); + + Vector<Ref<Image>> images; + //cube + for (int i = 0; i < 4; i++) { + images.push_back(image); + } + + texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, images); +} + +Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND_V(!tex, Ref<Image>()); + +#ifdef TOOLS_ENABLED + if (tex->image_cache_2d.is_valid() && !tex->is_render_target) { + return tex->image_cache_2d; + } +#endif + Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0); + ERR_FAIL_COND_V(data.size() == 0, Ref<Image>()); + Ref<Image> image; + image.instantiate(); + image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); + ERR_FAIL_COND_V(image->is_empty(), Ref<Image>()); + if (tex->format != tex->validated_format) { + image->convert(tex->format); + } + +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint() && !tex->is_render_target) { + tex->image_cache_2d = image; + } +#endif + + return image; +} + +Ref<Image> TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) const { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND_V(!tex, Ref<Image>()); + + Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, p_layer); + ERR_FAIL_COND_V(data.size() == 0, Ref<Image>()); + Ref<Image> image; + image.instantiate(); + image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data); + ERR_FAIL_COND_V(image->is_empty(), Ref<Image>()); + if (tex->format != tex->validated_format) { + image->convert(tex->format); + } + + return image; +} + +Vector<Ref<Image>> TextureStorage::texture_3d_get(RID p_texture) const { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND_V(!tex, Vector<Ref<Image>>()); + ERR_FAIL_COND_V(tex->type != Texture::TYPE_3D, Vector<Ref<Image>>()); + + Vector<uint8_t> all_data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0); + + ERR_FAIL_COND_V(all_data.size() != (int)tex->buffer_size_3d, Vector<Ref<Image>>()); + + Vector<Ref<Image>> ret; + + for (int i = 0; i < tex->buffer_slices_3d.size(); i++) { + const Texture::BufferSlice3D &bs = tex->buffer_slices_3d[i]; + ERR_FAIL_COND_V(bs.offset >= (uint32_t)all_data.size(), Vector<Ref<Image>>()); + ERR_FAIL_COND_V(bs.offset + bs.buffer_size > (uint32_t)all_data.size(), Vector<Ref<Image>>()); + Vector<uint8_t> sub_region = all_data.slice(bs.offset, bs.offset + bs.buffer_size); + + Ref<Image> img; + img.instantiate(); + img->create(bs.size.width, bs.size.height, false, tex->validated_format, sub_region); + ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>()); + if (tex->format != tex->validated_format) { + img->convert(tex->format); + } + + ret.push_back(img); + } + + return ret; +} + +void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + ERR_FAIL_COND(tex->proxy_to.is_valid()); //can't replace proxy + Texture *by_tex = texture_owner.get_or_null(p_by_texture); + ERR_FAIL_COND(!by_tex); + ERR_FAIL_COND(by_tex->proxy_to.is_valid()); //can't replace proxy + + if (tex == by_tex) { + return; + } + + if (tex->rd_texture_srgb.is_valid()) { + RD::get_singleton()->free(tex->rd_texture_srgb); + } + RD::get_singleton()->free(tex->rd_texture); + + if (tex->canvas_texture) { + memdelete(tex->canvas_texture); + tex->canvas_texture = nullptr; + } + + Vector<RID> proxies_to_update = tex->proxies; + Vector<RID> proxies_to_redirect = by_tex->proxies; + + *tex = *by_tex; + + tex->proxies = proxies_to_update; //restore proxies, so they can be updated + + if (tex->canvas_texture) { + tex->canvas_texture->diffuse = p_texture; //update + } + + for (int i = 0; i < proxies_to_update.size(); i++) { + texture_proxy_update(proxies_to_update[i], p_texture); + } + for (int i = 0; i < proxies_to_redirect.size(); i++) { + texture_proxy_update(proxies_to_redirect[i], p_texture); + } + //delete last, so proxies can be updated + texture_owner.free(p_by_texture); + + RendererStorageRD::base_singleton->decal_atlas_mark_dirty_on_texture(p_texture); +} + +void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + ERR_FAIL_COND(tex->type != Texture::TYPE_2D); + + tex->width_2d = p_width; + tex->height_2d = p_height; +} + +void TextureStorage::texture_set_path(RID p_texture, const String &p_path) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + + tex->path = p_path; +} + +String TextureStorage::texture_get_path(RID p_texture) const { + RendererRD::Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND_V(!tex, String()); + + return tex->path; +} + +void TextureStorage::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + + tex->detect_3d_callback_ud = p_userdata; + tex->detect_3d_callback = p_callback; +} + +void TextureStorage::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + + tex->detect_normal_callback_ud = p_userdata; + tex->detect_normal_callback = p_callback; +} + +void TextureStorage::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + + tex->detect_roughness_callback_ud = p_userdata; + tex->detect_roughness_callback = p_callback; +} + +void TextureStorage::texture_debug_usage(List<RS::TextureInfo> *r_info) { +} + +void TextureStorage::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { +} + +Size2 TextureStorage::texture_size_with_proxy(RID p_proxy) { + return texture_2d_get_size(p_proxy); +} + +Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { + Ref<Image> image = p_image->duplicate(); + + switch (p_image->get_format()) { + case Image::FORMAT_L8: { + r_format.format = RD::DATA_FORMAT_R8_UNORM; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; //luminance + case Image::FORMAT_LA8: { + r_format.format = RD::DATA_FORMAT_R8G8_UNORM; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_G; + } break; //luminance-alpha + case Image::FORMAT_R8: { + r_format.format = RD::DATA_FORMAT_R8_UNORM; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + case Image::FORMAT_RG8: { + r_format.format = RD::DATA_FORMAT_R8G8_UNORM; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + case Image::FORMAT_RGB8: { + //this format is not mandatory for specification, check if supported first + if (false && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT) && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R8G8B8_SRGB, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_R8G8B8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8_SRGB; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + + } break; + case Image::FORMAT_RGBA8: { + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + } break; + case Image::FORMAT_RGBA4444: { + r_format.format = RD::DATA_FORMAT_B4G4R4A4_UNORM_PACK16; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_B; //needs swizzle + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + } break; + case Image::FORMAT_RGB565: { + r_format.format = RD::DATA_FORMAT_B5G6R5_UNORM_PACK16; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + } break; + case Image::FORMAT_RF: { + r_format.format = RD::DATA_FORMAT_R32_SFLOAT; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; //float + case Image::FORMAT_RGF: { + r_format.format = RD::DATA_FORMAT_R32G32_SFLOAT; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + case Image::FORMAT_RGBF: { + //this format is not mandatory for specification, check if supported first + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R32G32B32_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; + image->convert(Image::FORMAT_RGBAF); + } + + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + case Image::FORMAT_RGBAF: { + r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + + } break; + case Image::FORMAT_RH: { + r_format.format = RD::DATA_FORMAT_R16_SFLOAT; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + + } break; //half float + case Image::FORMAT_RGH: { + r_format.format = RD::DATA_FORMAT_R16G16_SFLOAT; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + + } break; + case Image::FORMAT_RGBH: { + //this format is not mandatory for specification, check if supported first + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16B16_SFLOAT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_R16G16B16_SFLOAT; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + image->convert(Image::FORMAT_RGBAH); + } + + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + case Image::FORMAT_RGBAH: { + r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + + } break; + case Image::FORMAT_RGBE9995: { + r_format.format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32; +#ifndef _MSC_VER +#warning TODO need to make a function in Image to swap bits for this +#endif + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_IDENTITY; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_IDENTITY; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_IDENTITY; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_IDENTITY; + } break; + case Image::FORMAT_DXT1: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_BC1_RGB_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + + } break; //s3tc bc1 + case Image::FORMAT_DXT3: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC2_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC2_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_BC2_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + + } break; //bc2 + case Image::FORMAT_DXT5: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC3_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC3_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_BC3_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + } break; //bc3 + case Image::FORMAT_RGTC_R: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC4_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC4_UNORM_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8_UNORM; + image->decompress(); + image->convert(Image::FORMAT_R8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + + } break; + case Image::FORMAT_RGTC_RG: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC5_UNORM_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8_UNORM; + image->decompress(); + image->convert(Image::FORMAT_RG8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + + } break; + case Image::FORMAT_BPTC_RGBA: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC7_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_BC7_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + + } break; //btpc bc7 + case Image::FORMAT_BPTC_RGBF: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC6H_SFLOAT_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + image->decompress(); + image->convert(Image::FORMAT_RGBAH); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; //float bc6h + case Image::FORMAT_BPTC_RGBFU: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC6H_UFLOAT_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + image->decompress(); + image->convert(Image::FORMAT_RGBAH); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; //unsigned float bc6hu + case Image::FORMAT_ETC2_R11: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_EAC_R11_UNORM_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8_UNORM; + image->decompress(); + image->convert(Image::FORMAT_R8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + + } break; //etc2 + case Image::FORMAT_ETC2_R11S: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8_SNORM; + image->decompress(); + image->convert(Image::FORMAT_R8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; //signed: {} break; NOT srgb. + case Image::FORMAT_ETC2_RG11: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_EAC_R11G11_UNORM_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8_UNORM; + image->decompress(); + image->convert(Image::FORMAT_RG8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + case Image::FORMAT_ETC2_RG11S: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_EAC_R11G11_SNORM_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8_SNORM; + image->decompress(); + image->convert(Image::FORMAT_RG8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + case Image::FORMAT_ETC: + case Image::FORMAT_ETC2_RGB8: { + //ETC2 is backwards compatible with ETC1, and all modern platforms support it + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + + } break; + case Image::FORMAT_ETC2_RGBA8: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + } break; + case Image::FORMAT_ETC2_RGB8A1: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; + } break; + case Image::FORMAT_ETC2_RA_AS_RG: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + case Image::FORMAT_DXT5_RA_AS_RG: { + if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC3_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { + r_format.format = RD::DATA_FORMAT_BC3_UNORM_BLOCK; + r_format.format_srgb = RD::DATA_FORMAT_BC3_SRGB_BLOCK; + } else { + //not supported, reconvert + r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB; + image->decompress(); + image->convert(Image::FORMAT_RGBA8); + } + r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; + r_format.swizzle_g = RD::TEXTURE_SWIZZLE_A; + r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO; + r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE; + } break; + + default: { + } + } + + return image; +} diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h new file mode 100644 index 0000000000..5d8d165a08 --- /dev/null +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -0,0 +1,230 @@ +/*************************************************************************/ +/* 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 TEXTURE_STORAGE_RD_H +#define TEXTURE_STORAGE_RD_H + +#include "canvas_texture_storage.h" +#include "core/templates/rid_owner.h" +#include "servers/rendering/storage/texture_storage.h" + +namespace RendererRD { + +enum DefaultRDTexture { + DEFAULT_RD_TEXTURE_WHITE, + DEFAULT_RD_TEXTURE_BLACK, + DEFAULT_RD_TEXTURE_NORMAL, + DEFAULT_RD_TEXTURE_ANISO, + DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER, + DEFAULT_RD_TEXTURE_CUBEMAP_BLACK, + DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK, + DEFAULT_RD_TEXTURE_CUBEMAP_WHITE, + DEFAULT_RD_TEXTURE_3D_WHITE, + DEFAULT_RD_TEXTURE_3D_BLACK, + DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE, + DEFAULT_RD_TEXTURE_2D_UINT, + DEFAULT_RD_TEXTURE_MAX +}; + +class Texture { +public: + enum Type { + TYPE_2D, + TYPE_LAYERED, + TYPE_3D + }; + + Type type; + RS::TextureLayeredType layered_type = RS::TEXTURE_LAYERED_2D_ARRAY; + + RenderingDevice::TextureType rd_type; + RID rd_texture; + RID rd_texture_srgb; + RenderingDevice::DataFormat rd_format; + RenderingDevice::DataFormat rd_format_srgb; + + RD::TextureView rd_view; + + Image::Format format; + Image::Format validated_format; + + int width; + int height; + int depth; + int layers; + int mipmaps; + + int height_2d; + int width_2d; + + struct BufferSlice3D { + Size2i size; + uint32_t offset = 0; + uint32_t buffer_size = 0; + }; + Vector<BufferSlice3D> buffer_slices_3d; + uint32_t buffer_size_3d = 0; + + bool is_render_target; + bool is_proxy; + + Ref<Image> image_cache_2d; + String path; + + RID proxy_to; + Vector<RID> proxies; + + Set<RID> lightmap_users; + + RS::TextureDetectCallback detect_3d_callback = nullptr; + void *detect_3d_callback_ud = nullptr; + + RS::TextureDetectCallback detect_normal_callback = nullptr; + void *detect_normal_callback_ud = nullptr; + + RS::TextureDetectRoughnessCallback detect_roughness_callback = nullptr; + void *detect_roughness_callback_ud = nullptr; + + CanvasTexture *canvas_texture = nullptr; + + void cleanup(); +}; + +class TextureStorage : public RendererTextureStorage { +private: + static TextureStorage *singleton; + + //textures can be created from threads, so this RID_Owner is thread safe + mutable RID_Owner<Texture, true> texture_owner; + + struct TextureToRDFormat { + RD::DataFormat format; + RD::DataFormat format_srgb; + RD::TextureSwizzle swizzle_r; + RD::TextureSwizzle swizzle_g; + RD::TextureSwizzle swizzle_b; + RD::TextureSwizzle swizzle_a; + TextureToRDFormat() { + format = RD::DATA_FORMAT_MAX; + format_srgb = RD::DATA_FORMAT_MAX; + swizzle_r = RD::TEXTURE_SWIZZLE_R; + swizzle_g = RD::TEXTURE_SWIZZLE_G; + swizzle_b = RD::TEXTURE_SWIZZLE_B; + swizzle_a = RD::TEXTURE_SWIZZLE_A; + } + }; + + Ref<Image> _validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format); + void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0, bool p_immediate = false); + +public: + static TextureStorage *get_singleton(); + + RID default_rd_textures[DEFAULT_RD_TEXTURE_MAX]; + + _FORCE_INLINE_ RID texture_rd_get_default(DefaultRDTexture p_texture) { + return default_rd_textures[p_texture]; + } + + TextureStorage(); + virtual ~TextureStorage(); + + 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); }; + + virtual bool can_create_resources_async() const override; + + virtual RID texture_allocate() override; + virtual void texture_free(RID p_rid) override; + + virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) override; + virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) override; + virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override; + virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent + + virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override; + virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override; + virtual void texture_proxy_update(RID p_proxy, RID p_base) override; + + //these two APIs can be used together or in combination with the others. + virtual void texture_2d_placeholder_initialize(RID p_texture) override; + virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) override; + virtual void texture_3d_placeholder_initialize(RID p_texture) override; + + virtual Ref<Image> texture_2d_get(RID p_texture) const override; + virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const override; + virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const override; + + virtual void texture_replace(RID p_texture, RID p_by_texture) override; + virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) override; + + virtual void texture_set_path(RID p_texture, const String &p_path) override; + virtual String texture_get_path(RID p_texture) const override; + + virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override; + virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) override; + virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) override; + + virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) override; + + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override; + + virtual Size2 texture_size_with_proxy(RID p_proxy) override; + + //internal usage + + _FORCE_INLINE_ RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) { + if (p_texture.is_null()) { + return RID(); + } + RendererRD::Texture *tex = texture_owner.get_or_null(p_texture); + + if (!tex) { + return RID(); + } + return (p_srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; + } + + _FORCE_INLINE_ Size2i texture_2d_get_size(RID p_texture) { + if (p_texture.is_null()) { + return Size2i(); + } + RendererRD::Texture *tex = texture_owner.get_or_null(p_texture); + + if (!tex) { + return Size2i(); + } + return Size2i(tex->width_2d, tex->height_2d); + } +}; + +} // namespace RendererRD + +#endif // !_TEXTURE_STORAGE_RD_H diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp b/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp new file mode 100644 index 0000000000..5843b9db24 --- /dev/null +++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp @@ -0,0 +1,64 @@ +/*************************************************************************/ +/* uniform_set_cache_rd.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. */ +/*************************************************************************/ + +#include "uniform_set_cache_rd.h" + +UniformSetCacheRD *UniformSetCacheRD::singleton = nullptr; + +void UniformSetCacheRD::_invalidate(Cache *p_cache) { + if (p_cache->prev) { + p_cache->prev->next = p_cache->next; + } else { + // At begining of table + uint32_t table_idx = p_cache->hash % HASH_TABLE_SIZE; + hash_table[table_idx] = p_cache->next; + } + + if (p_cache->next) { + p_cache->next->prev = p_cache->prev; + } + + cache_allocator.free(p_cache); + cache_instances_used--; +} +void UniformSetCacheRD::_uniform_set_invalidation_callback(void *p_userdata) { + singleton->_invalidate(reinterpret_cast<Cache *>(p_userdata)); +} + +UniformSetCacheRD::UniformSetCacheRD() { + ERR_FAIL_COND(singleton != nullptr); + singleton = this; +} + +UniformSetCacheRD::~UniformSetCacheRD() { + if (cache_instances_used > 0) { + ERR_PRINT("At exit: " + itos(cache_instances_used) + " uniform set cache instance(s) still in use."); + } +} diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.h b/servers/rendering/renderer_rd/uniform_set_cache_rd.h new file mode 100644 index 0000000000..e49cf4dafa --- /dev/null +++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.h @@ -0,0 +1,221 @@ +/*************************************************************************/ +/* uniform_set_cache_rd.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 UNIFORM_SET_CACHE_H +#define UNIFORM_SET_CACHE_H + +#include "core/templates/local_vector.h" +#include "core/templates/paged_allocator.h" +#include "servers/rendering/rendering_device.h" + +class UniformSetCacheRD : public Object { + GDCLASS(UniformSetCacheRD, Object) + + struct Cache { + Cache *prev = nullptr; + Cache *next = nullptr; + uint32_t hash = 0; + RID shader; + uint32_t set = 0; + RID cache; + LocalVector<RD::Uniform> uniforms; + }; + + PagedAllocator<Cache> cache_allocator; + + enum { + HASH_TABLE_SIZE = 16381 // Prime + }; + + Cache *hash_table[HASH_TABLE_SIZE] = {}; + + static _FORCE_INLINE_ uint32_t _hash_uniform(const RD::Uniform &u, uint32_t h) { + h = hash_djb2_one_32(u.uniform_type, h); + h = hash_djb2_one_32(u.binding, h); + uint32_t rsize = u.get_id_count(); + for (uint32_t j = 0; j < rsize; j++) { + h = hash_djb2_one_64(u.get_id(j).get_id(), h); + } + return h; + } + + static _FORCE_INLINE_ bool _compare_uniform(const RD::Uniform &a, const RD::Uniform &b) { + if (a.binding != b.binding) { + return false; + } + if (a.uniform_type != b.uniform_type) { + return false; + } + uint32_t rsize = a.get_id_count(); + if (rsize != b.get_id_count()) { + return false; + } + for (uint32_t j = 0; j < rsize; j++) { + if (a.get_id(j) != b.get_id(j)) { + return false; + } + } + return true; + } + + _FORCE_INLINE_ uint32_t _hash_args(uint32_t h, const RD::Uniform &arg) { + return _hash_uniform(arg, h); + } + + template <typename... Args> + uint32_t _hash_args(uint32_t h, const RD::Uniform &arg, Args... args) { + h = _hash_uniform(arg, h); + return _hash_args(h, args...); + } + + _FORCE_INLINE_ bool _compare_args(uint32_t idx, const LocalVector<RD::Uniform> &uniforms, const RD::Uniform &arg) { + return _compare_uniform(uniforms[idx], arg); + } + + template <typename... Args> + _FORCE_INLINE_ bool _compare_args(uint32_t idx, const LocalVector<RD::Uniform> &uniforms, const RD::Uniform &arg, Args... args) { + if (!_compare_uniform(uniforms[idx], arg)) { + return false; + } + return _compare_args(idx + 1, uniforms, args...); + } + + _FORCE_INLINE_ void _create_args(Vector<RD::Uniform> &uniforms, const RD::Uniform &arg) { + uniforms.push_back(arg); + } + + template <typename... Args> + _FORCE_INLINE_ void _create_args(Vector<RD::Uniform> &uniforms, const RD::Uniform &arg, Args... args) { + uniforms.push_back(arg); + _create_args(uniforms, args...); + } + + static UniformSetCacheRD *singleton; + + uint32_t cache_instances_used = 0; + + void _invalidate(Cache *p_cache); + static void _uniform_set_invalidation_callback(void *p_userdata); + + RID _allocate_from_uniforms(RID p_shader, uint32_t p_set, uint32_t p_hash, uint32_t p_table_idx, const Vector<RD::Uniform> &p_uniforms) { + RID rid = RD::get_singleton()->uniform_set_create(p_uniforms, p_shader, p_set); + ERR_FAIL_COND_V(rid.is_null(), rid); + + Cache *c = cache_allocator.alloc(); + c->hash = p_hash; + c->set = p_set; + c->shader = p_shader; + c->cache = rid; + c->uniforms.resize(p_uniforms.size()); + for (uint32_t i = 0; i < c->uniforms.size(); i++) { + c->uniforms[i] = p_uniforms[i]; + } + c->prev = nullptr; + c->next = hash_table[p_table_idx]; + if (hash_table[p_table_idx]) { + hash_table[p_table_idx]->prev = c; + } + hash_table[p_table_idx] = c; + + RD::get_singleton()->uniform_set_set_invalidation_callback(rid, _uniform_set_invalidation_callback, c); + + cache_instances_used++; + + return rid; + } + +public: + template <typename... Args> + RID get_cache(RID p_shader, uint32_t p_set, Args... args) { + uint32_t h = hash_djb2_one_64(p_shader.get_id()); + h = hash_djb2_one_32(p_set, h); + h = _hash_args(h, args...); + + uint32_t table_idx = h % HASH_TABLE_SIZE; + { + const Cache *c = hash_table[table_idx]; + + while (c) { + if (c->hash == h && c->set == p_set && c->shader == p_shader && _compare_args(0, c->uniforms, args...)) { + return c->cache; + } + c = c->next; + } + } + + // Not in cache, create: + + Vector<RD::Uniform> uniforms; + _create_args(uniforms, args...); + + return _allocate_from_uniforms(p_shader, p_set, h, table_idx, uniforms); + } + + template <typename... Args> + RID get_cache_vec(RID p_shader, uint32_t p_set, const Vector<RD::Uniform> &p_uniforms) { + uint32_t h = hash_djb2_one_64(p_shader.get_id()); + h = hash_djb2_one_32(p_set, h); + for (int i = 0; i < p_uniforms.size(); i++) { + h = _hash_uniform(p_uniforms[i], h); + } + + uint32_t table_idx = h % HASH_TABLE_SIZE; + { + const Cache *c = hash_table[table_idx]; + + while (c) { + if (c->hash == h && c->set == p_set && c->shader == p_shader) { + bool all_ok = true; + for (int i = 0; i < p_uniforms.size(); i++) { + if (!_compare_uniform(p_uniforms[i], c->uniforms[i])) { + all_ok = false; + break; + } + } + + if (all_ok) { + return c->cache; + } + } + c = c->next; + } + } + + // Not in cache, create: + return _allocate_from_uniforms(p_shader, p_set, h, table_idx, p_uniforms); + } + + static UniformSetCacheRD *get_singleton() { return singleton; } + + UniformSetCacheRD(); + ~UniformSetCacheRD(); +}; + +#endif // UNIFORMSETCACHE_H diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 5bdc7ce600..700ca7e167 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2039,7 +2039,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in cull.shadows[p_shadow_index].light_instance = light->instance; for (int i = 0; i < splits; i++) { - RENDER_TIMESTAMP("Culling Directional Light split" + itos(i)); + RENDER_TIMESTAMP("Cull DirectionalLight3D, Split " + itos(i)); // setup a camera matrix for that range! CameraMatrix camera_matrix; @@ -2227,7 +2227,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } for (int i = 0; i < 2; i++) { //using this one ensures that raster deferred will have it - RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); + RENDER_TIMESTAMP("Cull OmniLight3D Shadow Paraboloid, Half " + itos(i)); real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); @@ -2295,7 +2295,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons cm.set_perspective(90, 1, radius * 0.005f, radius); for (int i = 0; i < 6; i++) { - RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i)); + RENDER_TIMESTAMP("Cull OmniLight3D Shadow Cube, Side " + itos(i)); //using this one ensures that raster deferred will have it static const Vector3 view_normals[6] = { @@ -2368,7 +2368,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } break; case RS::LIGHT_SPOT: { - RENDER_TIMESTAMP("Culling Spot Light"); + RENDER_TIMESTAMP("Cull SpotLight3D Shadow"); if (max_shadows_used + 1 > MAX_UPDATE_SHADOWS) { return true; @@ -2508,7 +2508,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ RID environment = _render_get_environment(p_camera, p_scenario); - RENDER_TIMESTAMP("Update occlusion buffer") + RENDER_TIMESTAMP("Update Occlusion Buffer") // For now just cull on the first camera RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_ortogonal, RendererThreadPool::singleton->thread_work_pool); @@ -2890,7 +2890,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c scene_render->sdfgi_update(p_render_buffers, p_environment, p_camera_data->main_transform.origin); //update conditions for SDFGI (whether its used or not) } - RENDER_TIMESTAMP("Visibility Dependencies"); + RENDER_TIMESTAMP("Update Visibility Dependencies"); if (scenario->instance_visibility.get_bin_count() > 0) { if (!scenario->viewport_visibility_masks.has(p_viewport)) { @@ -2918,7 +2918,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c } } - RENDER_TIMESTAMP("Culling"); + RENDER_TIMESTAMP("Cull 3D Scene"); //rasterizer->set_camera(p_camera_data->main_transform, p_camera_data.main_projection, p_camera_data.is_ortogonal); @@ -2948,7 +2948,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c //check shadow.. if (light) { - if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->base) && !(RSG::storage->light_get_type(E->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_is_sky_only(E->base))) { + if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->base) && !(RSG::storage->light_get_type(E->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_get_sky_mode(E->base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY)) { lights_with_shadow.push_back(E); } //add to list @@ -3155,9 +3155,9 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) { //must redraw! - RENDER_TIMESTAMP(">Rendering Light " + itos(i)); + RENDER_TIMESTAMP("> Render Light3D " + itos(i)); light->shadow_dirty = _light_instance_update_shadow(ins, p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_ortogonal, p_camera_data->vaspect, p_shadow_atlas, scenario, p_screen_mesh_lod_threshold); - RENDER_TIMESTAMP("<Rendering Light " + itos(i)); + RENDER_TIMESTAMP("< Render Light3D " + itos(i)); } else { light->shadow_dirty = redraw; } @@ -3217,7 +3217,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c occluders_tex = RSG::viewport->viewport_get_occluder_debug_texture(p_viewport); } - RENDER_TIMESTAMP("Render Scene "); + RENDER_TIMESTAMP("Render 3D Scene"); scene_render->render_scene(p_render_buffers, p_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info); for (uint32_t i = 0; i < max_shadows_used; i++) { @@ -3263,7 +3263,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, } else { environment = scenario->fallback_environment; } - RENDER_TIMESTAMP("Render Empty Scene "); + RENDER_TIMESTAMP("Render Empty 3D Scene"); RendererSceneRender::CameraData camera_data; camera_data.set_camera(Transform3D(), CameraMatrix(), true, false); @@ -3337,7 +3337,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int environment = scenario->fallback_environment; } - RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step)); + RENDER_TIMESTAMP("Render ReflectionProbe, Step " + itos(p_step)); RendererSceneRender::CameraData camera_data; camera_data.set_camera(xform, cm, false, false); @@ -3345,7 +3345,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int } else { //do roughness postprocess step until it believes it's done - RENDER_TIMESTAMP("Post-Process Reflection Probe, Step " + itos(p_step)); + RENDER_TIMESTAMP("Post-Process ReflectionProbe, Step " + itos(p_step)); return scene_render->reflection_probe_instance_postprocess_step(reflection_probe->instance); } @@ -3398,7 +3398,7 @@ void RendererSceneCull::render_probes() { SelfList<InstanceVoxelGIData> *voxel_gi = voxel_gi_update_list.first(); if (voxel_gi) { - RENDER_TIMESTAMP("Render GI Probes"); + RENDER_TIMESTAMP("Render VoxelGI"); } while (voxel_gi) { @@ -3473,7 +3473,7 @@ void RendererSceneCull::render_probes() { cache->attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) || cache->spot_angle != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) || cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION) || - cache->sky_only != RSG::storage->light_directional_is_sky_only(instance->base)) { + cache->sky_mode != RSG::storage->light_directional_get_sky_mode(instance->base)) { cache_dirty = true; } } @@ -3541,7 +3541,7 @@ void RendererSceneCull::render_probes() { cache->attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION); cache->spot_angle = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); cache->spot_attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION); - cache->sky_only = RSG::storage->light_directional_is_sky_only(instance->base); + cache->sky_mode = RSG::storage->light_directional_get_sky_mode(instance->base); idx++; } diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 90d290bef9..2112118673 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -689,7 +689,7 @@ public: float spot_angle; float spot_attenuation; bool has_shadow; - bool sky_only; + RS::LightDirectionalSkyMode sky_mode; }; Vector<LightCache> light_cache; diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index a2df7ad38e..b5d6aae718 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -121,59 +121,6 @@ public: Set<Dependency *> dependencies; }; - virtual bool can_create_resources_async() const = 0; - /* TEXTURE API */ - - virtual RID texture_allocate() = 0; - - virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) = 0; - virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; - virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; - virtual void texture_proxy_initialize(RID p_texture, RID p_base) = 0; //all slices, then all the mipmaps, must be coherent - - virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; - virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0; - virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0; - - //these two APIs can be used together or in combination with the others. - virtual void texture_2d_placeholder_initialize(RID p_texture) = 0; - virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) = 0; - virtual void texture_3d_placeholder_initialize(RID p_texture) = 0; - - virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; - virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0; - virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0; - - virtual void texture_replace(RID p_texture, RID p_by_texture) = 0; - virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0; - - virtual void texture_set_path(RID p_texture, const String &p_path) = 0; - virtual String texture_get_path(RID p_texture) const = 0; - - virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0; - virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0; - virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) = 0; - - virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) = 0; - - virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; - - virtual Size2 texture_size_with_proxy(RID p_proxy) = 0; - - virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; - virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; - - /* CANVAS TEXTURE API */ - - virtual RID canvas_texture_allocate() = 0; - virtual void canvas_texture_initialize(RID p_rid) = 0; - - virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0; - virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0; - - virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0; - virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0; - /* SHADER API */ virtual RID shader_allocate() = 0; @@ -317,10 +264,10 @@ public: virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0; virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; - virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0; virtual void light_set_projector(RID p_light, RID p_texture) = 0; virtual void light_set_negative(RID p_light, bool p_enable) = 0; virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; + virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) = 0; virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0; virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) = 0; virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0; @@ -330,8 +277,8 @@ public: virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) = 0; virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0; virtual bool light_directional_get_blend_splits(RID p_light) const = 0; - virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0; - virtual bool light_directional_is_sky_only(RID p_light) const = 0; + virtual void light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) = 0; + virtual RS::LightDirectionalSkyMode light_directional_get_sky_mode(RID p_light) const = 0; virtual RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) = 0; virtual RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) = 0; @@ -397,6 +344,9 @@ public: virtual AABB decal_get_aabb(RID p_decal) const = 0; + virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; + virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; + /* VOXEL GI API */ virtual RID voxel_gi_allocate() = 0; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 5a84bace2d..f492c5e9bd 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -145,7 +145,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) { } void RendererViewport::_draw_3d(Viewport *p_viewport) { - RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); + RENDER_TIMESTAMP("> Render 3D Scene"); Ref<XRInterface> xr_interface; if (p_viewport->use_xr && XRServer::get_singleton() != nullptr) { @@ -170,7 +170,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) { float screen_mesh_lod_threshold = p_viewport->mesh_lod_threshold / float(p_viewport->size.width); RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->self, p_viewport->internal_size, screen_mesh_lod_threshold, p_viewport->shadow_atlas, xr_interface, &p_viewport->render_info); - RENDER_TIMESTAMP("<End Rendering 3D Scene"); + RENDER_TIMESTAMP("< Render 3D Scene"); } void RendererViewport::_draw_viewport(Viewport *p_viewport) { @@ -281,7 +281,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { int shadow_count = 0; int directional_light_count = 0; - RENDER_TIMESTAMP("Cull Canvas Lights"); + RENDER_TIMESTAMP("Cull 2D Lights"); for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); @@ -293,7 +293,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::Light *cl = F->get(); if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. - Size2 tsize = RSG::storage->texture_size_with_proxy(cl->texture); + Size2 tsize = RSG::texture_storage->texture_size_with_proxy(cl->texture); tsize *= cl->scale; Vector2 offset = tsize / 2.0; @@ -355,8 +355,8 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::LightOccluderInstance *occluders = nullptr; - RENDER_TIMESTAMP(">Render 2D Shadows"); - RENDER_TIMESTAMP("Cull Occluders"); + RENDER_TIMESTAMP("> Render PointLight2D Shadows"); + RENDER_TIMESTAMP("Cull LightOccluder2Ds"); //make list of occluders for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { @@ -378,13 +378,13 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::Light *light = lights_with_shadow; while (light) { - RENDER_TIMESTAMP("Render Shadow"); + RENDER_TIMESTAMP("Render PointLight2D Shadow"); RSG::canvas_render->light_update_shadow(light->light_internal, shadow_count++, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders); light = light->shadows_next_ptr; } - RENDER_TIMESTAMP("<End rendering 2D Shadows"); + RENDER_TIMESTAMP("< Render PointLight2D Shadows"); } if (directional_lights_with_shadow) { @@ -436,7 +436,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::LightOccluderInstance *occluders = nullptr; - RENDER_TIMESTAMP(">Render Directional 2D Shadows"); + RENDER_TIMESTAMP("> Render DirectionalLight2D Shadows"); //make list of occluders int occ_cullded = 0; @@ -467,7 +467,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { light = light->shadows_next_ptr; } - RENDER_TIMESTAMP("<Render Directional 2D Shadows"); + RENDER_TIMESTAMP("< Render DirectionalLight2D Shadows"); } if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) { @@ -548,7 +548,6 @@ void RendererViewport::draw_viewports() { // get our xr interface in case we need it Ref<XRInterface> xr_interface; - XRServer *xr_server = XRServer::get_singleton(); if (xr_server != nullptr) { // let our XR server know we're about to render our frames so we can get our frame timing @@ -567,7 +566,7 @@ void RendererViewport::draw_viewports() { Map<DisplayServer::WindowID, Vector<BlitToScreen>> blit_to_screen_list; //draw viewports - RENDER_TIMESTAMP(">Render Viewports"); + RENDER_TIMESTAMP("> Render Viewports"); //determine what is visible draw_viewports_pass++; @@ -642,7 +641,7 @@ void RendererViewport::draw_viewports() { continue; //should not draw } - RENDER_TIMESTAMP(">Rendering Viewport " + itos(i)); + RENDER_TIMESTAMP("> Render Viewport " + itos(i)); RSG::storage->render_target_set_as_unused(vp->render_target); if (vp->use_xr && xr_interface.is_valid()) { @@ -700,7 +699,7 @@ void RendererViewport::draw_viewports() { vp->update_mode = RS::VIEWPORT_UPDATE_DISABLED; } - RENDER_TIMESTAMP("<Rendering Viewport " + itos(i)); + RENDER_TIMESTAMP("< Render Viewport " + itos(i)); objects_drawn += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] + vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME]; vertices_drawn += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] + vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME]; @@ -712,7 +711,7 @@ void RendererViewport::draw_viewports() { total_vertices_drawn = vertices_drawn; total_draw_calls_used = draw_calls_used; - RENDER_TIMESTAMP("<Render Viewports"); + RENDER_TIMESTAMP("< Render Viewports"); //this needs to be called to make screen swapping more efficient RSG::rasterizer->prepare_for_blitting_render_targets(); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 655a32a805..6ed4448638 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -500,6 +500,7 @@ public: virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>()) = 0; virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0; + virtual RID texture_create_from_extension(TextureType p_type, DataFormat p_format, TextureSamples p_samples, uint64_t p_flags, uint64_t p_image, uint64_t p_width, uint64_t p_height, uint64_t p_depth, uint64_t p_layers) = 0; enum TextureSliceType { TEXTURE_SLICE_2D, @@ -725,16 +726,65 @@ public: struct Uniform { UniformType uniform_type; - int binding; //binding index as specified in shader + int binding; // Binding index as specified in shader. - //for single items, provide one ID, for - //multiple items (declared as arrays in shader), - //provide more - //for sampler with texture, supply two IDs for each. - //accepted IDs are: Sampler, Texture, Uniform Buffer and Texture Buffer - Vector<RID> ids; + private: + // In most cases only one ID is provided per binding, so avoid allocating memory unnecesarily for performance. + RID id; // If only one is provided, this is used. + Vector<RID> ids; // If multiple ones are provided, this is used instead. - Uniform() { + public: + _FORCE_INLINE_ uint32_t get_id_count() const { + return (id.is_valid() ? 1 : ids.size()); + } + + _FORCE_INLINE_ RID get_id(uint32_t p_idx) const { + if (id.is_valid()) { + ERR_FAIL_COND_V(p_idx != 0, RID()); + return id; + } else { + return ids[p_idx]; + } + } + _FORCE_INLINE_ void set_id(uint32_t p_idx, RID p_id) { + if (id.is_valid()) { + ERR_FAIL_COND(p_idx != 0); + id = p_id; + } else { + ids.write[p_idx] = p_id; + } + } + + _FORCE_INLINE_ void append_id(RID p_id) { + if (ids.is_empty()) { + if (id == RID()) { + id = p_id; + } else { + ids.push_back(id); + ids.push_back(p_id); + id = RID(); + } + } else { + ids.push_back(p_id); + } + } + + _FORCE_INLINE_ void clear_ids() { + id = RID(); + ids.clear(); + } + + _FORCE_INLINE_ Uniform(UniformType p_type, int p_binding, RID p_id) { + uniform_type = p_type; + binding = p_binding; + id = p_id; + } + _FORCE_INLINE_ Uniform(UniformType p_type, int p_binding, const Vector<RID> &p_ids) { + uniform_type = p_type; + binding = p_binding; + ids = p_ids; + } + _FORCE_INLINE_ Uniform() { uniform_type = UNIFORM_TYPE_IMAGE; binding = 0; } @@ -1172,7 +1222,7 @@ public: LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z, }; - virtual int limit_get(Limit p_limit) = 0; + virtual uint64_t limit_get(Limit p_limit) = 0; //methods below not exposed, used by RenderingDeviceRD virtual void prepare_screen_for_drawing() = 0; diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index b07857364b..ee5bf8b891 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -441,23 +441,23 @@ public: RD_SETGET(RD::UniformType, uniform_type) RD_SETGET(int32_t, binding) - void add_id(const RID &p_id) { base.ids.push_back(p_id); } - void clear_ids() { base.ids.clear(); } + void add_id(const RID &p_id) { base.append_id(p_id); } + void clear_ids() { base.clear_ids(); } Array get_ids() const { Array ids; - for (int i = 0; i < base.ids.size(); i++) { - ids.push_back(base.ids[i]); + for (uint32_t i = 0; i < base.get_id_count(); i++) { + ids.push_back(base.get_id(i)); } return ids; } protected: void _set_ids(const Array &p_ids) { - base.ids.clear(); + base.clear_ids(); for (int i = 0; i < p_ids.size(); i++) { RID id = p_ids[i]; ERR_FAIL_COND(id.is_null()); - base.ids.push_back(id); + base.append_id(id); } } static void _bind_methods() { diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index d93aad5d7b..af02e25cd9 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -398,6 +398,8 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) : RendererSceneCull *sr = memnew(RendererSceneCull); RSG::scene = sr; RSG::rasterizer = RendererCompositor::create(); + RSG::canvas_texture_storage = RSG::rasterizer->get_canvas_texture_storage(); + RSG::texture_storage = RSG::rasterizer->get_texture_storage(); RSG::storage = RSG::rasterizer->get_storage(); RSG::canvas_render = RSG::rasterizer->get_canvas(); sr->set_scene_render(RSG::rasterizer->get_scene()); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 6d2c36537b..d75caae018 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -126,54 +126,53 @@ public: #include "servers/server_wrap_mt_common.h" -//from now on, calls forwarded to this singleton -#define ServerName RendererStorage -#define server_name RSG::storage - /* TEXTURE API */ -#define FUNCRIDTEX0(m_type) \ - virtual RID m_type##_create() override { \ - RID ret = RSG::storage->texture_allocate(); \ - if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ - RSG::storage->m_type##_initialize(ret); \ - } else { \ - command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret); \ - } \ - return ret; \ +#define ServerName RendererTextureStorage +#define server_name RSG::texture_storage + +#define FUNCRIDTEX0(m_type) \ + virtual RID m_type##_create() override { \ + RID ret = RSG::texture_storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \ + RSG::texture_storage->m_type##_initialize(ret); \ + } else { \ + command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret); \ + } \ + return ret; \ } -#define FUNCRIDTEX1(m_type, m_type1) \ - virtual RID m_type##_create(m_type1 p1) override { \ - RID ret = RSG::storage->texture_allocate(); \ - if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ - RSG::storage->m_type##_initialize(ret, p1); \ - } else { \ - command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1); \ - } \ - return ret; \ +#define FUNCRIDTEX1(m_type, m_type1) \ + virtual RID m_type##_create(m_type1 p1) override { \ + RID ret = RSG::texture_storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \ + RSG::texture_storage->m_type##_initialize(ret, p1); \ + } else { \ + command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1); \ + } \ + return ret; \ } -#define FUNCRIDTEX2(m_type, m_type1, m_type2) \ - virtual RID m_type##_create(m_type1 p1, m_type2 p2) override { \ - RID ret = RSG::storage->texture_allocate(); \ - if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ - RSG::storage->m_type##_initialize(ret, p1, p2); \ - } else { \ - command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1, p2); \ - } \ - return ret; \ +#define FUNCRIDTEX2(m_type, m_type1, m_type2) \ + virtual RID m_type##_create(m_type1 p1, m_type2 p2) override { \ + RID ret = RSG::texture_storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \ + RSG::texture_storage->m_type##_initialize(ret, p1, p2); \ + } else { \ + command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1, p2); \ + } \ + return ret; \ } -#define FUNCRIDTEX6(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ - virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6) override { \ - RID ret = RSG::storage->texture_allocate(); \ - if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { \ - RSG::storage->m_type##_initialize(ret, p1, p2, p3, p4, p5, p6); \ - } else { \ - command_queue.push(RSG::storage, &RendererStorage::m_type##_initialize, ret, p1, p2, p3, p4, p5, p6); \ - } \ - return ret; \ +#define FUNCRIDTEX6(m_type, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6) \ + virtual RID m_type##_create(m_type1 p1, m_type2 p2, m_type3 p3, m_type4 p4, m_type5 p5, m_type6 p6) override { \ + RID ret = RSG::texture_storage->texture_allocate(); \ + if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { \ + RSG::texture_storage->m_type##_initialize(ret, p1, p2, p3, p4, p5, p6); \ + } else { \ + command_queue.push(RSG::texture_storage, &RendererTextureStorage::m_type##_initialize, ret, p1, p2, p3, p4, p5, p6); \ + } \ + return ret; \ } //these go pass-through, as they can be called from any thread @@ -214,6 +213,13 @@ public: FUNC2(texture_set_force_redraw_if_visible, RID, bool) +//from now on, calls forwarded to this singleton +#undef ServerName +#undef server_name + +#define ServerName RendererStorage +#define server_name RSG::storage + /* SHADER API */ FUNCRIDSPLIT(shader) @@ -246,7 +252,9 @@ public: virtual RID mesh_create_from_surfaces(const Vector<SurfaceData> &p_surfaces, int p_blend_shape_count = 0) override { RID mesh = RSG::storage->mesh_allocate(); - if (Thread::get_caller_id() == server_thread || RSG::storage->can_create_resources_async()) { + // TODO once we have RSG::mesh_storage, add can_create_resources_async and call here instead of texture_storage!! + + if (Thread::get_caller_id() == server_thread || RSG::texture_storage->can_create_resources_async()) { if (Thread::get_caller_id() == server_thread) { command_queue.flush_if_pending(); } @@ -342,10 +350,10 @@ public: FUNC2(light_set_color, RID, const Color &) FUNC3(light_set_param, RID, LightParam, float) FUNC2(light_set_shadow, RID, bool) - FUNC2(light_set_shadow_color, RID, const Color &) FUNC2(light_set_projector, RID, RID) FUNC2(light_set_negative, RID, bool) FUNC2(light_set_cull_mask, RID, uint32_t) + FUNC5(light_set_distance_fade, RID, bool, float, float, float) FUNC2(light_set_reverse_cull_face_mode, RID, bool) FUNC2(light_set_bake_mode, RID, LightBakeMode) FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t) @@ -354,7 +362,7 @@ public: FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) FUNC2(light_directional_set_blend_splits, RID, bool) - FUNC2(light_directional_set_sky_only, RID, bool) + FUNC2(light_directional_set_sky_mode, RID, LightDirectionalSkyMode) /* PROBE API */ diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp index b8b06b5eea..83aa8959c1 100644 --- a/servers/rendering/rendering_server_globals.cpp +++ b/servers/rendering/rendering_server_globals.cpp @@ -32,6 +32,8 @@ bool RenderingServerGlobals::threaded = false; +RendererCanvasTextureStorage *RenderingServerGlobals::canvas_texture_storage = nullptr; +RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr; RendererStorage *RenderingServerGlobals::storage = nullptr; RendererCanvasRender *RenderingServerGlobals::canvas_render = nullptr; RendererCompositor *RenderingServerGlobals::rasterizer = nullptr; diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h index 4351830a5f..2bef490760 100644 --- a/servers/rendering/rendering_server_globals.h +++ b/servers/rendering/rendering_server_globals.h @@ -34,6 +34,8 @@ #include "servers/rendering/renderer_canvas_cull.h" #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_scene.h" +#include "servers/rendering/storage/canvas_texture_storage.h" +#include "servers/rendering/storage/texture_storage.h" class RendererCanvasCull; class RendererViewport; @@ -43,6 +45,8 @@ class RenderingServerGlobals { public: static bool threaded; + static RendererCanvasTextureStorage *canvas_texture_storage; + static RendererTextureStorage *texture_storage; static RendererStorage *storage; static RendererCanvasRender *canvas_render; static RendererCompositor *rasterizer; diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index a0b0b31a7b..812d636a0b 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -1373,148 +1373,4 @@ void ShaderCompiler::initialize(DefaultIdentifierActions p_actions) { } ShaderCompiler::ShaderCompiler() { -#if 0 - - /** SPATIAL SHADER **/ - - actions[RS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform"; - actions[RS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix"; - actions[RS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix"; - actions[RS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix"; - actions[RS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix"; - actions[RS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview"; - - actions[RS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz"; - actions[RS::SHADER_SPATIAL].renames["NORMAL"] = "normal"; - actions[RS::SHADER_SPATIAL].renames["TANGENT"] = "tangent"; - actions[RS::SHADER_SPATIAL].renames["BINORMAL"] = "binormal"; - actions[RS::SHADER_SPATIAL].renames["POSITION"] = "position"; - actions[RS::SHADER_SPATIAL].renames["UV"] = "uv_interp"; - actions[RS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp"; - actions[RS::SHADER_SPATIAL].renames["COLOR"] = "color_interp"; - actions[RS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize"; - actions[RS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "gl_InstanceID"; - - //builtins - - actions[RS::SHADER_SPATIAL].renames["TIME"] = "time"; - actions[RS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"] = "viewport_size"; - - actions[RS::SHADER_SPATIAL].renames["FRAGCOORD"] = "gl_FragCoord"; - actions[RS::SHADER_SPATIAL].renames["FRONT_FACING"] = "gl_FrontFacing"; - actions[RS::SHADER_SPATIAL].renames["NORMAL_MAP"] = "normal_map"; - actions[RS::SHADER_SPATIAL].renames["NORMAL_MAP_DEPTH"] = "normal_map_depth"; - actions[RS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo"; - actions[RS::SHADER_SPATIAL].renames["ALPHA"] = "alpha"; - actions[RS::SHADER_SPATIAL].renames["METALLIC"] = "metallic"; - actions[RS::SHADER_SPATIAL].renames["SPECULAR"] = "specular"; - actions[RS::SHADER_SPATIAL].renames["ROUGHNESS"] = "roughness"; - actions[RS::SHADER_SPATIAL].renames["RIM"] = "rim"; - actions[RS::SHADER_SPATIAL].renames["RIM_TINT"] = "rim_tint"; - actions[RS::SHADER_SPATIAL].renames["CLEARCOAT"] = "clearcoat"; - actions[RS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; - actions[RS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy"; - actions[RS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; - actions[RS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; - actions[RS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission"; - actions[RS::SHADER_SPATIAL].renames["AO"] = "ao"; - actions[RS::SHADER_SPATIAL].renames["AO_LIGHT_AFFECT"] = "ao_light_affect"; - actions[RS::SHADER_SPATIAL].renames["EMISSION"] = "emission"; - actions[RS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord"; - actions[RS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom"; - actions[RS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv"; - actions[RS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture"; - actions[RS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer"; - actions[RS::SHADER_SPATIAL].renames["DEPTH"] = "gl_FragDepth"; - actions[RS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; - actions[RS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; - - //for light - actions[RS::SHADER_SPATIAL].renames["VIEW"] = "view"; - actions[RS::SHADER_SPATIAL].renames["LIGHT_COLOR"] = "light_color"; - actions[RS::SHADER_SPATIAL].renames["LIGHT"] = "light"; - actions[RS::SHADER_SPATIAL].renames["ATTENUATION"] = "attenuation"; - actions[RS::SHADER_SPATIAL].renames["DIFFUSE_LIGHT"] = "diffuse_light"; - actions[RS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light"; - - actions[RS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT"; - actions[RS::SHADER_SPATIAL].usage_defines["RIM"] = "#define LIGHT_USE_RIM\n"; - actions[RS::SHADER_SPATIAL].usage_defines["RIM_TINT"] = "@RIM"; - actions[RS::SHADER_SPATIAL].usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n"; - actions[RS::SHADER_SPATIAL].usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT"; - actions[RS::SHADER_SPATIAL].usage_defines["ANISOTROPY"] = "#define LIGHT_USE_ANISOTROPY\n"; - actions[RS::SHADER_SPATIAL].usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY"; - actions[RS::SHADER_SPATIAL].usage_defines["AO"] = "#define ENABLE_AO\n"; - actions[RS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n"; - actions[RS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["NORMAL_MAP"] = "#define ENABLE_NORMAL_MAP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP"; - actions[RS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; - actions[RS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; - - actions[RS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; - actions[RS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; - - actions[RS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - - actions[RS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; - - bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley"); - - if (!force_lambert) { - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; - } - - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; - - bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx"); - - if (!force_blinn) { - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - } else { - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; - } - - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n"; - - /* PARTICLES SHADER */ - - actions[RS::SHADER_PARTICLES].renames["COLOR"] = "out_color"; - actions[RS::SHADER_PARTICLES].renames["VELOCITY"] = "out_velocity_active.xyz"; - actions[RS::SHADER_PARTICLES].renames["MASS"] = "mass"; - actions[RS::SHADER_PARTICLES].renames["ACTIVE"] = "shader_active"; - actions[RS::SHADER_PARTICLES].renames["RESTART"] = "restart"; - actions[RS::SHADER_PARTICLES].renames["CUSTOM"] = "out_custom"; - actions[RS::SHADER_PARTICLES].renames["TRANSFORM"] = "xform"; - actions[RS::SHADER_PARTICLES].renames["TIME"] = "time"; - actions[RS::SHADER_PARTICLES].renames["LIFETIME"] = "lifetime"; - actions[RS::SHADER_PARTICLES].renames["DELTA"] = "local_delta"; - actions[RS::SHADER_PARTICLES].renames["NUMBER"] = "particle_number"; - actions[RS::SHADER_PARTICLES].renames["INDEX"] = "index"; - actions[RS::SHADER_PARTICLES].renames["GRAVITY"] = "current_gravity"; - actions[RS::SHADER_PARTICLES].renames["EMISSION_TRANSFORM"] = "emission_transform"; - actions[RS::SHADER_PARTICLES].renames["RANDOM_SEED"] = "random_seed"; - - actions[RS::SHADER_PARTICLES].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n"; - actions[RS::SHADER_PARTICLES].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n"; - actions[RS::SHADER_PARTICLES].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n"; -#endif } diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 7683cf20b3..08f1ced803 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -7483,8 +7483,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct int uniforms = 0; int instance_index = 0; #ifdef DEBUG_ENABLED - int uniform_buffer_size = 0; - int max_uniform_buffer_size = 0; + uint64_t uniform_buffer_size = 0; + uint64_t max_uniform_buffer_size = 0; int uniform_buffer_exceeded_line = -1; bool check_device_limit_warnings = false; diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index d628cf3713..9ea98dc593 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -121,7 +121,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["RIM"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["RIM_TINT"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CLEARCOAT"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CLEARCOAT_GLOSS"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CLEARCOAT_ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY_FLOW"] = ShaderLanguage::TYPE_VEC2; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT; @@ -202,7 +202,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "unshaded" }); shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "wireframe" }); shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "diffuse", "lambert", "lambert_wrap", "burley", "toon" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "specular", "schlick_ggx", "blinn", "phong", "toon", "disabled" }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "specular", "schlick_ggx", "toon", "disabled" }); shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "skip_vertex_transform" }); shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "world_vertex_coords" }); shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "ensure_correct_normals" }); diff --git a/servers/rendering/storage/SCsub b/servers/rendering/storage/SCsub new file mode 100644 index 0000000000..86681f9c74 --- /dev/null +++ b/servers/rendering/storage/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.servers_sources, "*.cpp") diff --git a/servers/rendering/storage/canvas_texture_storage.h b/servers/rendering/storage/canvas_texture_storage.h new file mode 100644 index 0000000000..ad4c67f649 --- /dev/null +++ b/servers/rendering/storage/canvas_texture_storage.h @@ -0,0 +1,51 @@ +/*************************************************************************/ +/* 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_H +#define CANVAS_TEXTURE_STORAGE_H + +#include "servers/rendering_server.h" + +class RendererCanvasTextureStorage { +public: + virtual ~RendererCanvasTextureStorage(){}; + + virtual RID canvas_texture_allocate() = 0; + virtual void canvas_texture_initialize(RID p_rid) = 0; + virtual void canvas_texture_free(RID p_rid) = 0; + + virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0; + virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0; + + virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0; + virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0; +}; + +#endif // !CANVAS_TEXTURE_STORAGE_H diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h new file mode 100644 index 0000000000..bef5e3e146 --- /dev/null +++ b/servers/rendering/storage/texture_storage.h @@ -0,0 +1,80 @@ +/*************************************************************************/ +/* 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 TEXTURE_STORAGE_H +#define TEXTURE_STORAGE_H + +#include "servers/rendering_server.h" + +class RendererTextureStorage { +public: + virtual bool can_create_resources_async() const = 0; + + virtual ~RendererTextureStorage(){}; + + virtual RID texture_allocate() = 0; + virtual void texture_free(RID p_rid) = 0; + + virtual void texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) = 0; + virtual void texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) = 0; + virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) = 0; + virtual void texture_proxy_initialize(RID p_texture, RID p_base) = 0; //all slices, then all the mipmaps, must be coherent + + virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0; + virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0; + virtual void texture_proxy_update(RID p_proxy, RID p_base) = 0; + + //these two APIs can be used together or in combination with the others. + virtual void texture_2d_placeholder_initialize(RID p_texture) = 0; + virtual void texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) = 0; + virtual void texture_3d_placeholder_initialize(RID p_texture) = 0; + + virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; + virtual Ref<Image> texture_2d_layer_get(RID p_texture, int p_layer) const = 0; + virtual Vector<Ref<Image>> texture_3d_get(RID p_texture) const = 0; + + virtual void texture_replace(RID p_texture, RID p_by_texture) = 0; + virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0; + + virtual void texture_set_path(RID p_texture, const String &p_path) = 0; + virtual String texture_get_path(RID p_texture) const = 0; + + virtual void texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0; + virtual void texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) = 0; + virtual void texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) = 0; + + virtual void texture_debug_usage(List<RS::TextureInfo> *r_info) = 0; + + virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; + + virtual Size2 texture_size_with_proxy(RID p_proxy) = 0; +}; + +#endif // !TEXTURE_STORAGE_H diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 820aeab5b7..668bd31a49 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1879,10 +1879,10 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("light_set_color", "light", "color"), &RenderingServer::light_set_color); ClassDB::bind_method(D_METHOD("light_set_param", "light", "param", "value"), &RenderingServer::light_set_param); ClassDB::bind_method(D_METHOD("light_set_shadow", "light", "enabled"), &RenderingServer::light_set_shadow); - ClassDB::bind_method(D_METHOD("light_set_shadow_color", "light", "color"), &RenderingServer::light_set_shadow_color); ClassDB::bind_method(D_METHOD("light_set_projector", "light", "texture"), &RenderingServer::light_set_projector); ClassDB::bind_method(D_METHOD("light_set_negative", "light", "enable"), &RenderingServer::light_set_negative); ClassDB::bind_method(D_METHOD("light_set_cull_mask", "light", "mask"), &RenderingServer::light_set_cull_mask); + ClassDB::bind_method(D_METHOD("light_set_distance_fade", "decal", "enabled", "begin", "shadow", "length"), &RenderingServer::light_set_distance_fade); ClassDB::bind_method(D_METHOD("light_set_reverse_cull_face_mode", "light", "enabled"), &RenderingServer::light_set_reverse_cull_face_mode); ClassDB::bind_method(D_METHOD("light_set_bake_mode", "light", "bake_mode"), &RenderingServer::light_set_bake_mode); ClassDB::bind_method(D_METHOD("light_set_max_sdfgi_cascade", "light", "cascade"), &RenderingServer::light_set_max_sdfgi_cascade); @@ -1891,7 +1891,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("light_directional_set_shadow_mode", "light", "mode"), &RenderingServer::light_directional_set_shadow_mode); ClassDB::bind_method(D_METHOD("light_directional_set_blend_splits", "light", "enable"), &RenderingServer::light_directional_set_blend_splits); - ClassDB::bind_method(D_METHOD("light_directional_set_sky_only", "light", "enable"), &RenderingServer::light_directional_set_sky_only); + ClassDB::bind_method(D_METHOD("light_directional_set_sky_mode", "light", "mode"), &RenderingServer::light_directional_set_sky_mode); ClassDB::bind_method(D_METHOD("light_projectors_set_filter", "filter"), &RenderingServer::light_projectors_set_filter); @@ -1937,6 +1937,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS); BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS); + BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY); + BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY); + BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY); + ClassDB::bind_method(D_METHOD("shadows_quality_set", "quality"), &RenderingServer::shadows_quality_set); ClassDB::bind_method(D_METHOD("directional_shadow_quality_set", "quality"), &RenderingServer::directional_shadow_quality_set); ClassDB::bind_method(D_METHOD("directional_shadow_atlas_set_size", "size", "is_16bits"), &RenderingServer::directional_shadow_atlas_set_size); @@ -2371,10 +2375,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES); - BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_DISABLED); - BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_LOW); - BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_MEDIUM); - BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_HIGH); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_DISABLED); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_LOW); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_HIGH); BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_VERY_LOW); BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_LOW); @@ -2580,6 +2584,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture"), &RenderingServer::canvas_item_add_particles); ClassDB::bind_method(D_METHOD("canvas_item_add_set_transform", "item", "transform"), &RenderingServer::canvas_item_add_set_transform); ClassDB::bind_method(D_METHOD("canvas_item_add_clip_ignore", "item", "ignore"), &RenderingServer::canvas_item_add_clip_ignore); + ClassDB::bind_method(D_METHOD("canvas_item_add_animation_slice", "item", "animation_length", "slice_begin", "slice_end", "offset"), &RenderingServer::canvas_item_add_animation_slice, DEFVAL(0.0)); ClassDB::bind_method(D_METHOD("canvas_item_set_sort_children_by_y", "item", "enabled"), &RenderingServer::canvas_item_set_sort_children_by_y); ClassDB::bind_method(D_METHOD("canvas_item_set_z_index", "item", "z_index"), &RenderingServer::canvas_item_set_z_index); ClassDB::bind_method(D_METHOD("canvas_item_set_z_as_relative_to_parent", "item", "enabled"), &RenderingServer::canvas_item_set_z_as_relative_to_parent); @@ -2879,8 +2884,6 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading.mobile", true); GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley", false); GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true); - GLOBAL_DEF("rendering/shading/overrides/force_blinn_over_ggx", false); - GLOBAL_DEF("rendering/shading/overrides/force_blinn_over_ggx.mobile", true); GLOBAL_DEF("rendering/driver/depth_prepass/enable", true); @@ -2896,8 +2899,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/environment/ssao/quality", 2); ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/quality", PropertyInfo(Variant::INT, "rendering/environment/ssao/quality", PROPERTY_HINT_ENUM, "Very Low (Fast),Low (Fast),Medium (Average),High (Slow),Ultra (Custom)")); - GLOBAL_DEF("rendering/environment/ssao/half_size", false); - GLOBAL_DEF("rendering/environment/ssao/half_size.mobile", true); + GLOBAL_DEF("rendering/environment/ssao/half_size", true); GLOBAL_DEF("rendering/environment/ssao/adaptive_target", 0.5); ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/adaptive_target", PropertyInfo(Variant::FLOAT, "rendering/environment/ssao/adaptive_target", PROPERTY_HINT_RANGE, "0.0,1.0,0.01")); GLOBAL_DEF("rendering/environment/ssao/blur_passes", 2); @@ -3001,7 +3003,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512); ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1")); - GLOBAL_DEF_RST("rendering/xr/enabled", false); + GLOBAL_DEF_RST_BASIC("xr/shaders/enabled", false); GLOBAL_DEF_RST("rendering/2d/options/use_software_skinning", true); GLOBAL_DEF_RST("rendering/2d/options/ninepatch_mode", 1); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 5e58afe718..94692ba68d 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -439,10 +439,10 @@ public: virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, LightParam p_param, float p_value) = 0; virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; - virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0; virtual void light_set_projector(RID p_light, RID p_texture) = 0; virtual void light_set_negative(RID p_light, bool p_enable) = 0; virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; + virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) = 0; virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0; enum LightBakeMode { @@ -469,9 +469,15 @@ public: LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS, }; + enum LightDirectionalSkyMode { + LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY, + LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY, + LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY, + }; + virtual void light_directional_set_shadow_mode(RID p_light, LightDirectionalShadowMode p_mode) = 0; virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0; - virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0; + virtual void light_directional_set_sky_mode(RID p_light, LightDirectionalSkyMode p_mode) = 0; virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0; @@ -1009,10 +1015,10 @@ public: virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance) = 0; enum EnvironmentSSRRoughnessQuality { - ENV_SSR_ROUGNESS_QUALITY_DISABLED, - ENV_SSR_ROUGNESS_QUALITY_LOW, - ENV_SSR_ROUGNESS_QUALITY_MEDIUM, - ENV_SSR_ROUGNESS_QUALITY_HIGH, + ENV_SSR_ROUGHNESS_QUALITY_DISABLED, + ENV_SSR_ROUGHNESS_QUALITY_LOW, + ENV_SSR_ROUGHNESS_QUALITY_MEDIUM, + ENV_SSR_ROUGHNESS_QUALITY_HIGH, }; virtual void environment_set_ssr_roughness_quality(EnvironmentSSRRoughnessQuality p_quality) = 0; @@ -1569,6 +1575,7 @@ VARIANT_ENUM_CAST(RenderingServer::LightParam); VARIANT_ENUM_CAST(RenderingServer::LightBakeMode); VARIANT_ENUM_CAST(RenderingServer::LightOmniShadowMode); VARIANT_ENUM_CAST(RenderingServer::LightDirectionalShadowMode); +VARIANT_ENUM_CAST(RenderingServer::LightDirectionalSkyMode); VARIANT_ENUM_CAST(RenderingServer::LightProjectorFilter); VARIANT_ENUM_CAST(RenderingServer::ReflectionProbeUpdateMode); VARIANT_ENUM_CAST(RenderingServer::ReflectionProbeAmbientMode); diff --git a/servers/text/text_server_dummy.h b/servers/text/text_server_dummy.h new file mode 100644 index 0000000000..c603881b7c --- /dev/null +++ b/servers/text/text_server_dummy.h @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* text_server_dummy.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 TEXT_SERVER_DUMMY_H +#define TEXT_SERVER_DUMMY_H + +#include "servers/text/text_server_extension.h" + +/*************************************************************************/ + +class TextServerDummy : public TextServerExtension { + GDCLASS(TextServerDummy, TextServerExtension); + _THREAD_SAFE_CLASS_ + +public: + virtual String get_name() const override { + return "Dummy"; + } +}; + +#endif // TEXT_SERVER_DUMMY_H diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index 5792572dc1..c8efacc9c5 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -31,261 +31,269 @@ #include "text_server_extension.h" void TextServerExtension::_bind_methods() { - GDVIRTUAL_BIND(_has_feature, "feature"); - GDVIRTUAL_BIND(_get_name); - GDVIRTUAL_BIND(_get_features); + GDVIRTUAL_BIND(has_feature, "feature"); + GDVIRTUAL_BIND(get_name); + GDVIRTUAL_BIND(get_features); - GDVIRTUAL_BIND(_free, "rid"); - GDVIRTUAL_BIND(_has, "rid"); - GDVIRTUAL_BIND(_load_support_data, "filename"); + GDVIRTUAL_BIND(free_rid, "rid"); + GDVIRTUAL_BIND(has, "rid"); + GDVIRTUAL_BIND(load_support_data, "filename"); - GDVIRTUAL_BIND(_get_support_data_filename); - GDVIRTUAL_BIND(_get_support_data_info); - GDVIRTUAL_BIND(_save_support_data, "filename"); + GDVIRTUAL_BIND(get_support_data_filename); + GDVIRTUAL_BIND(get_support_data_info); + GDVIRTUAL_BIND(save_support_data, "filename"); - GDVIRTUAL_BIND(_is_locale_right_to_left, "locale"); + GDVIRTUAL_BIND(is_locale_right_to_left, "locale"); - GDVIRTUAL_BIND(_name_to_tag, "name"); - GDVIRTUAL_BIND(_tag_to_name, "tag"); + GDVIRTUAL_BIND(name_to_tag, "name"); + GDVIRTUAL_BIND(tag_to_name, "tag"); /* Font interface */ - GDVIRTUAL_BIND(_create_font); + GDVIRTUAL_BIND(create_font); - GDVIRTUAL_BIND(_font_set_data, "font_rid", "data"); - GDVIRTUAL_BIND(_font_set_data_ptr, "font_rid", "data_ptr", "data_size"); + GDVIRTUAL_BIND(font_set_data, "font_rid", "data"); + GDVIRTUAL_BIND(font_set_data_ptr, "font_rid", "data_ptr", "data_size"); - GDVIRTUAL_BIND(_font_set_style, "font_rid", "style"); - GDVIRTUAL_BIND(_font_get_style, "font_rid"); + GDVIRTUAL_BIND(font_set_style, "font_rid", "style"); + GDVIRTUAL_BIND(font_get_style, "font_rid"); - GDVIRTUAL_BIND(_font_set_name, "font_rid", "name"); - GDVIRTUAL_BIND(_font_get_name, "font_rid"); + GDVIRTUAL_BIND(font_set_name, "font_rid", "name"); + GDVIRTUAL_BIND(font_get_name, "font_rid"); - GDVIRTUAL_BIND(_font_set_style_name, "font_rid", "name_style"); - GDVIRTUAL_BIND(_font_get_style_name, "font_rid"); + GDVIRTUAL_BIND(font_set_style_name, "font_rid", "name_style"); + GDVIRTUAL_BIND(font_get_style_name, "font_rid"); - GDVIRTUAL_BIND(_font_set_antialiased, "font_rid", "antialiased"); - GDVIRTUAL_BIND(_font_is_antialiased, "font_rid"); + GDVIRTUAL_BIND(font_set_antialiased, "font_rid", "antialiased"); + GDVIRTUAL_BIND(font_is_antialiased, "font_rid"); - GDVIRTUAL_BIND(_font_set_multichannel_signed_distance_field, "font_rid", "msdf"); - GDVIRTUAL_BIND(_font_is_multichannel_signed_distance_field, "font_rid"); + GDVIRTUAL_BIND(font_set_multichannel_signed_distance_field, "font_rid", "msdf"); + GDVIRTUAL_BIND(font_is_multichannel_signed_distance_field, "font_rid"); - GDVIRTUAL_BIND(_font_set_msdf_pixel_range, "font_rid", "msdf_pixel_range"); - GDVIRTUAL_BIND(_font_get_msdf_pixel_range, "font_rid"); + GDVIRTUAL_BIND(font_set_msdf_pixel_range, "font_rid", "msdf_pixel_range"); + GDVIRTUAL_BIND(font_get_msdf_pixel_range, "font_rid"); - GDVIRTUAL_BIND(_font_set_msdf_size, "font_rid", "msdf_size"); - GDVIRTUAL_BIND(_font_get_msdf_size, "font_rid"); + GDVIRTUAL_BIND(font_set_msdf_size, "font_rid", "msdf_size"); + GDVIRTUAL_BIND(font_get_msdf_size, "font_rid"); - GDVIRTUAL_BIND(_font_set_fixed_size, "font_rid", "fixed_size"); - GDVIRTUAL_BIND(_font_get_fixed_size, "font_rid"); + GDVIRTUAL_BIND(font_set_fixed_size, "font_rid", "fixed_size"); + GDVIRTUAL_BIND(font_get_fixed_size, "font_rid"); - GDVIRTUAL_BIND(_font_set_force_autohinter, "font_rid", "force_autohinter"); - GDVIRTUAL_BIND(_font_is_force_autohinter, "font_rid"); + GDVIRTUAL_BIND(font_set_force_autohinter, "font_rid", "force_autohinter"); + GDVIRTUAL_BIND(font_is_force_autohinter, "font_rid"); - GDVIRTUAL_BIND(_font_set_hinting, "font_rid", "hinting"); - GDVIRTUAL_BIND(_font_get_hinting, "font_rid"); + GDVIRTUAL_BIND(font_set_hinting, "font_rid", "hinting"); + GDVIRTUAL_BIND(font_get_hinting, "font_rid"); - GDVIRTUAL_BIND(_font_set_subpixel_positioning, "font_rid", "subpixel_positioning"); - GDVIRTUAL_BIND(_font_get_subpixel_positioning, "font_rid"); + GDVIRTUAL_BIND(font_set_subpixel_positioning, "font_rid", "subpixel_positioning"); + GDVIRTUAL_BIND(font_get_subpixel_positioning, "font_rid"); - GDVIRTUAL_BIND(_font_set_variation_coordinates, "font_rid", "variation_coordinates"); - GDVIRTUAL_BIND(_font_get_variation_coordinates, "font_rid"); + GDVIRTUAL_BIND(font_set_embolden, "font_rid", "strength"); + GDVIRTUAL_BIND(font_get_embolden, "font_rid"); - GDVIRTUAL_BIND(_font_set_oversampling, "font_rid", "oversampling"); - GDVIRTUAL_BIND(_font_get_oversampling, "font_rid"); + GDVIRTUAL_BIND(font_set_transform, "font_rid", "transform"); + GDVIRTUAL_BIND(font_get_transform, "font_rid"); - GDVIRTUAL_BIND(_font_get_size_cache_list, "font_rid"); - GDVIRTUAL_BIND(_font_clear_size_cache, "font_rid"); - GDVIRTUAL_BIND(_font_remove_size_cache, "font_rid", "size"); + GDVIRTUAL_BIND(font_set_variation_coordinates, "font_rid", "variation_coordinates"); + GDVIRTUAL_BIND(font_get_variation_coordinates, "font_rid"); - GDVIRTUAL_BIND(_font_set_ascent, "font_rid", "size", "ascent"); - GDVIRTUAL_BIND(_font_get_ascent, "font_rid", "size"); + GDVIRTUAL_BIND(font_set_oversampling, "font_rid", "oversampling"); + GDVIRTUAL_BIND(font_get_oversampling, "font_rid"); - GDVIRTUAL_BIND(_font_set_descent, "font_rid", "size", "descent"); - GDVIRTUAL_BIND(_font_get_descent, "font_rid", "size"); + GDVIRTUAL_BIND(font_get_size_cache_list, "font_rid"); + GDVIRTUAL_BIND(font_clear_size_cache, "font_rid"); + GDVIRTUAL_BIND(font_remove_size_cache, "font_rid", "size"); - GDVIRTUAL_BIND(_font_set_underline_position, "font_rid", "size", "underline_position"); - GDVIRTUAL_BIND(_font_get_underline_position, "font_rid", "size"); + GDVIRTUAL_BIND(font_set_ascent, "font_rid", "size", "ascent"); + GDVIRTUAL_BIND(font_get_ascent, "font_rid", "size"); - GDVIRTUAL_BIND(_font_set_underline_thickness, "font_rid", "size", "underline_thickness"); - GDVIRTUAL_BIND(_font_get_underline_thickness, "font_rid", "size"); + GDVIRTUAL_BIND(font_set_descent, "font_rid", "size", "descent"); + GDVIRTUAL_BIND(font_get_descent, "font_rid", "size"); - GDVIRTUAL_BIND(_font_set_scale, "font_rid", "size", "scale"); - GDVIRTUAL_BIND(_font_get_scale, "font_rid", "size"); + GDVIRTUAL_BIND(font_set_underline_position, "font_rid", "size", "underline_position"); + GDVIRTUAL_BIND(font_get_underline_position, "font_rid", "size"); - GDVIRTUAL_BIND(_font_set_spacing, "font_rid", "size", "spacing", "value"); - GDVIRTUAL_BIND(_font_get_spacing, "font_rid", "size", "spacing"); + GDVIRTUAL_BIND(font_set_underline_thickness, "font_rid", "size", "underline_thickness"); + GDVIRTUAL_BIND(font_get_underline_thickness, "font_rid", "size"); - GDVIRTUAL_BIND(_font_get_texture_count, "font_rid", "size"); - GDVIRTUAL_BIND(_font_clear_textures, "font_rid", "size"); - GDVIRTUAL_BIND(_font_remove_texture, "font_rid", "size", "texture_index"); + GDVIRTUAL_BIND(font_set_scale, "font_rid", "size", "scale"); + GDVIRTUAL_BIND(font_get_scale, "font_rid", "size"); - GDVIRTUAL_BIND(_font_set_texture_image, "font_rid", "size", "texture_index", "image"); - GDVIRTUAL_BIND(_font_get_texture_image, "font_rid", "size", "texture_index"); + GDVIRTUAL_BIND(font_set_spacing, "font_rid", "size", "spacing", "value"); + GDVIRTUAL_BIND(font_get_spacing, "font_rid", "size", "spacing"); - GDVIRTUAL_BIND(_font_set_texture_offsets, "font_rid", "size", "texture_index", "offset"); - GDVIRTUAL_BIND(_font_get_texture_offsets, "font_rid", "size", "texture_index"); + GDVIRTUAL_BIND(font_get_texture_count, "font_rid", "size"); + GDVIRTUAL_BIND(font_clear_textures, "font_rid", "size"); + GDVIRTUAL_BIND(font_remove_texture, "font_rid", "size", "texture_index"); - GDVIRTUAL_BIND(_font_get_glyph_list, "font_rid", "size"); - GDVIRTUAL_BIND(_font_clear_glyphs, "font_rid", "size"); - GDVIRTUAL_BIND(_font_remove_glyph, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(font_set_texture_image, "font_rid", "size", "texture_index", "image"); + GDVIRTUAL_BIND(font_get_texture_image, "font_rid", "size", "texture_index"); - GDVIRTUAL_BIND(_font_get_glyph_advance, "font_rid", "size", "glyph"); - GDVIRTUAL_BIND(_font_set_glyph_advance, "font_rid", "size", "glyph", "advance"); + GDVIRTUAL_BIND(font_set_texture_offsets, "font_rid", "size", "texture_index", "offset"); + GDVIRTUAL_BIND(font_get_texture_offsets, "font_rid", "size", "texture_index"); - GDVIRTUAL_BIND(_font_get_glyph_offset, "font_rid", "size", "glyph"); - GDVIRTUAL_BIND(_font_set_glyph_offset, "font_rid", "size", "glyph", "offset"); + GDVIRTUAL_BIND(font_get_glyph_list, "font_rid", "size"); + GDVIRTUAL_BIND(font_clear_glyphs, "font_rid", "size"); + GDVIRTUAL_BIND(font_remove_glyph, "font_rid", "size", "glyph"); - GDVIRTUAL_BIND(_font_get_glyph_size, "font_rid", "size", "glyph"); - GDVIRTUAL_BIND(_font_set_glyph_size, "font_rid", "size", "glyph", "gl_size"); + GDVIRTUAL_BIND(font_get_glyph_advance, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(font_set_glyph_advance, "font_rid", "size", "glyph", "advance"); - GDVIRTUAL_BIND(_font_get_glyph_uv_rect, "font_rid", "size", "glyph"); - GDVIRTUAL_BIND(_font_set_glyph_uv_rect, "font_rid", "size", "glyph", "uv_rect"); + GDVIRTUAL_BIND(font_get_glyph_offset, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(font_set_glyph_offset, "font_rid", "size", "glyph", "offset"); - GDVIRTUAL_BIND(_font_get_glyph_texture_idx, "font_rid", "size", "glyph"); - GDVIRTUAL_BIND(_font_set_glyph_texture_idx, "font_rid", "size", "glyph", "texture_idx"); + GDVIRTUAL_BIND(font_get_glyph_size, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(font_set_glyph_size, "font_rid", "size", "glyph", "gl_size"); - GDVIRTUAL_BIND(_font_get_glyph_contours, "font_rid", "size", "index"); + GDVIRTUAL_BIND(font_get_glyph_uv_rect, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(font_set_glyph_uv_rect, "font_rid", "size", "glyph", "uv_rect"); - GDVIRTUAL_BIND(_font_get_kerning_list, "font_rid", "size"); - GDVIRTUAL_BIND(_font_clear_kerning_map, "font_rid", "size"); - GDVIRTUAL_BIND(_font_remove_kerning, "font_rid", "size", "glyph_pair"); + GDVIRTUAL_BIND(font_get_glyph_texture_idx, "font_rid", "size", "glyph"); + GDVIRTUAL_BIND(font_set_glyph_texture_idx, "font_rid", "size", "glyph", "texture_idx"); - GDVIRTUAL_BIND(_font_set_kerning, "font_rid", "size", "glyph_pair", "kerning"); - GDVIRTUAL_BIND(_font_get_kerning, "font_rid", "size", "glyph_pair"); + GDVIRTUAL_BIND(font_get_glyph_contours, "font_rid", "size", "index"); - GDVIRTUAL_BIND(_font_get_glyph_index, "font_rid", "size", "char", "variation_selector"); + GDVIRTUAL_BIND(font_get_kerning_list, "font_rid", "size"); + GDVIRTUAL_BIND(font_clear_kerning_map, "font_rid", "size"); + GDVIRTUAL_BIND(font_remove_kerning, "font_rid", "size", "glyph_pair"); - GDVIRTUAL_BIND(_font_has_char, "font_rid", "char"); - GDVIRTUAL_BIND(_font_get_supported_chars, "font_rid"); + GDVIRTUAL_BIND(font_set_kerning, "font_rid", "size", "glyph_pair", "kerning"); + GDVIRTUAL_BIND(font_get_kerning, "font_rid", "size", "glyph_pair"); - GDVIRTUAL_BIND(_font_render_range, "font_rid", "size", "start", "end"); - GDVIRTUAL_BIND(_font_render_glyph, "font_rid", "size", "index"); + GDVIRTUAL_BIND(font_get_glyph_index, "font_rid", "size", "char", "variation_selector"); - GDVIRTUAL_BIND(_font_draw_glyph, "font_rid", "canvas", "size", "pos", "index", "color"); - GDVIRTUAL_BIND(_font_draw_glyph_outline, "font_rid", "canvas", "size", "outline_size", "pos", "index", "color"); + GDVIRTUAL_BIND(font_has_char, "font_rid", "char"); + GDVIRTUAL_BIND(font_get_supported_chars, "font_rid"); - GDVIRTUAL_BIND(_font_is_language_supported, "font_rid", "language"); - GDVIRTUAL_BIND(_font_set_language_support_override, "font_rid", "language", "supported"); - GDVIRTUAL_BIND(_font_get_language_support_override, "font_rid", "language"); - GDVIRTUAL_BIND(_font_remove_language_support_override, "font_rid", "language"); - GDVIRTUAL_BIND(_font_get_language_support_overrides, "font_rid"); + GDVIRTUAL_BIND(font_render_range, "font_rid", "size", "start", "end"); + GDVIRTUAL_BIND(font_render_glyph, "font_rid", "size", "index"); - GDVIRTUAL_BIND(_font_is_script_supported, "font_rid", "script"); - GDVIRTUAL_BIND(_font_set_script_support_override, "font_rid", "script", "supported"); - GDVIRTUAL_BIND(_font_get_script_support_override, "font_rid", "script"); - GDVIRTUAL_BIND(_font_remove_script_support_override, "font_rid", "script"); - GDVIRTUAL_BIND(_font_get_script_support_overrides, "font_rid"); + GDVIRTUAL_BIND(font_draw_glyph, "font_rid", "canvas", "size", "pos", "index", "color"); + GDVIRTUAL_BIND(font_draw_glyph_outline, "font_rid", "canvas", "size", "outline_size", "pos", "index", "color"); - GDVIRTUAL_BIND(_font_set_opentype_feature_overrides, "font_rid", "overrides"); - GDVIRTUAL_BIND(_font_get_opentype_feature_overrides, "font_rid"); + GDVIRTUAL_BIND(font_is_language_supported, "font_rid", "language"); + GDVIRTUAL_BIND(font_set_language_support_override, "font_rid", "language", "supported"); + GDVIRTUAL_BIND(font_get_language_support_override, "font_rid", "language"); + GDVIRTUAL_BIND(font_remove_language_support_override, "font_rid", "language"); + GDVIRTUAL_BIND(font_get_language_support_overrides, "font_rid"); - GDVIRTUAL_BIND(_font_supported_feature_list, "font_rid"); - GDVIRTUAL_BIND(_font_supported_variation_list, "font_rid"); + GDVIRTUAL_BIND(font_is_script_supported, "font_rid", "script"); + GDVIRTUAL_BIND(font_set_script_support_override, "font_rid", "script", "supported"); + GDVIRTUAL_BIND(font_get_script_support_override, "font_rid", "script"); + GDVIRTUAL_BIND(font_remove_script_support_override, "font_rid", "script"); + GDVIRTUAL_BIND(font_get_script_support_overrides, "font_rid"); - GDVIRTUAL_BIND(_font_get_global_oversampling); - GDVIRTUAL_BIND(_font_set_global_oversampling, "oversampling"); + GDVIRTUAL_BIND(font_set_opentype_feature_overrides, "font_rid", "overrides"); + GDVIRTUAL_BIND(font_get_opentype_feature_overrides, "font_rid"); - GDVIRTUAL_BIND(_get_hex_code_box_size, "size", "index"); - GDVIRTUAL_BIND(_draw_hex_code_box, "canvas", "size", "pos", "index", "color"); + GDVIRTUAL_BIND(font_supported_feature_list, "font_rid"); + GDVIRTUAL_BIND(font_supported_variation_list, "font_rid"); + + GDVIRTUAL_BIND(font_get_global_oversampling); + GDVIRTUAL_BIND(font_set_global_oversampling, "oversampling"); + + GDVIRTUAL_BIND(get_hex_code_box_size, "size", "index"); + GDVIRTUAL_BIND(draw_hex_code_box, "canvas", "size", "pos", "index", "color"); /* Shaped text buffer interface */ - GDVIRTUAL_BIND(_create_shaped_text, "direction", "orientation"); + GDVIRTUAL_BIND(create_shaped_text, "direction", "orientation"); + + GDVIRTUAL_BIND(shaped_text_clear, "shaped"); - GDVIRTUAL_BIND(_shaped_text_clear, "shaped"); + GDVIRTUAL_BIND(shaped_text_set_direction, "shaped", "direction"); + GDVIRTUAL_BIND(shaped_text_get_direction, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_inferred_direction, "shaped"); - GDVIRTUAL_BIND(_shaped_text_set_direction, "shaped", "direction"); - GDVIRTUAL_BIND(_shaped_text_get_direction, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_inferred_direction, "shaped"); + GDVIRTUAL_BIND(shaped_text_set_bidi_override, "shaped", "override"); - GDVIRTUAL_BIND(_shaped_text_set_bidi_override, "shaped", "override"); + GDVIRTUAL_BIND(shaped_text_set_custom_punctuation, "shaped", "punct"); + GDVIRTUAL_BIND(shaped_text_get_custom_punctuation, "shaped"); - GDVIRTUAL_BIND(_shaped_text_set_custom_punctuation, "shaped", "punct"); - GDVIRTUAL_BIND(_shaped_text_get_custom_punctuation, "shaped"); + GDVIRTUAL_BIND(shaped_text_set_orientation, "shaped", "orientation"); + GDVIRTUAL_BIND(shaped_text_get_orientation, "shaped"); - GDVIRTUAL_BIND(_shaped_text_set_orientation, "shaped", "orientation"); - GDVIRTUAL_BIND(_shaped_text_get_orientation, "shaped"); + GDVIRTUAL_BIND(shaped_text_set_preserve_invalid, "shaped", "enabled"); + GDVIRTUAL_BIND(shaped_text_get_preserve_invalid, "shaped"); - GDVIRTUAL_BIND(_shaped_text_set_preserve_invalid, "shaped", "enabled"); - GDVIRTUAL_BIND(_shaped_text_get_preserve_invalid, "shaped"); + GDVIRTUAL_BIND(shaped_text_set_preserve_control, "shaped", "enabled"); + GDVIRTUAL_BIND(shaped_text_get_preserve_control, "shaped"); - GDVIRTUAL_BIND(_shaped_text_set_preserve_control, "shaped", "enabled"); - GDVIRTUAL_BIND(_shaped_text_get_preserve_control, "shaped"); + GDVIRTUAL_BIND(shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language", "meta"); + GDVIRTUAL_BIND(shaped_text_add_object, "shaped", "key", "size", "inline_align", "length"); + GDVIRTUAL_BIND(shaped_text_resize_object, "shaped", "key", "size", "inline_align"); - GDVIRTUAL_BIND(_shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language", "meta"); - GDVIRTUAL_BIND(_shaped_text_add_object, "shaped", "key", "size", "inline_align", "length"); - GDVIRTUAL_BIND(_shaped_text_resize_object, "shaped", "key", "size", "inline_align"); + GDVIRTUAL_BIND(shaped_get_span_count, "shaped"); + GDVIRTUAL_BIND(shaped_get_span_meta, "shaped", "index"); + GDVIRTUAL_BIND(shaped_set_span_update_font, "shaped", "index", "fonts", "size", "opentype_features"); - GDVIRTUAL_BIND(_shaped_get_span_count, "shaped"); - GDVIRTUAL_BIND(_shaped_get_span_meta, "shaped", "index"); - GDVIRTUAL_BIND(_shaped_set_span_update_font, "shaped", "index", "fonts", "size", "opentype_features"); + GDVIRTUAL_BIND(shaped_text_substr, "shaped", "start", "length"); + GDVIRTUAL_BIND(shaped_text_get_parent, "shaped"); - GDVIRTUAL_BIND(_shaped_text_substr, "shaped", "start", "length"); - GDVIRTUAL_BIND(_shaped_text_get_parent, "shaped"); + GDVIRTUAL_BIND(shaped_text_fit_to_width, "shaped", "width", "jst_flags"); + GDVIRTUAL_BIND(shaped_text_tab_align, "shaped", "tab_stops"); - GDVIRTUAL_BIND(_shaped_text_fit_to_width, "shaped", "width", "jst_flags"); - GDVIRTUAL_BIND(_shaped_text_tab_align, "shaped", "tab_stops"); + GDVIRTUAL_BIND(shaped_text_shape, "shaped"); + GDVIRTUAL_BIND(shaped_text_update_breaks, "shaped"); + GDVIRTUAL_BIND(shaped_text_update_justification_ops, "shaped"); - GDVIRTUAL_BIND(_shaped_text_shape, "shaped"); - GDVIRTUAL_BIND(_shaped_text_update_breaks, "shaped"); - GDVIRTUAL_BIND(_shaped_text_update_justification_ops, "shaped"); + GDVIRTUAL_BIND(shaped_text_is_ready, "shaped"); - GDVIRTUAL_BIND(_shaped_text_is_ready, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_glyphs, "shaped"); + GDVIRTUAL_BIND(shaped_text_sort_logical, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_glyph_count, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_glyphs, "shaped"); - GDVIRTUAL_BIND(_shaped_text_sort_logical, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_glyph_count, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_range, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_range, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_line_breaks_adv, "shaped", "width", "start", "once", "break_flags"); + GDVIRTUAL_BIND(shaped_text_get_line_breaks, "shaped", "width", "start", "break_flags"); + GDVIRTUAL_BIND(shaped_text_get_word_breaks, "shaped", "grapheme_flags"); - GDVIRTUAL_BIND(_shaped_text_get_line_breaks_adv, "shaped", "width", "start", "once", "break_flags"); - GDVIRTUAL_BIND(_shaped_text_get_line_breaks, "shaped", "width", "start", "break_flags"); - GDVIRTUAL_BIND(_shaped_text_get_word_breaks, "shaped", "grapheme_flags"); + GDVIRTUAL_BIND(shaped_text_get_trim_pos, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_ellipsis_pos, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_ellipsis_glyph_count, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_ellipsis_glyphs, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_trim_pos, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_ellipsis_pos, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyph_count, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyphs, "shaped"); + GDVIRTUAL_BIND(shaped_text_overrun_trim_to_width, "shaped", "width", "trim_flags"); - GDVIRTUAL_BIND(_shaped_text_overrun_trim_to_width, "shaped", "width", "trim_flags"); + GDVIRTUAL_BIND(shaped_text_get_objects, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_object_rect, "shaped", "key"); - GDVIRTUAL_BIND(_shaped_text_get_objects, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_object_rect, "shaped", "key"); + GDVIRTUAL_BIND(shaped_text_get_size, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_ascent, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_descent, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_width, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_underline_position, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_underline_thickness, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_size, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_ascent, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_descent, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_width, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_underline_position, "shaped"); - GDVIRTUAL_BIND(_shaped_text_get_underline_thickness, "shaped"); + GDVIRTUAL_BIND(shaped_text_get_dominant_direction_in_range, "shaped", "start", "end"); - GDVIRTUAL_BIND(_shaped_text_get_dominant_direction_in_range, "shaped", "start", "end"); + GDVIRTUAL_BIND(shaped_text_get_carets, "shaped", "position", "caret"); + GDVIRTUAL_BIND(shaped_text_get_selection, "shaped", "start", "end"); - GDVIRTUAL_BIND(_shaped_text_get_carets, "shaped", "position", "caret"); - GDVIRTUAL_BIND(_shaped_text_get_selection, "shaped", "start", "end"); + GDVIRTUAL_BIND(shaped_text_hit_test_grapheme, "shaped", "coord"); + GDVIRTUAL_BIND(shaped_text_hit_test_position, "shaped", "coord"); - GDVIRTUAL_BIND(_shaped_text_hit_test_grapheme, "shaped", "coord"); - GDVIRTUAL_BIND(_shaped_text_hit_test_position, "shaped", "coord"); + GDVIRTUAL_BIND(shaped_text_draw, "shaped", "canvas", "pos", "clip_l", "clip_r", "color"); + GDVIRTUAL_BIND(shaped_text_draw_outline, "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color"); - GDVIRTUAL_BIND(_shaped_text_draw, "shaped", "canvas", "pos", "clip_l", "clip_r", "color"); - GDVIRTUAL_BIND(_shaped_text_draw_outline, "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color"); + GDVIRTUAL_BIND(shaped_text_get_grapheme_bounds, "shaped", "pos"); + GDVIRTUAL_BIND(shaped_text_next_grapheme_pos, "shaped", "pos"); + GDVIRTUAL_BIND(shaped_text_prev_grapheme_pos, "shaped", "pos"); - GDVIRTUAL_BIND(_shaped_text_get_grapheme_bounds, "shaped", "pos"); - GDVIRTUAL_BIND(_shaped_text_next_grapheme_pos, "shaped", "pos"); - GDVIRTUAL_BIND(_shaped_text_prev_grapheme_pos, "shaped", "pos"); + GDVIRTUAL_BIND(format_number, "string", "language"); + GDVIRTUAL_BIND(parse_number, "string", "language"); + GDVIRTUAL_BIND(percent_sign, "language"); - GDVIRTUAL_BIND(_format_number, "string", "language"); - GDVIRTUAL_BIND(_parse_number, "string", "language"); - GDVIRTUAL_BIND(_percent_sign, "language"); + GDVIRTUAL_BIND(strip_diacritics, "string"); - GDVIRTUAL_BIND(_string_to_upper, "string", "language"); - GDVIRTUAL_BIND(_string_to_lower, "string", "language"); + GDVIRTUAL_BIND(string_to_upper, "string", "language"); + GDVIRTUAL_BIND(string_to_lower, "string", "language"); } bool TextServerExtension::has_feature(Feature p_feature) const { bool ret; - if (GDVIRTUAL_CALL(_has_feature, p_feature, ret)) { + if (GDVIRTUAL_CALL(has_feature, p_feature, ret)) { return ret; } return false; @@ -293,27 +301,27 @@ bool TextServerExtension::has_feature(Feature p_feature) const { String TextServerExtension::get_name() const { String ret; - if (GDVIRTUAL_CALL(_get_name, ret)) { + if (GDVIRTUAL_CALL(get_name, ret)) { return ret; } return "Unknown"; } -uint32_t TextServerExtension::get_features() const { - uint32_t ret; - if (GDVIRTUAL_CALL(_get_features, ret)) { +int64_t TextServerExtension::get_features() const { + int64_t ret; + if (GDVIRTUAL_CALL(get_features, ret)) { return ret; } return 0; } -void TextServerExtension::free(RID p_rid) { - GDVIRTUAL_CALL(_free, p_rid); +void TextServerExtension::free_rid(const RID &p_rid) { + GDVIRTUAL_CALL(free_rid, p_rid); } -bool TextServerExtension::has(RID p_rid) { +bool TextServerExtension::has(const RID &p_rid) { bool ret; - if (GDVIRTUAL_CALL(_has, p_rid, ret)) { + if (GDVIRTUAL_CALL(has, p_rid, ret)) { return ret; } return false; @@ -321,7 +329,7 @@ bool TextServerExtension::has(RID p_rid) { bool TextServerExtension::load_support_data(const String &p_filename) { bool ret; - if (GDVIRTUAL_CALL(_load_support_data, p_filename, ret)) { + if (GDVIRTUAL_CALL(load_support_data, p_filename, ret)) { return ret; } return false; @@ -329,7 +337,7 @@ bool TextServerExtension::load_support_data(const String &p_filename) { String TextServerExtension::get_support_data_filename() const { String ret; - if (GDVIRTUAL_CALL(_get_support_data_filename, ret)) { + if (GDVIRTUAL_CALL(get_support_data_filename, ret)) { return ret; } return String(); @@ -337,7 +345,7 @@ String TextServerExtension::get_support_data_filename() const { String TextServerExtension::get_support_data_info() const { String ret; - if (GDVIRTUAL_CALL(_get_support_data_info, ret)) { + if (GDVIRTUAL_CALL(get_support_data_info, ret)) { return ret; } return String(); @@ -345,7 +353,7 @@ String TextServerExtension::get_support_data_info() const { bool TextServerExtension::save_support_data(const String &p_filename) const { bool ret; - if (GDVIRTUAL_CALL(_save_support_data, p_filename, ret)) { + if (GDVIRTUAL_CALL(save_support_data, p_filename, ret)) { return ret; } return false; @@ -353,23 +361,23 @@ bool TextServerExtension::save_support_data(const String &p_filename) const { bool TextServerExtension::is_locale_right_to_left(const String &p_locale) const { bool ret; - if (GDVIRTUAL_CALL(_is_locale_right_to_left, p_locale, ret)) { + if (GDVIRTUAL_CALL(is_locale_right_to_left, p_locale, ret)) { return ret; } return false; } -int32_t TextServerExtension::name_to_tag(const String &p_name) const { - int32_t ret; - if (GDVIRTUAL_CALL(_name_to_tag, p_name, ret)) { +int64_t TextServerExtension::name_to_tag(const String &p_name) const { + int64_t ret; + if (GDVIRTUAL_CALL(name_to_tag, p_name, ret)) { return ret; } return 0; } -String TextServerExtension::tag_to_name(int32_t p_tag) const { +String TextServerExtension::tag_to_name(int64_t p_tag) const { String ret; - if (GDVIRTUAL_CALL(_tag_to_name, p_tag, ret)) { + if (GDVIRTUAL_CALL(tag_to_name, p_tag, ret)) { return ret; } return ""; @@ -381,570 +389,594 @@ String TextServerExtension::tag_to_name(int32_t p_tag) const { RID TextServerExtension::create_font() { RID ret; - if (GDVIRTUAL_CALL(_create_font, ret)) { + if (GDVIRTUAL_CALL(create_font, ret)) { return ret; } return RID(); } -void TextServerExtension::font_set_data(RID p_font_rid, const PackedByteArray &p_data) { - GDVIRTUAL_CALL(_font_set_data, p_font_rid, p_data); +void TextServerExtension::font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) { + GDVIRTUAL_CALL(font_set_data, p_font_rid, p_data); } -void TextServerExtension::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) { - GDVIRTUAL_CALL(_font_set_data_ptr, p_font_rid, p_data_ptr, p_data_size); +void TextServerExtension::font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) { + GDVIRTUAL_CALL(font_set_data_ptr, p_font_rid, p_data_ptr, p_data_size); } -void TextServerExtension::font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) { - GDVIRTUAL_CALL(_font_set_style, p_font_rid, p_style); +void TextServerExtension::font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) { + GDVIRTUAL_CALL(font_set_style, p_font_rid, p_style); } -uint32_t /*FontStyle*/ TextServerExtension::font_get_style(RID p_font_rid) const { - uint32_t ret; - if (GDVIRTUAL_CALL(_font_get_style, p_font_rid, ret)) { +int64_t /*FontStyle*/ TextServerExtension::font_get_style(const RID &p_font_rid) const { + int64_t ret; + if (GDVIRTUAL_CALL(font_get_style, p_font_rid, ret)) { return ret; } return 0; } -void TextServerExtension::font_set_style_name(RID p_font_rid, const String &p_name) { - GDVIRTUAL_CALL(_font_set_style_name, p_font_rid, p_name); +void TextServerExtension::font_set_style_name(const RID &p_font_rid, const String &p_name) { + GDVIRTUAL_CALL(font_set_style_name, p_font_rid, p_name); } -String TextServerExtension::font_get_style_name(RID p_font_rid) const { +String TextServerExtension::font_get_style_name(const RID &p_font_rid) const { String ret; - if (GDVIRTUAL_CALL(_font_get_style_name, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_get_style_name, p_font_rid, ret)) { return ret; } return String(); } -void TextServerExtension::font_set_name(RID p_font_rid, const String &p_name) { - GDVIRTUAL_CALL(_font_set_name, p_font_rid, p_name); +void TextServerExtension::font_set_name(const RID &p_font_rid, const String &p_name) { + GDVIRTUAL_CALL(font_set_name, p_font_rid, p_name); } -String TextServerExtension::font_get_name(RID p_font_rid) const { +String TextServerExtension::font_get_name(const RID &p_font_rid) const { String ret; - if (GDVIRTUAL_CALL(_font_get_name, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_get_name, p_font_rid, ret)) { return ret; } return String(); } -void TextServerExtension::font_set_antialiased(RID p_font_rid, bool p_antialiased) { - GDVIRTUAL_CALL(_font_set_antialiased, p_font_rid, p_antialiased); +void TextServerExtension::font_set_antialiased(const RID &p_font_rid, bool p_antialiased) { + GDVIRTUAL_CALL(font_set_antialiased, p_font_rid, p_antialiased); } -bool TextServerExtension::font_is_antialiased(RID p_font_rid) const { +bool TextServerExtension::font_is_antialiased(const RID &p_font_rid) const { bool ret; - if (GDVIRTUAL_CALL(_font_is_antialiased, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_is_antialiased, p_font_rid, ret)) { return ret; } return false; } -void TextServerExtension::font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) { - GDVIRTUAL_CALL(_font_set_multichannel_signed_distance_field, p_font_rid, p_msdf); +void TextServerExtension::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) { + GDVIRTUAL_CALL(font_set_multichannel_signed_distance_field, p_font_rid, p_msdf); } -bool TextServerExtension::font_is_multichannel_signed_distance_field(RID p_font_rid) const { +bool TextServerExtension::font_is_multichannel_signed_distance_field(const RID &p_font_rid) const { bool ret; - if (GDVIRTUAL_CALL(_font_is_multichannel_signed_distance_field, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_is_multichannel_signed_distance_field, p_font_rid, ret)) { return ret; } return false; } -void TextServerExtension::font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) { - GDVIRTUAL_CALL(_font_set_msdf_pixel_range, p_font_rid, p_msdf_pixel_range); +void TextServerExtension::font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) { + GDVIRTUAL_CALL(font_set_msdf_pixel_range, p_font_rid, p_msdf_pixel_range); } -int TextServerExtension::font_get_msdf_pixel_range(RID p_font_rid) const { - int ret; - if (GDVIRTUAL_CALL(_font_get_msdf_pixel_range, p_font_rid, ret)) { +int64_t TextServerExtension::font_get_msdf_pixel_range(const RID &p_font_rid) const { + int64_t ret; + if (GDVIRTUAL_CALL(font_get_msdf_pixel_range, p_font_rid, ret)) { return ret; } return 0; } -void TextServerExtension::font_set_msdf_size(RID p_font_rid, int p_msdf_size) { - GDVIRTUAL_CALL(_font_set_msdf_size, p_font_rid, p_msdf_size); +void TextServerExtension::font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) { + GDVIRTUAL_CALL(font_set_msdf_size, p_font_rid, p_msdf_size); } -int TextServerExtension::font_get_msdf_size(RID p_font_rid) const { - int ret; - if (GDVIRTUAL_CALL(_font_get_msdf_size, p_font_rid, ret)) { +int64_t TextServerExtension::font_get_msdf_size(const RID &p_font_rid) const { + int64_t ret; + if (GDVIRTUAL_CALL(font_get_msdf_size, p_font_rid, ret)) { return ret; } return 0; } -void TextServerExtension::font_set_fixed_size(RID p_font_rid, int p_fixed_size) { - GDVIRTUAL_CALL(_font_set_fixed_size, p_font_rid, p_fixed_size); +void TextServerExtension::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) { + GDVIRTUAL_CALL(font_set_fixed_size, p_font_rid, p_fixed_size); } -int TextServerExtension::font_get_fixed_size(RID p_font_rid) const { - int ret; - if (GDVIRTUAL_CALL(_font_get_fixed_size, p_font_rid, ret)) { +int64_t TextServerExtension::font_get_fixed_size(const RID &p_font_rid) const { + int64_t ret; + if (GDVIRTUAL_CALL(font_get_fixed_size, p_font_rid, ret)) { return ret; } return 0; } -void TextServerExtension::font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) { - GDVIRTUAL_CALL(_font_set_force_autohinter, p_font_rid, p_force_autohinter); +void TextServerExtension::font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) { + GDVIRTUAL_CALL(font_set_force_autohinter, p_font_rid, p_force_autohinter); } -bool TextServerExtension::font_is_force_autohinter(RID p_font_rid) const { +bool TextServerExtension::font_is_force_autohinter(const RID &p_font_rid) const { bool ret; - if (GDVIRTUAL_CALL(_font_is_force_autohinter, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_is_force_autohinter, p_font_rid, ret)) { return ret; } return false; } -void TextServerExtension::font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) { - GDVIRTUAL_CALL(_font_set_hinting, p_font_rid, p_hinting); +void TextServerExtension::font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) { + GDVIRTUAL_CALL(font_set_hinting, p_font_rid, p_hinting); } -TextServer::Hinting TextServerExtension::font_get_hinting(RID p_font_rid) const { +TextServer::Hinting TextServerExtension::font_get_hinting(const RID &p_font_rid) const { TextServer::Hinting ret; - if (GDVIRTUAL_CALL(_font_get_hinting, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_get_hinting, p_font_rid, ret)) { return (TextServer::Hinting)ret; } return TextServer::Hinting::HINTING_NONE; } -void TextServerExtension::font_set_subpixel_positioning(RID p_font_rid, TextServer::SubpixelPositioning p_subpixel) { - GDVIRTUAL_CALL(_font_set_subpixel_positioning, p_font_rid, p_subpixel); +void TextServerExtension::font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) { + GDVIRTUAL_CALL(font_set_subpixel_positioning, p_font_rid, p_subpixel); } -TextServer::SubpixelPositioning TextServerExtension::font_get_subpixel_positioning(RID p_font_rid) const { +TextServer::SubpixelPositioning TextServerExtension::font_get_subpixel_positioning(const RID &p_font_rid) const { TextServer::SubpixelPositioning ret; - if (GDVIRTUAL_CALL(_font_get_subpixel_positioning, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_get_subpixel_positioning, p_font_rid, ret)) { return (TextServer::SubpixelPositioning)ret; } return TextServer::SubpixelPositioning::SUBPIXEL_POSITIONING_DISABLED; } -void TextServerExtension::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) { - GDVIRTUAL_CALL(_font_set_variation_coordinates, p_font_rid, p_variation_coordinates); +void TextServerExtension::font_set_embolden(const RID &p_font_rid, double p_strength) { + GDVIRTUAL_CALL(font_set_embolden, p_font_rid, p_strength); +} + +double TextServerExtension::font_get_embolden(const RID &p_font_rid) const { + double ret; + if (GDVIRTUAL_CALL(font_get_embolden, p_font_rid, ret)) { + return ret; + } + return 0.0; +} + +void TextServerExtension::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) { + GDVIRTUAL_CALL(font_set_transform, p_font_rid, p_transform); +} + +Transform2D TextServerExtension::font_get_transform(const RID &p_font_rid) const { + Transform2D ret; + if (GDVIRTUAL_CALL(font_get_transform, p_font_rid, ret)) { + return ret; + } + return Transform2D(); +} + +void TextServerExtension::font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) { + GDVIRTUAL_CALL(font_set_variation_coordinates, p_font_rid, p_variation_coordinates); } -Dictionary TextServerExtension::font_get_variation_coordinates(RID p_font_rid) const { +Dictionary TextServerExtension::font_get_variation_coordinates(const RID &p_font_rid) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_get_variation_coordinates, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_get_variation_coordinates, p_font_rid, ret)) { return ret; } return Dictionary(); } -void TextServerExtension::font_set_oversampling(RID p_font_rid, float p_oversampling) { - GDVIRTUAL_CALL(_font_set_oversampling, p_font_rid, p_oversampling); +void TextServerExtension::font_set_oversampling(const RID &p_font_rid, double p_oversampling) { + GDVIRTUAL_CALL(font_set_oversampling, p_font_rid, p_oversampling); } -float TextServerExtension::font_get_oversampling(RID p_font_rid) const { - float ret; - if (GDVIRTUAL_CALL(_font_get_oversampling, p_font_rid, ret)) { +double TextServerExtension::font_get_oversampling(const RID &p_font_rid) const { + double ret; + if (GDVIRTUAL_CALL(font_get_oversampling, p_font_rid, ret)) { return ret; } - return 0.f; + return 0.0; } -Array TextServerExtension::font_get_size_cache_list(RID p_font_rid) const { +Array TextServerExtension::font_get_size_cache_list(const RID &p_font_rid) const { Array ret; - if (GDVIRTUAL_CALL(_font_get_size_cache_list, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_get_size_cache_list, p_font_rid, ret)) { return ret; } return Array(); } -void TextServerExtension::font_clear_size_cache(RID p_font_rid) { - GDVIRTUAL_CALL(_font_clear_size_cache, p_font_rid); +void TextServerExtension::font_clear_size_cache(const RID &p_font_rid) { + GDVIRTUAL_CALL(font_clear_size_cache, p_font_rid); } -void TextServerExtension::font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) { - GDVIRTUAL_CALL(_font_remove_size_cache, p_font_rid, p_size); +void TextServerExtension::font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) { + GDVIRTUAL_CALL(font_remove_size_cache, p_font_rid, p_size); } -void TextServerExtension::font_set_ascent(RID p_font_rid, int p_size, float p_ascent) { - GDVIRTUAL_CALL(_font_set_ascent, p_font_rid, p_size, p_ascent); +void TextServerExtension::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) { + GDVIRTUAL_CALL(font_set_ascent, p_font_rid, p_size, p_ascent); } -float TextServerExtension::font_get_ascent(RID p_font_rid, int p_size) const { - float ret; - if (GDVIRTUAL_CALL(_font_get_ascent, p_font_rid, p_size, ret)) { +double TextServerExtension::font_get_ascent(const RID &p_font_rid, int64_t p_size) const { + double ret; + if (GDVIRTUAL_CALL(font_get_ascent, p_font_rid, p_size, ret)) { return ret; } - return 0.f; + return 0.0; } -void TextServerExtension::font_set_descent(RID p_font_rid, int p_size, float p_descent) { - GDVIRTUAL_CALL(_font_set_descent, p_font_rid, p_size, p_descent); +void TextServerExtension::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) { + GDVIRTUAL_CALL(font_set_descent, p_font_rid, p_size, p_descent); } -float TextServerExtension::font_get_descent(RID p_font_rid, int p_size) const { - float ret; - if (GDVIRTUAL_CALL(_font_get_descent, p_font_rid, p_size, ret)) { +double TextServerExtension::font_get_descent(const RID &p_font_rid, int64_t p_size) const { + double ret; + if (GDVIRTUAL_CALL(font_get_descent, p_font_rid, p_size, ret)) { return ret; } - return 0.f; + return 0.0; } -void TextServerExtension::font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) { - GDVIRTUAL_CALL(_font_set_underline_position, p_font_rid, p_size, p_underline_position); +void TextServerExtension::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) { + GDVIRTUAL_CALL(font_set_underline_position, p_font_rid, p_size, p_underline_position); } -float TextServerExtension::font_get_underline_position(RID p_font_rid, int p_size) const { - float ret; - if (GDVIRTUAL_CALL(_font_get_underline_position, p_font_rid, p_size, ret)) { +double TextServerExtension::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const { + double ret; + if (GDVIRTUAL_CALL(font_get_underline_position, p_font_rid, p_size, ret)) { return ret; } - return 0.f; + return 0.0; } -void TextServerExtension::font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) { - GDVIRTUAL_CALL(_font_set_underline_thickness, p_font_rid, p_size, p_underline_thickness); +void TextServerExtension::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) { + GDVIRTUAL_CALL(font_set_underline_thickness, p_font_rid, p_size, p_underline_thickness); } -float TextServerExtension::font_get_underline_thickness(RID p_font_rid, int p_size) const { - float ret; - if (GDVIRTUAL_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret)) { +double TextServerExtension::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const { + double ret; + if (GDVIRTUAL_CALL(font_get_underline_thickness, p_font_rid, p_size, ret)) { return ret; } - return 0.f; + return 0.0; } -void TextServerExtension::font_set_scale(RID p_font_rid, int p_size, float p_scale) { - GDVIRTUAL_CALL(_font_set_scale, p_font_rid, p_size, p_scale); +void TextServerExtension::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) { + GDVIRTUAL_CALL(font_set_scale, p_font_rid, p_size, p_scale); } -float TextServerExtension::font_get_scale(RID p_font_rid, int p_size) const { - float ret; - if (GDVIRTUAL_CALL(_font_get_scale, p_font_rid, p_size, ret)) { +double TextServerExtension::font_get_scale(const RID &p_font_rid, int64_t p_size) const { + double ret; + if (GDVIRTUAL_CALL(font_get_scale, p_font_rid, p_size, ret)) { return ret; } - return 0.f; + return 0.0; } -void TextServerExtension::font_set_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing, int p_value) { - GDVIRTUAL_CALL(_font_set_spacing, p_font_rid, p_size, p_spacing, p_value); +void TextServerExtension::font_set_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing, int64_t p_value) { + GDVIRTUAL_CALL(font_set_spacing, p_font_rid, p_size, p_spacing, p_value); } -int TextServerExtension::font_get_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing) const { - int ret; - if (GDVIRTUAL_CALL(_font_get_spacing, p_font_rid, p_size, p_spacing, ret)) { +int64_t TextServerExtension::font_get_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing) const { + int64_t ret; + if (GDVIRTUAL_CALL(font_get_spacing, p_font_rid, p_size, p_spacing, ret)) { return ret; } return 0; } -int TextServerExtension::font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const { - int ret; - if (GDVIRTUAL_CALL(_font_get_texture_count, p_font_rid, p_size, ret)) { +int64_t TextServerExtension::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const { + int64_t ret; + if (GDVIRTUAL_CALL(font_get_texture_count, p_font_rid, p_size, ret)) { return ret; } return 0; } -void TextServerExtension::font_clear_textures(RID p_font_rid, const Vector2i &p_size) { - GDVIRTUAL_CALL(_font_clear_textures, p_font_rid, p_size); +void TextServerExtension::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) { + GDVIRTUAL_CALL(font_clear_textures, p_font_rid, p_size); } -void TextServerExtension::font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) { - GDVIRTUAL_CALL(_font_remove_texture, p_font_rid, p_size, p_texture_index); +void TextServerExtension::font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) { + GDVIRTUAL_CALL(font_remove_texture, p_font_rid, p_size, p_texture_index); } -void TextServerExtension::font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) { - GDVIRTUAL_CALL(_font_set_texture_image, p_font_rid, p_size, p_texture_index, p_image); +void TextServerExtension::font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) { + GDVIRTUAL_CALL(font_set_texture_image, p_font_rid, p_size, p_texture_index, p_image); } -Ref<Image> TextServerExtension::font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { +Ref<Image> TextServerExtension::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const { Ref<Image> ret; - if (GDVIRTUAL_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret)) { + if (GDVIRTUAL_CALL(font_get_texture_image, p_font_rid, p_size, p_texture_index, ret)) { return ret; } return Ref<Image>(); } -void TextServerExtension::font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) { - GDVIRTUAL_CALL(_font_set_texture_offsets, p_font_rid, p_size, p_texture_index, p_offset); +void TextServerExtension::font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) { + GDVIRTUAL_CALL(font_set_texture_offsets, p_font_rid, p_size, p_texture_index, p_offset); } -PackedInt32Array TextServerExtension::font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const { +PackedInt32Array TextServerExtension::font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const { PackedInt32Array ret; - if (GDVIRTUAL_CALL(_font_get_texture_offsets, p_font_rid, p_size, p_texture_index, ret)) { + if (GDVIRTUAL_CALL(font_get_texture_offsets, p_font_rid, p_size, p_texture_index, ret)) { return ret; } return PackedInt32Array(); } -Array TextServerExtension::font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const { +Array TextServerExtension::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const { Array ret; - if (GDVIRTUAL_CALL(_font_get_glyph_list, p_font_rid, p_size, ret)) { + if (GDVIRTUAL_CALL(font_get_glyph_list, p_font_rid, p_size, ret)) { return ret; } return Array(); } -void TextServerExtension::font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) { - GDVIRTUAL_CALL(_font_clear_glyphs, p_font_rid, p_size); +void TextServerExtension::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) { + GDVIRTUAL_CALL(font_clear_glyphs, p_font_rid, p_size); } -void TextServerExtension::font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) { - GDVIRTUAL_CALL(_font_remove_glyph, p_font_rid, p_size, p_glyph); +void TextServerExtension::font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) { + GDVIRTUAL_CALL(font_remove_glyph, p_font_rid, p_size, p_glyph); } -Vector2 TextServerExtension::font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const { +Vector2 TextServerExtension::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const { Vector2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret)) { + if (GDVIRTUAL_CALL(font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret)) { return ret; } return Vector2(); } -void TextServerExtension::font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) { - GDVIRTUAL_CALL(_font_set_glyph_advance, p_font_rid, p_size, p_glyph, p_advance); +void TextServerExtension::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) { + GDVIRTUAL_CALL(font_set_glyph_advance, p_font_rid, p_size, p_glyph, p_advance); } -Vector2 TextServerExtension::font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { +Vector2 TextServerExtension::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Vector2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret)) { + if (GDVIRTUAL_CALL(font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret)) { return ret; } return Vector2(); } -void TextServerExtension::font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) { - GDVIRTUAL_CALL(_font_set_glyph_offset, p_font_rid, p_size, p_glyph, p_offset); +void TextServerExtension::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) { + GDVIRTUAL_CALL(font_set_glyph_offset, p_font_rid, p_size, p_glyph, p_offset); } -Vector2 TextServerExtension::font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { +Vector2 TextServerExtension::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Vector2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret)) { + if (GDVIRTUAL_CALL(font_get_glyph_size, p_font_rid, p_size, p_glyph, ret)) { return ret; } return Vector2(); } -void TextServerExtension::font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) { - GDVIRTUAL_CALL(_font_set_glyph_size, p_font_rid, p_size, p_glyph, p_gl_size); +void TextServerExtension::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) { + GDVIRTUAL_CALL(font_set_glyph_size, p_font_rid, p_size, p_glyph, p_gl_size); } -Rect2 TextServerExtension::font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { +Rect2 TextServerExtension::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { Rect2 ret; - if (GDVIRTUAL_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret)) { + if (GDVIRTUAL_CALL(font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret)) { return ret; } return Rect2(); } -void TextServerExtension::font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) { - GDVIRTUAL_CALL(_font_set_glyph_uv_rect, p_font_rid, p_size, p_glyph, p_uv_rect); +void TextServerExtension::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) { + GDVIRTUAL_CALL(font_set_glyph_uv_rect, p_font_rid, p_size, p_glyph, p_uv_rect); } -int TextServerExtension::font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const { - int ret; - if (GDVIRTUAL_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret)) { +int64_t TextServerExtension::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { + int64_t ret; + if (GDVIRTUAL_CALL(font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret)) { return ret; } return 0; } -void TextServerExtension::font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) { - GDVIRTUAL_CALL(_font_set_glyph_texture_idx, p_font_rid, p_size, p_glyph, p_texture_idx); +void TextServerExtension::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) { + GDVIRTUAL_CALL(font_set_glyph_texture_idx, p_font_rid, p_size, p_glyph, p_texture_idx); } -Dictionary TextServerExtension::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index) const { +Dictionary TextServerExtension::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_get_glyph_contours, p_font_rid, p_size, p_index, ret)) { + if (GDVIRTUAL_CALL(font_get_glyph_contours, p_font_rid, p_size, p_index, ret)) { return ret; } return Dictionary(); } -Array TextServerExtension::font_get_kerning_list(RID p_font_rid, int p_size) const { +Array TextServerExtension::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const { Array ret; - if (GDVIRTUAL_CALL(_font_get_kerning_list, p_font_rid, p_size, ret)) { + if (GDVIRTUAL_CALL(font_get_kerning_list, p_font_rid, p_size, ret)) { return ret; } return Array(); } -void TextServerExtension::font_clear_kerning_map(RID p_font_rid, int p_size) { - GDVIRTUAL_CALL(_font_clear_kerning_map, p_font_rid, p_size); +void TextServerExtension::font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) { + GDVIRTUAL_CALL(font_clear_kerning_map, p_font_rid, p_size); } -void TextServerExtension::font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) { - GDVIRTUAL_CALL(_font_remove_kerning, p_font_rid, p_size, p_glyph_pair); +void TextServerExtension::font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) { + GDVIRTUAL_CALL(font_remove_kerning, p_font_rid, p_size, p_glyph_pair); } -void TextServerExtension::font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) { - GDVIRTUAL_CALL(_font_set_kerning, p_font_rid, p_size, p_glyph_pair, p_kerning); +void TextServerExtension::font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) { + GDVIRTUAL_CALL(font_set_kerning, p_font_rid, p_size, p_glyph_pair, p_kerning); } -Vector2 TextServerExtension::font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const { +Vector2 TextServerExtension::font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const { Vector2 ret; - if (GDVIRTUAL_CALL(_font_get_kerning, p_font_rid, p_size, p_glyph_pair, ret)) { + if (GDVIRTUAL_CALL(font_get_kerning, p_font_rid, p_size, p_glyph_pair, ret)) { return ret; } return Vector2(); } -int32_t TextServerExtension::font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const { - int32_t ret; - if (GDVIRTUAL_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret)) { +int64_t TextServerExtension::font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const { + int64_t ret; + if (GDVIRTUAL_CALL(font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret)) { return ret; } return 0; } -bool TextServerExtension::font_has_char(RID p_font_rid, char32_t p_char) const { +bool TextServerExtension::font_has_char(const RID &p_font_rid, int64_t p_char) const { bool ret; - if (GDVIRTUAL_CALL(_font_has_char, p_font_rid, p_char, ret)) { + if (GDVIRTUAL_CALL(font_has_char, p_font_rid, p_char, ret)) { return ret; } return false; } -String TextServerExtension::font_get_supported_chars(RID p_font_rid) const { +String TextServerExtension::font_get_supported_chars(const RID &p_font_rid) const { String ret; - if (GDVIRTUAL_CALL(_font_get_supported_chars, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_get_supported_chars, p_font_rid, ret)) { return ret; } return String(); } -void TextServerExtension::font_render_range(RID p_font_rid, const Vector2i &p_size, char32_t p_start, char32_t p_end) { - GDVIRTUAL_CALL(_font_render_range, p_font_rid, p_size, p_start, p_end); +void TextServerExtension::font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) { + GDVIRTUAL_CALL(font_render_range, p_font_rid, p_size, p_start, p_end); } -void TextServerExtension::font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) { - GDVIRTUAL_CALL(_font_render_glyph, p_font_rid, p_size, p_index); +void TextServerExtension::font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) { + GDVIRTUAL_CALL(font_render_glyph, p_font_rid, p_size, p_index); } -void TextServerExtension::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { - GDVIRTUAL_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color); +void TextServerExtension::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { + GDVIRTUAL_CALL(font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color); } -void TextServerExtension::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const { - GDVIRTUAL_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color); +void TextServerExtension::font_draw_glyph_outline(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { + GDVIRTUAL_CALL(font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color); } -bool TextServerExtension::font_is_language_supported(RID p_font_rid, const String &p_language) const { +bool TextServerExtension::font_is_language_supported(const RID &p_font_rid, const String &p_language) const { bool ret; - if (GDVIRTUAL_CALL(_font_is_language_supported, p_font_rid, p_language, ret)) { + if (GDVIRTUAL_CALL(font_is_language_supported, p_font_rid, p_language, ret)) { return ret; } return false; } -void TextServerExtension::font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) { - GDVIRTUAL_CALL(_font_set_language_support_override, p_font_rid, p_language, p_supported); +void TextServerExtension::font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) { + GDVIRTUAL_CALL(font_set_language_support_override, p_font_rid, p_language, p_supported); } -bool TextServerExtension::font_get_language_support_override(RID p_font_rid, const String &p_language) { +bool TextServerExtension::font_get_language_support_override(const RID &p_font_rid, const String &p_language) { bool ret; - if (GDVIRTUAL_CALL(_font_get_language_support_override, p_font_rid, p_language, ret)) { + if (GDVIRTUAL_CALL(font_get_language_support_override, p_font_rid, p_language, ret)) { return ret; } return false; } -void TextServerExtension::font_remove_language_support_override(RID p_font_rid, const String &p_language) { - GDVIRTUAL_CALL(_font_remove_language_support_override, p_font_rid, p_language); +void TextServerExtension::font_remove_language_support_override(const RID &p_font_rid, const String &p_language) { + GDVIRTUAL_CALL(font_remove_language_support_override, p_font_rid, p_language); } -Vector<String> TextServerExtension::font_get_language_support_overrides(RID p_font_rid) { - Vector<String> ret; - if (GDVIRTUAL_CALL(_font_get_language_support_overrides, p_font_rid, ret)) { +PackedStringArray TextServerExtension::font_get_language_support_overrides(const RID &p_font_rid) { + PackedStringArray ret; + if (GDVIRTUAL_CALL(font_get_language_support_overrides, p_font_rid, ret)) { return ret; } - return Vector<String>(); + return PackedStringArray(); } -bool TextServerExtension::font_is_script_supported(RID p_font_rid, const String &p_script) const { +bool TextServerExtension::font_is_script_supported(const RID &p_font_rid, const String &p_script) const { bool ret; - if (GDVIRTUAL_CALL(_font_is_script_supported, p_font_rid, p_script, ret)) { + if (GDVIRTUAL_CALL(font_is_script_supported, p_font_rid, p_script, ret)) { return ret; } return false; } -void TextServerExtension::font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) { - GDVIRTUAL_CALL(_font_set_script_support_override, p_font_rid, p_script, p_supported); +void TextServerExtension::font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) { + GDVIRTUAL_CALL(font_set_script_support_override, p_font_rid, p_script, p_supported); } -bool TextServerExtension::font_get_script_support_override(RID p_font_rid, const String &p_script) { +bool TextServerExtension::font_get_script_support_override(const RID &p_font_rid, const String &p_script) { bool ret; - if (GDVIRTUAL_CALL(_font_get_script_support_override, p_font_rid, p_script, ret)) { + if (GDVIRTUAL_CALL(font_get_script_support_override, p_font_rid, p_script, ret)) { return ret; } return false; } -void TextServerExtension::font_remove_script_support_override(RID p_font_rid, const String &p_script) { - GDVIRTUAL_CALL(_font_remove_script_support_override, p_font_rid, p_script); +void TextServerExtension::font_remove_script_support_override(const RID &p_font_rid, const String &p_script) { + GDVIRTUAL_CALL(font_remove_script_support_override, p_font_rid, p_script); } -Vector<String> TextServerExtension::font_get_script_support_overrides(RID p_font_rid) { - Vector<String> ret; - if (GDVIRTUAL_CALL(_font_get_script_support_overrides, p_font_rid, ret)) { +PackedStringArray TextServerExtension::font_get_script_support_overrides(const RID &p_font_rid) { + PackedStringArray ret; + if (GDVIRTUAL_CALL(font_get_script_support_overrides, p_font_rid, ret)) { return ret; } - return Vector<String>(); + return PackedStringArray(); } -void TextServerExtension::font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) { - GDVIRTUAL_CALL(_font_set_opentype_feature_overrides, p_font_rid, p_overrides); +void TextServerExtension::font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) { + GDVIRTUAL_CALL(font_set_opentype_feature_overrides, p_font_rid, p_overrides); } -Dictionary TextServerExtension::font_get_opentype_feature_overrides(RID p_font_rid) const { +Dictionary TextServerExtension::font_get_opentype_feature_overrides(const RID &p_font_rid) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_get_opentype_feature_overrides, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_get_opentype_feature_overrides, p_font_rid, ret)) { return ret; } return Dictionary(); } -Dictionary TextServerExtension::font_supported_feature_list(RID p_font_rid) const { +Dictionary TextServerExtension::font_supported_feature_list(const RID &p_font_rid) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_supported_feature_list, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_supported_feature_list, p_font_rid, ret)) { return ret; } return Dictionary(); } -Dictionary TextServerExtension::font_supported_variation_list(RID p_font_rid) const { +Dictionary TextServerExtension::font_supported_variation_list(const RID &p_font_rid) const { Dictionary ret; - if (GDVIRTUAL_CALL(_font_supported_variation_list, p_font_rid, ret)) { + if (GDVIRTUAL_CALL(font_supported_variation_list, p_font_rid, ret)) { return ret; } return Dictionary(); } -float TextServerExtension::font_get_global_oversampling() const { - float ret; - if (GDVIRTUAL_CALL(_font_get_global_oversampling, ret)) { +double TextServerExtension::font_get_global_oversampling() const { + double ret; + if (GDVIRTUAL_CALL(font_get_global_oversampling, ret)) { return ret; } - return 0.f; + return 0.0; } -void TextServerExtension::font_set_global_oversampling(float p_oversampling) { - GDVIRTUAL_CALL(_font_set_global_oversampling, p_oversampling); +void TextServerExtension::font_set_global_oversampling(double p_oversampling) { + GDVIRTUAL_CALL(font_set_global_oversampling, p_oversampling); } -Vector2 TextServerExtension::get_hex_code_box_size(int p_size, char32_t p_index) const { +Vector2 TextServerExtension::get_hex_code_box_size(int64_t p_size, int64_t p_index) const { Vector2 ret; - if (GDVIRTUAL_CALL(_get_hex_code_box_size, p_size, p_index, ret)) { + if (GDVIRTUAL_CALL(get_hex_code_box_size, p_size, p_index, ret)) { return ret; } return TextServer::get_hex_code_box_size(p_size, p_index); } -void TextServerExtension::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const { - if (!GDVIRTUAL_CALL(_draw_hex_code_box, p_canvas, p_size, p_pos, p_index, p_color)) { +void TextServerExtension::draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { + if (!GDVIRTUAL_CALL(draw_hex_code_box, p_canvas, p_size, p_pos, p_index, p_color)) { TextServer::draw_hex_code_box(p_canvas, p_size, p_pos, p_index, p_color); } } @@ -955,433 +987,425 @@ void TextServerExtension::draw_hex_code_box(RID p_canvas, int p_size, const Vect RID TextServerExtension::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) { RID ret; - if (GDVIRTUAL_CALL(_create_shaped_text, p_direction, p_orientation, ret)) { + if (GDVIRTUAL_CALL(create_shaped_text, p_direction, p_orientation, ret)) { return ret; } return RID(); } -void TextServerExtension::shaped_text_clear(RID p_shaped) { - GDVIRTUAL_CALL(_shaped_text_clear, p_shaped); +void TextServerExtension::shaped_text_clear(const RID &p_shaped) { + GDVIRTUAL_CALL(shaped_text_clear, p_shaped); } -void TextServerExtension::shaped_text_set_direction(RID p_shaped, TextServer::Direction p_direction) { - GDVIRTUAL_CALL(_shaped_text_set_direction, p_shaped, p_direction); +void TextServerExtension::shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) { + GDVIRTUAL_CALL(shaped_text_set_direction, p_shaped, p_direction); } -TextServer::Direction TextServerExtension::shaped_text_get_direction(RID p_shaped) const { +TextServer::Direction TextServerExtension::shaped_text_get_direction(const RID &p_shaped) const { TextServer::Direction ret; - if (GDVIRTUAL_CALL(_shaped_text_get_direction, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_direction, p_shaped, ret)) { return (TextServer::Direction)ret; } return TextServer::Direction::DIRECTION_AUTO; } -TextServer::Direction TextServerExtension::shaped_text_get_inferred_direction(RID p_shaped) const { +TextServer::Direction TextServerExtension::shaped_text_get_inferred_direction(const RID &p_shaped) const { TextServer::Direction ret; - if (GDVIRTUAL_CALL(_shaped_text_get_inferred_direction, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_inferred_direction, p_shaped, ret)) { return (TextServer::Direction)ret; } return TextServer::Direction::DIRECTION_LTR; } -void TextServerExtension::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) { - GDVIRTUAL_CALL(_shaped_text_set_orientation, p_shaped, p_orientation); +void TextServerExtension::shaped_text_set_orientation(const RID &p_shaped, TextServer::Orientation p_orientation) { + GDVIRTUAL_CALL(shaped_text_set_orientation, p_shaped, p_orientation); } -TextServer::Orientation TextServerExtension::shaped_text_get_orientation(RID p_shaped) const { +TextServer::Orientation TextServerExtension::shaped_text_get_orientation(const RID &p_shaped) const { TextServer::Orientation ret; - if (GDVIRTUAL_CALL(_shaped_text_get_orientation, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_orientation, p_shaped, ret)) { return (TextServer::Orientation)ret; } return TextServer::Orientation::ORIENTATION_HORIZONTAL; } -void TextServerExtension::shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) { - GDVIRTUAL_CALL(_shaped_text_set_bidi_override, p_shaped, p_override); +void TextServerExtension::shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) { + GDVIRTUAL_CALL(shaped_text_set_bidi_override, p_shaped, p_override); } -void TextServerExtension::shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) { - GDVIRTUAL_CALL(_shaped_text_set_custom_punctuation, p_shaped, p_punct); +void TextServerExtension::shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) { + GDVIRTUAL_CALL(shaped_text_set_custom_punctuation, p_shaped, p_punct); } -String TextServerExtension::shaped_text_get_custom_punctuation(RID p_shaped) const { +String TextServerExtension::shaped_text_get_custom_punctuation(const RID &p_shaped) const { String ret; - if (GDVIRTUAL_CALL(_shaped_text_get_custom_punctuation, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_custom_punctuation, p_shaped, ret)) { return ret; } return String(); } -void TextServerExtension::shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) { - GDVIRTUAL_CALL(_shaped_text_set_preserve_invalid, p_shaped, p_enabled); +void TextServerExtension::shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) { + GDVIRTUAL_CALL(shaped_text_set_preserve_invalid, p_shaped, p_enabled); } -bool TextServerExtension::shaped_text_get_preserve_invalid(RID p_shaped) const { +bool TextServerExtension::shaped_text_get_preserve_invalid(const RID &p_shaped) const { bool ret; - if (GDVIRTUAL_CALL(_shaped_text_get_preserve_invalid, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_preserve_invalid, p_shaped, ret)) { return ret; } return false; } -void TextServerExtension::shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) { - GDVIRTUAL_CALL(_shaped_text_set_preserve_control, p_shaped, p_enabled); +void TextServerExtension::shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) { + GDVIRTUAL_CALL(shaped_text_set_preserve_control, p_shaped, p_enabled); } -bool TextServerExtension::shaped_text_get_preserve_control(RID p_shaped) const { +bool TextServerExtension::shaped_text_get_preserve_control(const RID &p_shaped) const { bool ret; - if (GDVIRTUAL_CALL(_shaped_text_get_preserve_control, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_preserve_control, p_shaped, ret)) { return ret; } return false; } -bool TextServerExtension::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { +bool TextServerExtension::shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) { bool ret; - Array fonts; - for (int i = 0; i < p_fonts.size(); i++) { - fonts.push_back(p_fonts[i]); - } - if (GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, fonts, p_size, p_opentype_features, p_language, p_meta, ret)) { + if (GDVIRTUAL_CALL(shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret)) { return ret; } return false; } -bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) { +bool TextServerExtension::shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length) { bool ret; - if (GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, ret)) { + if (GDVIRTUAL_CALL(shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, ret)) { return ret; } return false; } -bool TextServerExtension::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) { +bool TextServerExtension::shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align) { bool ret; - if (GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, ret)) { + if (GDVIRTUAL_CALL(shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, ret)) { return ret; } return false; } -int TextServerExtension::shaped_get_span_count(RID p_shaped) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_get_span_count, p_shaped, ret)) { +int64_t TextServerExtension::shaped_get_span_count(const RID &p_shaped) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_get_span_count, p_shaped, ret)) { return ret; } return 0; } -Variant TextServerExtension::shaped_get_span_meta(RID p_shaped, int p_index) const { +Variant TextServerExtension::shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const { Variant ret; - if (GDVIRTUAL_CALL(_shaped_get_span_meta, p_shaped, p_index, ret)) { + if (GDVIRTUAL_CALL(shaped_get_span_meta, p_shaped, p_index, ret)) { return ret; } return false; } -void TextServerExtension::shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features) { - Array fonts; - for (int i = 0; i < p_fonts.size(); i++) { - fonts.push_back(p_fonts[i]); - } - GDVIRTUAL_CALL(_shaped_set_span_update_font, p_shaped, p_index, fonts, p_size, p_opentype_features); +void TextServerExtension::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) { + GDVIRTUAL_CALL(shaped_set_span_update_font, p_shaped, p_index, p_fonts, p_size, p_opentype_features); } -RID TextServerExtension::shaped_text_substr(RID p_shaped, int p_start, int p_length) const { +RID TextServerExtension::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const { RID ret; - if (GDVIRTUAL_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret)) { + if (GDVIRTUAL_CALL(shaped_text_substr, p_shaped, p_start, p_length, ret)) { return ret; } return RID(); } -RID TextServerExtension::shaped_text_get_parent(RID p_shaped) const { +RID TextServerExtension::shaped_text_get_parent(const RID &p_shaped) const { RID ret; - if (GDVIRTUAL_CALL(_shaped_text_get_parent, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_parent, p_shaped, ret)) { return ret; } return RID(); } -float TextServerExtension::shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t p_jst_flags) { - float ret; - if (GDVIRTUAL_CALL(_shaped_text_fit_to_width, p_shaped, p_width, p_jst_flags, ret)) { +double TextServerExtension::shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t p_jst_flags) { + double ret; + if (GDVIRTUAL_CALL(shaped_text_fit_to_width, p_shaped, p_width, p_jst_flags, ret)) { return ret; } - return 0.f; + return 0.0; } -float TextServerExtension::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) { - float ret; - if (GDVIRTUAL_CALL(_shaped_text_tab_align, p_shaped, p_tab_stops, ret)) { +double TextServerExtension::shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) { + double ret; + if (GDVIRTUAL_CALL(shaped_text_tab_align, p_shaped, p_tab_stops, ret)) { return ret; } - return 0.f; + return 0.0; } -bool TextServerExtension::shaped_text_shape(RID p_shaped) { +bool TextServerExtension::shaped_text_shape(const RID &p_shaped) { bool ret; - if (GDVIRTUAL_CALL(_shaped_text_shape, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_shape, p_shaped, ret)) { return ret; } return false; } -bool TextServerExtension::shaped_text_update_breaks(RID p_shaped) { +bool TextServerExtension::shaped_text_update_breaks(const RID &p_shaped) { bool ret; - if (GDVIRTUAL_CALL(_shaped_text_update_breaks, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_update_breaks, p_shaped, ret)) { return ret; } return false; } -bool TextServerExtension::shaped_text_update_justification_ops(RID p_shaped) { +bool TextServerExtension::shaped_text_update_justification_ops(const RID &p_shaped) { bool ret; - if (GDVIRTUAL_CALL(_shaped_text_update_justification_ops, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_update_justification_ops, p_shaped, ret)) { return ret; } return false; } -bool TextServerExtension::shaped_text_is_ready(RID p_shaped) const { +bool TextServerExtension::shaped_text_is_ready(const RID &p_shaped) const { bool ret; - if (GDVIRTUAL_CALL(_shaped_text_is_ready, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_is_ready, p_shaped, ret)) { return ret; } return false; } -const Glyph *TextServerExtension::shaped_text_get_glyphs(RID p_shaped) const { - GDNativePtr<Glyph> ret; - if (GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, ret)) { +const Glyph *TextServerExtension::shaped_text_get_glyphs(const RID &p_shaped) const { + GDNativeConstPtr<const Glyph> ret; + if (GDVIRTUAL_CALL(shaped_text_get_glyphs, p_shaped, ret)) { return ret; } return nullptr; } -const Glyph *TextServerExtension::shaped_text_sort_logical(RID p_shaped) { - GDNativePtr<Glyph> ret; - if (GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, ret)) { +const Glyph *TextServerExtension::shaped_text_sort_logical(const RID &p_shaped) { + GDNativeConstPtr<const Glyph> ret; + if (GDVIRTUAL_CALL(shaped_text_sort_logical, p_shaped, ret)) { return ret; } return nullptr; } -int TextServerExtension::shaped_text_get_glyph_count(RID p_shaped) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_get_glyph_count, p_shaped, ret)) { +int64_t TextServerExtension::shaped_text_get_glyph_count(const RID &p_shaped) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_get_glyph_count, p_shaped, ret)) { return ret; } return 0; } -Vector2i TextServerExtension::shaped_text_get_range(RID p_shaped) const { +Vector2i TextServerExtension::shaped_text_get_range(const RID &p_shaped) const { Vector2i ret; - if (GDVIRTUAL_CALL(_shaped_text_get_range, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_range, p_shaped, ret)) { return ret; } return Vector2i(); } -PackedInt32Array TextServerExtension::shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint16_t p_break_flags) const { +PackedInt32Array TextServerExtension::shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start, bool p_once, int64_t p_break_flags) const { PackedInt32Array ret; - if (GDVIRTUAL_CALL(_shaped_text_get_line_breaks_adv, p_shaped, p_width, p_start, p_once, p_break_flags, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_line_breaks_adv, p_shaped, p_width, p_start, p_once, p_break_flags, ret)) { return ret; } return TextServer::shaped_text_get_line_breaks_adv(p_shaped, p_width, p_start, p_once, p_break_flags); } -PackedInt32Array TextServerExtension::shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start, uint16_t p_break_flags) const { +PackedInt32Array TextServerExtension::shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start, int64_t p_break_flags) const { PackedInt32Array ret; - if (GDVIRTUAL_CALL(_shaped_text_get_line_breaks, p_shaped, p_width, p_start, p_break_flags, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_line_breaks, p_shaped, p_width, p_start, p_break_flags, ret)) { return ret; } return TextServer::shaped_text_get_line_breaks(p_shaped, p_width, p_start, p_break_flags); } -PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const { +PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags) const { PackedInt32Array ret; - if (GDVIRTUAL_CALL(_shaped_text_get_word_breaks, p_shaped, p_grapheme_flags, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_word_breaks, p_shaped, p_grapheme_flags, ret)) { return ret; } return TextServer::shaped_text_get_word_breaks(p_shaped, p_grapheme_flags); } -int TextServerExtension::shaped_text_get_trim_pos(RID p_shaped) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_get_trim_pos, p_shaped, ret)) { +int64_t TextServerExtension::shaped_text_get_trim_pos(const RID &p_shaped) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_get_trim_pos, p_shaped, ret)) { return ret; } return -1; } -int TextServerExtension::shaped_text_get_ellipsis_pos(RID p_shaped) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret)) { +int64_t TextServerExtension::shaped_text_get_ellipsis_pos(const RID &p_shaped) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_get_ellipsis_pos, p_shaped, ret)) { return ret; } return -1; } -const Glyph *TextServerExtension::shaped_text_get_ellipsis_glyphs(RID p_shaped) const { - GDNativePtr<Glyph> ret; - if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, ret)) { +const Glyph *TextServerExtension::shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const { + GDNativeConstPtr<const Glyph> ret; + if (GDVIRTUAL_CALL(shaped_text_get_ellipsis_glyphs, p_shaped, ret)) { return ret; } return nullptr; } -int TextServerExtension::shaped_text_get_ellipsis_glyph_count(RID p_shaped) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret)) { +int64_t TextServerExtension::shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_get_ellipsis_glyph_count, p_shaped, ret)) { return ret; } return -1; } -void TextServerExtension::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint16_t p_trim_flags) { - GDVIRTUAL_CALL(_shaped_text_overrun_trim_to_width, p_shaped_line, p_width, p_trim_flags); +void TextServerExtension::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, int64_t p_trim_flags) { + GDVIRTUAL_CALL(shaped_text_overrun_trim_to_width, p_shaped_line, p_width, p_trim_flags); } -Array TextServerExtension::shaped_text_get_objects(RID p_shaped) const { +Array TextServerExtension::shaped_text_get_objects(const RID &p_shaped) const { Array ret; - if (GDVIRTUAL_CALL(_shaped_text_get_objects, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_objects, p_shaped, ret)) { return ret; } return Array(); } -Rect2 TextServerExtension::shaped_text_get_object_rect(RID p_shaped, Variant p_key) const { +Rect2 TextServerExtension::shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const { Rect2 ret; - if (GDVIRTUAL_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_object_rect, p_shaped, p_key, ret)) { return ret; } return Rect2(); } -Size2 TextServerExtension::shaped_text_get_size(RID p_shaped) const { +Size2 TextServerExtension::shaped_text_get_size(const RID &p_shaped) const { Size2 ret; - if (GDVIRTUAL_CALL(_shaped_text_get_size, p_shaped, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_size, p_shaped, ret)) { return ret; } return Size2(); } -float TextServerExtension::shaped_text_get_ascent(RID p_shaped) const { - float ret; - if (GDVIRTUAL_CALL(_shaped_text_get_ascent, p_shaped, ret)) { +double TextServerExtension::shaped_text_get_ascent(const RID &p_shaped) const { + double ret; + if (GDVIRTUAL_CALL(shaped_text_get_ascent, p_shaped, ret)) { return ret; } - return 0.f; + return 0.0; } -float TextServerExtension::shaped_text_get_descent(RID p_shaped) const { - float ret; - if (GDVIRTUAL_CALL(_shaped_text_get_descent, p_shaped, ret)) { +double TextServerExtension::shaped_text_get_descent(const RID &p_shaped) const { + double ret; + if (GDVIRTUAL_CALL(shaped_text_get_descent, p_shaped, ret)) { return ret; } - return 0.f; + return 0.0; } -float TextServerExtension::shaped_text_get_width(RID p_shaped) const { - float ret; - if (GDVIRTUAL_CALL(_shaped_text_get_width, p_shaped, ret)) { +double TextServerExtension::shaped_text_get_width(const RID &p_shaped) const { + double ret; + if (GDVIRTUAL_CALL(shaped_text_get_width, p_shaped, ret)) { return ret; } - return 0.f; + return 0.0; } -float TextServerExtension::shaped_text_get_underline_position(RID p_shaped) const { - float ret; - if (GDVIRTUAL_CALL(_shaped_text_get_underline_position, p_shaped, ret)) { +double TextServerExtension::shaped_text_get_underline_position(const RID &p_shaped) const { + double ret; + if (GDVIRTUAL_CALL(shaped_text_get_underline_position, p_shaped, ret)) { return ret; } - return 0.f; + return 0.0; } -float TextServerExtension::shaped_text_get_underline_thickness(RID p_shaped) const { - float ret; - if (GDVIRTUAL_CALL(_shaped_text_get_underline_thickness, p_shaped, ret)) { +double TextServerExtension::shaped_text_get_underline_thickness(const RID &p_shaped) const { + double ret; + if (GDVIRTUAL_CALL(shaped_text_get_underline_thickness, p_shaped, ret)) { return ret; } - return 0.f; + return 0.0; } -TextServer::Direction TextServerExtension::shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_get_dominant_direction_in_range, p_shaped, p_start, p_end, ret)) { +TextServer::Direction TextServerExtension::shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_get_dominant_direction_in_range, p_shaped, p_start, p_end, ret)) { return (TextServer::Direction)ret; } return TextServer::shaped_text_get_dominant_direction_in_range(p_shaped, p_start, p_end); } -CaretInfo TextServerExtension::shaped_text_get_carets(RID p_shaped, int p_position) const { +CaretInfo TextServerExtension::shaped_text_get_carets(const RID &p_shaped, int64_t p_position) const { CaretInfo ret; - if (GDVIRTUAL_CALL(_shaped_text_get_carets, p_shaped, p_position, &ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_carets, p_shaped, p_position, &ret)) { return ret; } return TextServer::shaped_text_get_carets(p_shaped, p_position); } -Vector<Vector2> TextServerExtension::shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const { +Vector<Vector2> TextServerExtension::shaped_text_get_selection(const RID &p_shaped, int64_t p_start, int64_t p_end) const { Vector<Vector2> ret; - if (GDVIRTUAL_CALL(_shaped_text_get_selection, p_shaped, p_start, p_end, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_selection, p_shaped, p_start, p_end, ret)) { return ret; } return TextServer::shaped_text_get_selection(p_shaped, p_start, p_end); } -int TextServerExtension::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_hit_test_grapheme, p_shaped, p_coords, ret)) { +int64_t TextServerExtension::shaped_text_hit_test_grapheme(const RID &p_shaped, double p_coords) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_hit_test_grapheme, p_shaped, p_coords, ret)) { return ret; } return TextServer::shaped_text_hit_test_grapheme(p_shaped, p_coords); } -int TextServerExtension::shaped_text_hit_test_position(RID p_shaped, float p_coords) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_hit_test_position, p_shaped, p_coords, ret)) { +int64_t TextServerExtension::shaped_text_hit_test_position(const RID &p_shaped, double p_coords) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_hit_test_position, p_shaped, p_coords, ret)) { return ret; } return TextServer::shaped_text_hit_test_position(p_shaped, p_coords); } -void TextServerExtension::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, const Color &p_color) const { - if (GDVIRTUAL_CALL(_shaped_text_draw, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color)) { +void TextServerExtension::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color) const { + if (GDVIRTUAL_CALL(shaped_text_draw, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color)) { return; } TextServer::shaped_text_draw(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color); } -void TextServerExtension::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, int p_outline_size, const Color &p_color) const { - if (GDVIRTUAL_CALL(_shaped_text_draw_outline, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color)) { +void TextServerExtension::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, int64_t p_outline_size, const Color &p_color) const { + if (GDVIRTUAL_CALL(shaped_text_draw_outline, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color)) { return; } - shaped_text_draw_outline(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color); + TextServer::shaped_text_draw_outline(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color); } -Vector2 TextServerExtension::shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) const { +Vector2 TextServerExtension::shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const { Vector2 ret; - if (GDVIRTUAL_CALL(_shaped_text_get_grapheme_bounds, p_shaped, p_pos, ret)) { + if (GDVIRTUAL_CALL(shaped_text_get_grapheme_bounds, p_shaped, p_pos, ret)) { return ret; } return TextServer::shaped_text_get_grapheme_bounds(p_shaped, p_pos); } -int TextServerExtension::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_next_grapheme_pos, p_shaped, p_pos, ret)) { +int64_t TextServerExtension::shaped_text_next_grapheme_pos(const RID &p_shaped, int64_t p_pos) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_next_grapheme_pos, p_shaped, p_pos, ret)) { return ret; } return TextServer::shaped_text_next_grapheme_pos(p_shaped, p_pos); } -int TextServerExtension::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const { - int ret; - if (GDVIRTUAL_CALL(_shaped_text_prev_grapheme_pos, p_shaped, p_pos, ret)) { +int64_t TextServerExtension::shaped_text_prev_grapheme_pos(const RID &p_shaped, int64_t p_pos) const { + int64_t ret; + if (GDVIRTUAL_CALL(shaped_text_prev_grapheme_pos, p_shaped, p_pos, ret)) { return ret; } return TextServer::shaped_text_prev_grapheme_pos(p_shaped, p_pos); @@ -1389,31 +1413,39 @@ int TextServerExtension::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) String TextServerExtension::format_number(const String &p_string, const String &p_language) const { String ret; - if (GDVIRTUAL_CALL(_format_number, p_string, p_language, ret)) { + if (GDVIRTUAL_CALL(format_number, p_string, p_language, ret)) { return ret; } - return TextServer::format_number(p_string, p_language); + return p_string; } String TextServerExtension::parse_number(const String &p_string, const String &p_language) const { String ret; - if (GDVIRTUAL_CALL(_parse_number, p_string, p_language, ret)) { + if (GDVIRTUAL_CALL(parse_number, p_string, p_language, ret)) { return ret; } - return TextServer::parse_number(p_string, p_language); + return p_string; } String TextServerExtension::percent_sign(const String &p_language) const { String ret; - if (GDVIRTUAL_CALL(_percent_sign, p_language, ret)) { + if (GDVIRTUAL_CALL(percent_sign, p_language, ret)) { + return ret; + } + return "%"; +} + +String TextServerExtension::strip_diacritics(const String &p_string) const { + String ret; + if (GDVIRTUAL_CALL(strip_diacritics, p_string, ret)) { return ret; } - return TextServer::percent_sign(p_language); + return TextServer::strip_diacritics(p_string); } String TextServerExtension::string_to_upper(const String &p_string, const String &p_language) const { String ret; - if (GDVIRTUAL_CALL(_string_to_upper, p_string, p_language, ret)) { + if (GDVIRTUAL_CALL(string_to_upper, p_string, p_language, ret)) { return ret; } return p_string; @@ -1421,7 +1453,7 @@ String TextServerExtension::string_to_upper(const String &p_string, const String String TextServerExtension::string_to_lower(const String &p_string, const String &p_language) const { String ret; - if (GDVIRTUAL_CALL(_string_to_lower, p_string, p_language, ret)) { + if (GDVIRTUAL_CALL(string_to_lower, p_string, p_language, ret)) { return ret; } return p_string; diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index d185e44806..c6e7bef4e8 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -48,423 +48,436 @@ protected: public: virtual bool has_feature(Feature p_feature) const override; virtual String get_name() const override; - virtual uint32_t get_features() const override; - GDVIRTUAL1RC(bool, _has_feature, Feature); - GDVIRTUAL0RC(String, _get_name); - GDVIRTUAL0RC(uint32_t, _get_features); + virtual int64_t get_features() const override; + GDVIRTUAL1RC(bool, has_feature, Feature); + GDVIRTUAL0RC(String, get_name); + GDVIRTUAL0RC(int64_t, get_features); - virtual void free(RID p_rid) override; - virtual bool has(RID p_rid) override; + virtual void free_rid(const RID &p_rid) override; + virtual bool has(const RID &p_rid) override; virtual bool load_support_data(const String &p_filename) override; - GDVIRTUAL1(_free, RID); - GDVIRTUAL1R(bool, _has, RID); - GDVIRTUAL1R(bool, _load_support_data, const String &); + GDVIRTUAL1(free_rid, RID); + GDVIRTUAL1R(bool, has, RID); + GDVIRTUAL1R(bool, load_support_data, const String &); virtual String get_support_data_filename() const override; virtual String get_support_data_info() const override; virtual bool save_support_data(const String &p_filename) const override; - GDVIRTUAL0RC(String, _get_support_data_filename); - GDVIRTUAL0RC(String, _get_support_data_info); - GDVIRTUAL1RC(bool, _save_support_data, const String &); + GDVIRTUAL0RC(String, get_support_data_filename); + GDVIRTUAL0RC(String, get_support_data_info); + GDVIRTUAL1RC(bool, save_support_data, const String &); virtual bool is_locale_right_to_left(const String &p_locale) const override; - GDVIRTUAL1RC(bool, _is_locale_right_to_left, const String &); + GDVIRTUAL1RC(bool, is_locale_right_to_left, const String &); - virtual int32_t name_to_tag(const String &p_name) const override; - virtual String tag_to_name(int32_t p_tag) const override; - GDVIRTUAL1RC(int32_t, _name_to_tag, const String &); - GDVIRTUAL1RC(String, _tag_to_name, int32_t); + virtual int64_t name_to_tag(const String &p_name) const override; + virtual String tag_to_name(int64_t p_tag) const override; + GDVIRTUAL1RC(int64_t, name_to_tag, const String &); + GDVIRTUAL1RC(String, tag_to_name, int64_t); /* Font interface */ virtual RID create_font() override; - GDVIRTUAL0R(RID, _create_font); - - virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) override; - virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) override; - GDVIRTUAL2(_font_set_data, RID, const PackedByteArray &); - GDVIRTUAL3(_font_set_data_ptr, RID, GDNativeConstPtr<const uint8_t>, uint64_t); - - virtual void font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) override; - virtual uint32_t /*FontStyle*/ font_get_style(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_style, RID, uint32_t); - GDVIRTUAL1RC(uint32_t, _font_get_style, RID); - - virtual void font_set_name(RID p_font_rid, const String &p_name) override; - virtual String font_get_name(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_name, RID, const String &); - GDVIRTUAL1RC(String, _font_get_name, RID); - - virtual void font_set_style_name(RID p_font_rid, const String &p_name) override; - virtual String font_get_style_name(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_style_name, RID, const String &); - GDVIRTUAL1RC(String, _font_get_style_name, RID); - - virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override; - virtual bool font_is_antialiased(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_antialiased, RID, bool); - GDVIRTUAL1RC(bool, _font_is_antialiased, RID); - - virtual void font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) override; - virtual bool font_is_multichannel_signed_distance_field(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_multichannel_signed_distance_field, RID, bool); - GDVIRTUAL1RC(bool, _font_is_multichannel_signed_distance_field, RID); - - virtual void font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) override; - virtual int font_get_msdf_pixel_range(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_msdf_pixel_range, RID, int); - GDVIRTUAL1RC(int, _font_get_msdf_pixel_range, RID); - - virtual void font_set_msdf_size(RID p_font_rid, int p_msdf_size) override; - virtual int font_get_msdf_size(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_msdf_size, RID, int); - GDVIRTUAL1RC(int, _font_get_msdf_size, RID); - - virtual void font_set_fixed_size(RID p_font_rid, int p_fixed_size) override; - virtual int font_get_fixed_size(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_fixed_size, RID, int); - GDVIRTUAL1RC(int, _font_get_fixed_size, RID); - - virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) override; - virtual bool font_is_force_autohinter(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_force_autohinter, RID, bool); - GDVIRTUAL1RC(bool, _font_is_force_autohinter, RID); - - virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) override; - virtual Hinting font_get_hinting(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_hinting, RID, Hinting); - GDVIRTUAL1RC(Hinting, _font_get_hinting, RID); - - virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) override; - virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_subpixel_positioning, RID, SubpixelPositioning); - GDVIRTUAL1RC(SubpixelPositioning, _font_get_subpixel_positioning, RID); - - virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override; - virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_variation_coordinates, RID, Dictionary); - GDVIRTUAL1RC(Dictionary, _font_get_variation_coordinates, RID); - - virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override; - virtual float font_get_oversampling(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_oversampling, RID, float); - GDVIRTUAL1RC(float, _font_get_oversampling, RID); - - virtual Array font_get_size_cache_list(RID p_font_rid) const override; - virtual void font_clear_size_cache(RID p_font_rid) override; - virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) override; - GDVIRTUAL1RC(Array, _font_get_size_cache_list, RID); - GDVIRTUAL1(_font_clear_size_cache, RID); - GDVIRTUAL2(_font_remove_size_cache, RID, const Vector2i &); - - virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) override; - virtual float font_get_ascent(RID p_font_rid, int p_size) const override; - GDVIRTUAL3(_font_set_ascent, RID, int, float); - GDVIRTUAL2RC(float, _font_get_ascent, RID, int); - - virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) override; - virtual float font_get_descent(RID p_font_rid, int p_size) const override; - GDVIRTUAL3(_font_set_descent, RID, int, float); - GDVIRTUAL2RC(float, _font_get_descent, RID, int); - - virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) override; - virtual float font_get_underline_position(RID p_font_rid, int p_size) const override; - GDVIRTUAL3(_font_set_underline_position, RID, int, float); - GDVIRTUAL2RC(float, _font_get_underline_position, RID, int); - - virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) override; - virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const override; - GDVIRTUAL3(_font_set_underline_thickness, RID, int, float); - GDVIRTUAL2RC(float, _font_get_underline_thickness, RID, int); - - virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) override; - virtual float font_get_scale(RID p_font_rid, int p_size) const override; - GDVIRTUAL3(_font_set_scale, RID, int, float); - GDVIRTUAL2RC(float, _font_get_scale, RID, int); - - virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override; - virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override; - GDVIRTUAL4(_font_set_spacing, RID, int, SpacingType, int); - GDVIRTUAL3RC(int, _font_get_spacing, RID, int, SpacingType); - - virtual int font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const override; - virtual void font_clear_textures(RID p_font_rid, const Vector2i &p_size) override; - virtual void font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) override; - GDVIRTUAL2RC(int, _font_get_texture_count, RID, const Vector2i &); - GDVIRTUAL2(_font_clear_textures, RID, const Vector2i &); - GDVIRTUAL3(_font_remove_texture, RID, const Vector2i &, int); - - virtual void font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) override; - virtual Ref<Image> font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override; - GDVIRTUAL4(_font_set_texture_image, RID, const Vector2i &, int, const Ref<Image> &); - GDVIRTUAL3RC(Ref<Image>, _font_get_texture_image, RID, const Vector2i &, int); - - virtual void font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) override; - virtual PackedInt32Array font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override; - GDVIRTUAL4(_font_set_texture_offsets, RID, const Vector2i &, int, const PackedInt32Array &); - GDVIRTUAL3RC(PackedInt32Array, _font_get_texture_offsets, RID, const Vector2i &, int); - - virtual Array font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const override; - virtual void font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) override; - virtual void font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) override; - GDVIRTUAL2RC(Array, _font_get_glyph_list, RID, const Vector2i &); - GDVIRTUAL2(_font_clear_glyphs, RID, const Vector2i &); - GDVIRTUAL3(_font_remove_glyph, RID, const Vector2i &, int32_t); - - virtual Vector2 font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) override; - GDVIRTUAL3RC(Vector2, _font_get_glyph_advance, RID, int, int32_t); - GDVIRTUAL4(_font_set_glyph_advance, RID, int, int32_t, const Vector2 &); - - virtual Vector2 font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) override; - GDVIRTUAL3RC(Vector2, _font_get_glyph_offset, RID, const Vector2i &, int32_t); - GDVIRTUAL4(_font_set_glyph_offset, RID, const Vector2i &, int32_t, const Vector2 &); - - virtual Vector2 font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) override; - GDVIRTUAL3RC(Vector2, _font_get_glyph_size, RID, const Vector2i &, int32_t); - GDVIRTUAL4(_font_set_glyph_size, RID, const Vector2i &, int32_t, const Vector2 &); - - virtual Rect2 font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) override; - GDVIRTUAL3RC(Rect2, _font_get_glyph_uv_rect, RID, const Vector2i &, int32_t); - GDVIRTUAL4(_font_set_glyph_uv_rect, RID, const Vector2i &, int32_t, const Rect2 &); - - virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override; - virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override; - GDVIRTUAL3RC(int, _font_get_glyph_texture_idx, RID, const Vector2i &, int32_t); - GDVIRTUAL4(_font_set_glyph_texture_idx, RID, const Vector2i &, int32_t, int); - - virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override; - GDVIRTUAL3RC(Dictionary, _font_get_glyph_contours, RID, int, int32_t); - - virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override; - virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override; - virtual void font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) override; - GDVIRTUAL2RC(Array, _font_get_kerning_list, RID, int); - GDVIRTUAL2(_font_clear_kerning_map, RID, int); - GDVIRTUAL3(_font_remove_kerning, RID, int, const Vector2i &); - - virtual void font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override; - virtual Vector2 font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const override; - GDVIRTUAL4(_font_set_kerning, RID, int, const Vector2i &, const Vector2 &); - GDVIRTUAL3RC(Vector2, _font_get_kerning, RID, int, const Vector2i &); - - virtual int32_t font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector = 0) const override; - GDVIRTUAL4RC(int32_t, _font_get_glyph_index, RID, int, char32_t, char32_t); - - virtual bool font_has_char(RID p_font_rid, char32_t p_char) const override; - virtual String font_get_supported_chars(RID p_font_rid) const override; - GDVIRTUAL2RC(bool, _font_has_char, RID, char32_t); - GDVIRTUAL1RC(String, _font_get_supported_chars, RID); - - virtual void font_render_range(RID p_font, const Vector2i &p_size, char32_t p_start, char32_t p_end) override; - virtual void font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) override; - GDVIRTUAL4(_font_render_range, RID, const Vector2i &, char32_t, char32_t); - GDVIRTUAL3(_font_render_glyph, RID, const Vector2i &, int32_t); - - virtual void font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override; - virtual void font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override; - GDVIRTUAL6C(_font_draw_glyph, RID, RID, int, const Vector2 &, int32_t, const Color &); - GDVIRTUAL7C(_font_draw_glyph_outline, RID, RID, int, int, const Vector2 &, int32_t, const Color &); - - virtual bool font_is_language_supported(RID p_font_rid, const String &p_language) const override; - virtual void font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) override; - virtual bool font_get_language_support_override(RID p_font_rid, const String &p_language) override; - virtual void font_remove_language_support_override(RID p_font_rid, const String &p_language) override; - virtual Vector<String> font_get_language_support_overrides(RID p_font_rid) override; - GDVIRTUAL2RC(bool, _font_is_language_supported, RID, const String &); - GDVIRTUAL3(_font_set_language_support_override, RID, const String &, bool); - GDVIRTUAL2R(bool, _font_get_language_support_override, RID, const String &); - GDVIRTUAL2(_font_remove_language_support_override, RID, const String &); - GDVIRTUAL1R(Vector<String>, _font_get_language_support_overrides, RID); - - virtual bool font_is_script_supported(RID p_font_rid, const String &p_script) const override; - virtual void font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) override; - virtual bool font_get_script_support_override(RID p_font_rid, const String &p_script) override; - virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override; - virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override; - GDVIRTUAL2RC(bool, _font_is_script_supported, RID, const String &); - GDVIRTUAL3(_font_set_script_support_override, RID, const String &, bool); - GDVIRTUAL2R(bool, _font_get_script_support_override, RID, const String &); - GDVIRTUAL2(_font_remove_script_support_override, RID, const String &); - GDVIRTUAL1R(Vector<String>, _font_get_script_support_overrides, RID); - - virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override; - virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override; - GDVIRTUAL2(_font_set_opentype_feature_overrides, RID, const Dictionary &); - GDVIRTUAL1RC(Dictionary, _font_get_opentype_feature_overrides, RID); - - virtual Dictionary font_supported_feature_list(RID p_font_rid) const override; - virtual Dictionary font_supported_variation_list(RID p_font_rid) const override; - GDVIRTUAL1RC(Dictionary, _font_supported_feature_list, RID); - GDVIRTUAL1RC(Dictionary, _font_supported_variation_list, RID); - - virtual float font_get_global_oversampling() const override; - virtual void font_set_global_oversampling(float p_oversampling) override; - GDVIRTUAL0RC(float, _font_get_global_oversampling); - GDVIRTUAL1(_font_set_global_oversampling, float); - - virtual Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const override; - virtual void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const override; - GDVIRTUAL2RC(Vector2, _get_hex_code_box_size, int, char32_t); - GDVIRTUAL5C(_draw_hex_code_box, RID, int, const Vector2 &, char32_t, const Color &); + GDVIRTUAL0R(RID, create_font); + + virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) override; + virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) override; + GDVIRTUAL2(font_set_data, RID, const PackedByteArray &); + GDVIRTUAL3(font_set_data_ptr, RID, GDNativeConstPtr<const uint8_t>, int64_t); + + virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) override; + virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_style, RID, int64_t); + GDVIRTUAL1RC(int64_t, font_get_style, RID); + + virtual void font_set_name(const RID &p_font_rid, const String &p_name) override; + virtual String font_get_name(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_name, RID, const String &); + GDVIRTUAL1RC(String, font_get_name, RID); + + virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) override; + virtual String font_get_style_name(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_style_name, RID, const String &); + GDVIRTUAL1RC(String, font_get_style_name, RID); + + virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override; + virtual bool font_is_antialiased(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_antialiased, RID, bool); + GDVIRTUAL1RC(bool, font_is_antialiased, RID); + + virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) override; + virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_multichannel_signed_distance_field, RID, bool); + GDVIRTUAL1RC(bool, font_is_multichannel_signed_distance_field, RID); + + virtual void font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) override; + virtual int64_t font_get_msdf_pixel_range(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_msdf_pixel_range, RID, int64_t); + GDVIRTUAL1RC(int64_t, font_get_msdf_pixel_range, RID); + + virtual void font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) override; + virtual int64_t font_get_msdf_size(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_msdf_size, RID, int64_t); + GDVIRTUAL1RC(int64_t, font_get_msdf_size, RID); + + virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) override; + virtual int64_t font_get_fixed_size(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_fixed_size, RID, int64_t); + GDVIRTUAL1RC(int64_t, font_get_fixed_size, RID); + + virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) override; + virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_subpixel_positioning, RID, SubpixelPositioning); + GDVIRTUAL1RC(SubpixelPositioning, font_get_subpixel_positioning, RID); + + virtual void font_set_embolden(const RID &p_font_rid, double p_strength) override; + virtual double font_get_embolden(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_embolden, RID, double); + GDVIRTUAL1RC(double, font_get_embolden, RID); + + virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) override; + virtual Transform2D font_get_transform(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_transform, RID, Transform2D); + GDVIRTUAL1RC(Transform2D, font_get_transform, RID); + + virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) override; + virtual bool font_is_force_autohinter(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_force_autohinter, RID, bool); + GDVIRTUAL1RC(bool, font_is_force_autohinter, RID); + + virtual void font_set_hinting(const RID &p_font_rid, Hinting p_hinting) override; + virtual Hinting font_get_hinting(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_hinting, RID, Hinting); + GDVIRTUAL1RC(Hinting, font_get_hinting, RID); + + virtual void font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) override; + virtual Dictionary font_get_variation_coordinates(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_variation_coordinates, RID, Dictionary); + GDVIRTUAL1RC(Dictionary, font_get_variation_coordinates, RID); + + virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) override; + virtual double font_get_oversampling(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_oversampling, RID, double); + GDVIRTUAL1RC(double, font_get_oversampling, RID); + + virtual Array font_get_size_cache_list(const RID &p_font_rid) const override; + virtual void font_clear_size_cache(const RID &p_font_rid) override; + virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override; + GDVIRTUAL1RC(Array, font_get_size_cache_list, RID); + GDVIRTUAL1(font_clear_size_cache, RID); + GDVIRTUAL2(font_remove_size_cache, RID, const Vector2i &); + + virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) override; + virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const override; + GDVIRTUAL3(font_set_ascent, RID, int64_t, double); + GDVIRTUAL2RC(double, font_get_ascent, RID, int64_t); + + virtual void font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) override; + virtual double font_get_descent(const RID &p_font_rid, int64_t p_size) const override; + GDVIRTUAL3(font_set_descent, RID, int64_t, double); + GDVIRTUAL2RC(double, font_get_descent, RID, int64_t); + + virtual void font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) override; + virtual double font_get_underline_position(const RID &p_font_rid, int64_t p_size) const override; + GDVIRTUAL3(font_set_underline_position, RID, int64_t, double); + GDVIRTUAL2RC(double, font_get_underline_position, RID, int64_t); + + virtual void font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) override; + virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const override; + GDVIRTUAL3(font_set_underline_thickness, RID, int64_t, double); + GDVIRTUAL2RC(double, font_get_underline_thickness, RID, int64_t); + + virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override; + virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override; + GDVIRTUAL3(font_set_scale, RID, int64_t, double); + GDVIRTUAL2RC(double, font_get_scale, RID, int64_t); + + virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) override; + virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const override; + GDVIRTUAL4(font_set_spacing, RID, int64_t, SpacingType, int64_t); + GDVIRTUAL3RC(int64_t, font_get_spacing, RID, int64_t, SpacingType); + + virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override; + virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override; + virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override; + GDVIRTUAL2RC(int64_t, font_get_texture_count, RID, const Vector2i &); + GDVIRTUAL2(font_clear_textures, RID, const Vector2i &); + GDVIRTUAL3(font_remove_texture, RID, const Vector2i &, int64_t); + + virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) override; + virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override; + GDVIRTUAL4(font_set_texture_image, RID, const Vector2i &, int64_t, const Ref<Image> &); + GDVIRTUAL3RC(Ref<Image>, font_get_texture_image, RID, const Vector2i &, int64_t); + + virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override; + virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override; + GDVIRTUAL4(font_set_texture_offsets, RID, const Vector2i &, int64_t, const PackedInt32Array &); + GDVIRTUAL3RC(PackedInt32Array, font_get_texture_offsets, RID, const Vector2i &, int64_t); + + virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override; + virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override; + virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override; + GDVIRTUAL2RC(Array, font_get_glyph_list, RID, const Vector2i &); + GDVIRTUAL2(font_clear_glyphs, RID, const Vector2i &); + GDVIRTUAL3(font_remove_glyph, RID, const Vector2i &, int64_t); + + virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const override; + virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) override; + GDVIRTUAL3RC(Vector2, font_get_glyph_advance, RID, int64_t, int64_t); + GDVIRTUAL4(font_set_glyph_advance, RID, int64_t, int64_t, const Vector2 &); + + virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) override; + GDVIRTUAL3RC(Vector2, font_get_glyph_offset, RID, const Vector2i &, int64_t); + GDVIRTUAL4(font_set_glyph_offset, RID, const Vector2i &, int64_t, const Vector2 &); + + virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) override; + GDVIRTUAL3RC(Vector2, font_get_glyph_size, RID, const Vector2i &, int64_t); + GDVIRTUAL4(font_set_glyph_size, RID, const Vector2i &, int64_t, const Vector2 &); + + virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) override; + GDVIRTUAL3RC(Rect2, font_get_glyph_uv_rect, RID, const Vector2i &, int64_t); + GDVIRTUAL4(font_set_glyph_uv_rect, RID, const Vector2i &, int64_t, const Rect2 &); + + virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override; + GDVIRTUAL3RC(int64_t, font_get_glyph_texture_idx, RID, const Vector2i &, int64_t); + GDVIRTUAL4(font_set_glyph_texture_idx, RID, const Vector2i &, int64_t, int64_t); + + virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override; + GDVIRTUAL3RC(Dictionary, font_get_glyph_contours, RID, int64_t, int64_t); + + virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; + virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) override; + virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) override; + GDVIRTUAL2RC(Array, font_get_kerning_list, RID, int64_t); + GDVIRTUAL2(font_clear_kerning_map, RID, int64_t); + GDVIRTUAL3(font_remove_kerning, RID, int64_t, const Vector2i &); + + virtual void font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override; + virtual Vector2 font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const override; + GDVIRTUAL4(font_set_kerning, RID, int64_t, const Vector2i &, const Vector2 &); + GDVIRTUAL3RC(Vector2, font_get_kerning, RID, int64_t, const Vector2i &); + + virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector = 0) const override; + GDVIRTUAL4RC(int64_t, font_get_glyph_index, RID, int64_t, int64_t, int64_t); + + virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override; + virtual String font_get_supported_chars(const RID &p_font_rid) const override; + GDVIRTUAL2RC(bool, font_has_char, RID, int64_t); + GDVIRTUAL1RC(String, font_get_supported_chars, RID); + + virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) override; + virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) override; + GDVIRTUAL4(font_render_range, RID, const Vector2i &, int64_t, int64_t); + GDVIRTUAL3(font_render_glyph, RID, const Vector2i &, int64_t); + + virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override; + virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override; + GDVIRTUAL6C(font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &); + GDVIRTUAL7C(font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &); + + virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const override; + virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) override; + virtual bool font_get_language_support_override(const RID &p_font_rid, const String &p_language) override; + virtual void font_remove_language_support_override(const RID &p_font_rid, const String &p_language) override; + virtual PackedStringArray font_get_language_support_overrides(const RID &p_font_rid) override; + GDVIRTUAL2RC(bool, font_is_language_supported, RID, const String &); + GDVIRTUAL3(font_set_language_support_override, RID, const String &, bool); + GDVIRTUAL2R(bool, font_get_language_support_override, RID, const String &); + GDVIRTUAL2(font_remove_language_support_override, RID, const String &); + GDVIRTUAL1R(PackedStringArray, font_get_language_support_overrides, RID); + + virtual bool font_is_script_supported(const RID &p_font_rid, const String &p_script) const override; + virtual void font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) override; + virtual bool font_get_script_support_override(const RID &p_font_rid, const String &p_script) override; + virtual void font_remove_script_support_override(const RID &p_font_rid, const String &p_script) override; + virtual PackedStringArray font_get_script_support_overrides(const RID &p_font_rid) override; + GDVIRTUAL2RC(bool, font_is_script_supported, RID, const String &); + GDVIRTUAL3(font_set_script_support_override, RID, const String &, bool); + GDVIRTUAL2R(bool, font_get_script_support_override, RID, const String &); + GDVIRTUAL2(font_remove_script_support_override, RID, const String &); + GDVIRTUAL1R(PackedStringArray, font_get_script_support_overrides, RID); + + virtual void font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) override; + virtual Dictionary font_get_opentype_feature_overrides(const RID &p_font_rid) const override; + GDVIRTUAL2(font_set_opentype_feature_overrides, RID, const Dictionary &); + GDVIRTUAL1RC(Dictionary, font_get_opentype_feature_overrides, RID); + + virtual Dictionary font_supported_feature_list(const RID &p_font_rid) const override; + virtual Dictionary font_supported_variation_list(const RID &p_font_rid) const override; + GDVIRTUAL1RC(Dictionary, font_supported_feature_list, RID); + GDVIRTUAL1RC(Dictionary, font_supported_variation_list, RID); + + virtual double font_get_global_oversampling() const override; + virtual void font_set_global_oversampling(double p_oversampling) override; + GDVIRTUAL0RC(double, font_get_global_oversampling); + GDVIRTUAL1(font_set_global_oversampling, double); + + virtual Vector2 get_hex_code_box_size(int64_t p_size, int64_t p_index) const override; + virtual void draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const override; + GDVIRTUAL2RC(Vector2, get_hex_code_box_size, int64_t, int64_t); + GDVIRTUAL5C(draw_hex_code_box, RID, int64_t, const Vector2 &, int64_t, const Color &); /* Shaped text buffer interface */ virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; - GDVIRTUAL2R(RID, _create_shaped_text, Direction, Orientation); - - virtual void shaped_text_clear(RID p_shaped) override; - GDVIRTUAL1(_shaped_text_clear, RID); - - virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override; - virtual Direction shaped_text_get_direction(RID p_shaped) const override; - virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const override; - GDVIRTUAL2(_shaped_text_set_direction, RID, Direction); - GDVIRTUAL1RC(Direction, _shaped_text_get_direction, RID); - GDVIRTUAL1RC(Direction, _shaped_text_get_inferred_direction, RID); - - virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override; - GDVIRTUAL2(_shaped_text_set_bidi_override, RID, const Array &); - - virtual void shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) override; - virtual String shaped_text_get_custom_punctuation(RID p_shaped) const override; - GDVIRTUAL2(_shaped_text_set_custom_punctuation, RID, String); - GDVIRTUAL1RC(String, _shaped_text_get_custom_punctuation, RID); - - virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; - virtual Orientation shaped_text_get_orientation(RID p_shaped) const override; - GDVIRTUAL2(_shaped_text_set_orientation, RID, Orientation); - GDVIRTUAL1RC(Orientation, _shaped_text_get_orientation, RID); - - virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) override; - virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const override; - GDVIRTUAL2(_shaped_text_set_preserve_invalid, RID, bool); - GDVIRTUAL1RC(bool, _shaped_text_get_preserve_invalid, RID); - - virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) override; - virtual bool shaped_text_get_preserve_control(RID p_shaped) const override; - GDVIRTUAL2(_shaped_text_set_preserve_control, RID, bool); - GDVIRTUAL1RC(bool, _shaped_text_get_preserve_control, RID); - - virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; - virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override; - virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override; - GDVIRTUAL7R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &, const Variant &); - GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlignment, int); - GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlignment); - - virtual int shaped_get_span_count(RID p_shaped) const override; - virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const override; - virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) override; - GDVIRTUAL1RC(int, _shaped_get_span_count, RID); - GDVIRTUAL2RC(Variant, _shaped_get_span_meta, RID, int); - GDVIRTUAL5(_shaped_set_span_update_font, RID, int, const Array &, int, const Dictionary &); - - virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override; - virtual RID shaped_text_get_parent(RID p_shaped) const override; - GDVIRTUAL3RC(RID, _shaped_text_substr, RID, int, int); - GDVIRTUAL1RC(RID, _shaped_text_get_parent, RID); - - virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; - virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) override; - GDVIRTUAL3R(float, _shaped_text_fit_to_width, RID, float, uint16_t); - GDVIRTUAL2R(float, _shaped_text_tab_align, RID, const PackedFloat32Array &); - - virtual bool shaped_text_shape(RID p_shaped) override; - virtual bool shaped_text_update_breaks(RID p_shaped) override; - virtual bool shaped_text_update_justification_ops(RID p_shaped) override; - GDVIRTUAL1R(bool, _shaped_text_shape, RID); - GDVIRTUAL1R(bool, _shaped_text_update_breaks, RID); - GDVIRTUAL1R(bool, _shaped_text_update_justification_ops, RID); - - virtual bool shaped_text_is_ready(RID p_shaped) const override; - GDVIRTUAL1RC(bool, _shaped_text_is_ready, RID); - - virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override; - virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override; - virtual int shaped_text_get_glyph_count(RID p_shaped) const override; - GDVIRTUAL1RC(GDNativePtr<Glyph>, _shaped_text_get_glyphs, RID); - GDVIRTUAL1R(GDNativePtr<Glyph>, _shaped_text_sort_logical, RID); - GDVIRTUAL1RC(int, _shaped_text_get_glyph_count, RID); - - virtual Vector2i shaped_text_get_range(RID p_shaped) const override; - GDVIRTUAL1RC(Vector2i, _shaped_text_get_range, RID); - - virtual PackedInt32Array shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start = 0, bool p_once = true, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; - virtual PackedInt32Array shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint16_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; - virtual PackedInt32Array shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override; - GDVIRTUAL5RC(PackedInt32Array, _shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int, bool, uint16_t); - GDVIRTUAL4RC(PackedInt32Array, _shaped_text_get_line_breaks, RID, float, int, uint16_t); - GDVIRTUAL2RC(PackedInt32Array, _shaped_text_get_word_breaks, RID, int); - - virtual int shaped_text_get_trim_pos(RID p_shaped) const override; - virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const override; - virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const override; - virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override; - GDVIRTUAL1RC(int, _shaped_text_get_trim_pos, RID); - GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_pos, RID); - GDVIRTUAL1RC(GDNativePtr<Glyph>, _shaped_text_get_ellipsis_glyphs, RID); - GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_glyph_count, RID); - - virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override; - GDVIRTUAL3(_shaped_text_overrun_trim_to_width, RID, float, uint16_t); - - virtual Array shaped_text_get_objects(RID p_shaped) const override; - virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override; - GDVIRTUAL1RC(Array, _shaped_text_get_objects, RID); - GDVIRTUAL2RC(Rect2, _shaped_text_get_object_rect, RID, Variant); - - virtual Size2 shaped_text_get_size(RID p_shaped) const override; - virtual float shaped_text_get_ascent(RID p_shaped) const override; - virtual float shaped_text_get_descent(RID p_shaped) const override; - virtual float shaped_text_get_width(RID p_shaped) const override; - virtual float shaped_text_get_underline_position(RID p_shaped) const override; - virtual float shaped_text_get_underline_thickness(RID p_shaped) const override; - GDVIRTUAL1RC(Size2, _shaped_text_get_size, RID); - GDVIRTUAL1RC(float, _shaped_text_get_ascent, RID); - GDVIRTUAL1RC(float, _shaped_text_get_descent, RID); - GDVIRTUAL1RC(float, _shaped_text_get_width, RID); - GDVIRTUAL1RC(float, _shaped_text_get_underline_position, RID); - GDVIRTUAL1RC(float, _shaped_text_get_underline_thickness, RID); - - virtual Direction shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const override; - GDVIRTUAL3RC(int, _shaped_text_get_dominant_direction_in_range, RID, int, int); - - virtual CaretInfo shaped_text_get_carets(RID p_shaped, int p_position) const override; - virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const override; - GDVIRTUAL3C(_shaped_text_get_carets, RID, int, GDNativePtr<CaretInfo>); - GDVIRTUAL3RC(Vector<Vector2>, _shaped_text_get_selection, RID, int, int); - - virtual int shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const override; - virtual int shaped_text_hit_test_position(RID p_shaped, float p_coords) const override; - GDVIRTUAL2RC(int, _shaped_text_hit_test_grapheme, RID, float); - GDVIRTUAL2RC(int, _shaped_text_hit_test_position, RID, float); - - virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const override; - virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const override; - GDVIRTUAL6C(_shaped_text_draw, RID, RID, const Vector2 &, float, float, const Color &); - GDVIRTUAL7C(_shaped_text_draw_outline, RID, RID, const Vector2 &, float, float, int, const Color &); - - virtual Vector2 shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) const override; - virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const override; - virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const override; - GDVIRTUAL2RC(Vector2, _shaped_text_get_grapheme_bounds, RID, int); - GDVIRTUAL2RC(int, _shaped_text_next_grapheme_pos, RID, int); - GDVIRTUAL2RC(int, _shaped_text_prev_grapheme_pos, RID, int); + GDVIRTUAL2R(RID, create_shaped_text, Direction, Orientation); + + virtual void shaped_text_clear(const RID &p_shaped) override; + GDVIRTUAL1(shaped_text_clear, RID); + + virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) override; + virtual Direction shaped_text_get_direction(const RID &p_shaped) const override; + virtual Direction shaped_text_get_inferred_direction(const RID &p_shaped) const override; + GDVIRTUAL2(shaped_text_set_direction, RID, Direction); + GDVIRTUAL1RC(Direction, shaped_text_get_direction, RID); + GDVIRTUAL1RC(Direction, shaped_text_get_inferred_direction, RID); + + virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) override; + GDVIRTUAL2(shaped_text_set_bidi_override, RID, const Array &); + + virtual void shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) override; + virtual String shaped_text_get_custom_punctuation(const RID &p_shaped) const override; + GDVIRTUAL2(shaped_text_set_custom_punctuation, RID, String); + GDVIRTUAL1RC(String, shaped_text_get_custom_punctuation, RID); + + virtual void shaped_text_set_orientation(const RID &p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override; + virtual Orientation shaped_text_get_orientation(const RID &p_shaped) const override; + GDVIRTUAL2(shaped_text_set_orientation, RID, Orientation); + GDVIRTUAL1RC(Orientation, shaped_text_get_orientation, RID); + + virtual void shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) override; + virtual bool shaped_text_get_preserve_invalid(const RID &p_shaped) const override; + GDVIRTUAL2(shaped_text_set_preserve_invalid, RID, bool); + GDVIRTUAL1RC(bool, shaped_text_get_preserve_invalid, RID); + + virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) override; + virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const override; + GDVIRTUAL2(shaped_text_set_preserve_control, RID, bool); + GDVIRTUAL1RC(bool, shaped_text_get_preserve_control, RID); + + virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override; + virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override; + virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override; + GDVIRTUAL7R(bool, shaped_text_add_string, RID, const String &, const Array &, int64_t, const Dictionary &, const String &, const Variant &); + GDVIRTUAL5R(bool, shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t); + GDVIRTUAL4R(bool, shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment); + + virtual int64_t shaped_get_span_count(const RID &p_shaped) const override; + virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override; + virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override; + GDVIRTUAL1RC(int64_t, shaped_get_span_count, RID); + GDVIRTUAL2RC(Variant, shaped_get_span_meta, RID, int64_t); + GDVIRTUAL5(shaped_set_span_update_font, RID, int64_t, const Array &, int64_t, const Dictionary &); + + virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override; + virtual RID shaped_text_get_parent(const RID &p_shaped) const override; + GDVIRTUAL3RC(RID, shaped_text_substr, RID, int64_t, int64_t); + GDVIRTUAL1RC(RID, shaped_text_get_parent, RID); + + virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override; + virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override; + GDVIRTUAL3R(double, shaped_text_fit_to_width, RID, double, int64_t); + GDVIRTUAL2R(double, shaped_text_tab_align, RID, const PackedFloat32Array &); + + virtual bool shaped_text_shape(const RID &p_shaped) override; + virtual bool shaped_text_update_breaks(const RID &p_shaped) override; + virtual bool shaped_text_update_justification_ops(const RID &p_shaped) override; + GDVIRTUAL1R(bool, shaped_text_shape, RID); + GDVIRTUAL1R(bool, shaped_text_update_breaks, RID); + GDVIRTUAL1R(bool, shaped_text_update_justification_ops, RID); + + virtual bool shaped_text_is_ready(const RID &p_shaped) const override; + GDVIRTUAL1RC(bool, shaped_text_is_ready, RID); + + virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const override; + virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) override; + virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const override; + GDVIRTUAL1RC(GDNativeConstPtr<const Glyph>, shaped_text_get_glyphs, RID); + GDVIRTUAL1R(GDNativeConstPtr<const Glyph>, shaped_text_sort_logical, RID); + GDVIRTUAL1RC(int64_t, shaped_text_get_glyph_count, RID); + + virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override; + GDVIRTUAL1RC(Vector2i, shaped_text_get_range, RID); + + virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; + virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, int64_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override; + virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override; + GDVIRTUAL5RC(PackedInt32Array, shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int64_t, bool, int64_t); + GDVIRTUAL4RC(PackedInt32Array, shaped_text_get_line_breaks, RID, double, int64_t, int64_t); + GDVIRTUAL2RC(PackedInt32Array, shaped_text_get_word_breaks, RID, int64_t); + + virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const override; + virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override; + virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override; + virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override; + GDVIRTUAL1RC(int64_t, shaped_text_get_trim_pos, RID); + GDVIRTUAL1RC(int64_t, shaped_text_get_ellipsis_pos, RID); + GDVIRTUAL1RC(GDNativeConstPtr<const Glyph>, shaped_text_get_ellipsis_glyphs, RID); + GDVIRTUAL1RC(int64_t, shaped_text_get_ellipsis_glyph_count, RID); + + virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) override; + GDVIRTUAL3(shaped_text_overrun_trim_to_width, RID, double, int64_t); + + virtual Array shaped_text_get_objects(const RID &p_shaped) const override; + virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override; + GDVIRTUAL1RC(Array, shaped_text_get_objects, RID); + GDVIRTUAL2RC(Rect2, shaped_text_get_object_rect, RID, const Variant &); + + virtual Size2 shaped_text_get_size(const RID &p_shaped) const override; + virtual double shaped_text_get_ascent(const RID &p_shaped) const override; + virtual double shaped_text_get_descent(const RID &p_shaped) const override; + virtual double shaped_text_get_width(const RID &p_shaped) const override; + virtual double shaped_text_get_underline_position(const RID &p_shaped) const override; + virtual double shaped_text_get_underline_thickness(const RID &p_shaped) const override; + GDVIRTUAL1RC(Size2, shaped_text_get_size, RID); + GDVIRTUAL1RC(double, shaped_text_get_ascent, RID); + GDVIRTUAL1RC(double, shaped_text_get_descent, RID); + GDVIRTUAL1RC(double, shaped_text_get_width, RID); + GDVIRTUAL1RC(double, shaped_text_get_underline_position, RID); + GDVIRTUAL1RC(double, shaped_text_get_underline_thickness, RID); + + virtual Direction shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const override; + GDVIRTUAL3RC(int64_t, shaped_text_get_dominant_direction_in_range, RID, int64_t, int64_t); + + virtual CaretInfo shaped_text_get_carets(const RID &p_shaped, int64_t p_position) const override; + virtual Vector<Vector2> shaped_text_get_selection(const RID &p_shaped, int64_t p_start, int64_t p_end) const override; + GDVIRTUAL3C(shaped_text_get_carets, RID, int64_t, GDNativePtr<CaretInfo>); + GDVIRTUAL3RC(Vector<Vector2>, shaped_text_get_selection, RID, int64_t, int64_t); + + virtual int64_t shaped_text_hit_test_grapheme(const RID &p_shaped, double p_coords) const override; + virtual int64_t shaped_text_hit_test_position(const RID &p_shaped, double p_coords) const override; + GDVIRTUAL2RC(int64_t, shaped_text_hit_test_grapheme, RID, double); + GDVIRTUAL2RC(int64_t, shaped_text_hit_test_position, RID, double); + + virtual void shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1)) const override; + virtual void shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const override; + GDVIRTUAL6C(shaped_text_draw, RID, RID, const Vector2 &, double, double, const Color &); + GDVIRTUAL7C(shaped_text_draw_outline, RID, RID, const Vector2 &, double, double, int64_t, const Color &); + + virtual Vector2 shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const override; + virtual int64_t shaped_text_next_grapheme_pos(const RID &p_shaped, int64_t p_pos) const override; + virtual int64_t shaped_text_prev_grapheme_pos(const RID &p_shaped, int64_t p_pos) const override; + GDVIRTUAL2RC(Vector2, shaped_text_get_grapheme_bounds, RID, int64_t); + GDVIRTUAL2RC(int64_t, shaped_text_next_grapheme_pos, RID, int64_t); + GDVIRTUAL2RC(int64_t, shaped_text_prev_grapheme_pos, RID, int64_t); virtual String format_number(const String &p_string, const String &p_language = "") const override; virtual String parse_number(const String &p_string, const String &p_language = "") const override; virtual String percent_sign(const String &p_language = "") const override; - GDVIRTUAL2RC(String, _format_number, const String &, const String &); - GDVIRTUAL2RC(String, _parse_number, const String &, const String &); - GDVIRTUAL1RC(String, _percent_sign, const String &); + GDVIRTUAL2RC(String, format_number, const String &, const String &); + GDVIRTUAL2RC(String, parse_number, const String &, const String &); + GDVIRTUAL1RC(String, percent_sign, const String &); + + virtual String strip_diacritics(const String &p_string) const override; + GDVIRTUAL1RC(String, strip_diacritics, const String &); virtual String string_to_upper(const String &p_string, const String &p_language = "") const override; virtual String string_to_lower(const String &p_string, const String &p_language = "") const override; - GDVIRTUAL2RC(String, _string_to_upper, const String &, const String &); - GDVIRTUAL2RC(String, _string_to_lower, const String &, const String &); + GDVIRTUAL2RC(String, string_to_upper, const String &, const String &); + GDVIRTUAL2RC(String, string_to_lower, const String &, const String &); TextServerExtension(); ~TextServerExtension(); diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 37cc6599b1..ec31885cae 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -200,7 +200,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("tag_to_name", "tag"), &TextServer::tag_to_name); ClassDB::bind_method(D_METHOD("has", "rid"), &TextServer::has); - ClassDB::bind_method(D_METHOD("free_rid", "rid"), &TextServer::free); // shouldn't conflict with Object::free() + ClassDB::bind_method(D_METHOD("free_rid", "rid"), &TextServer::free_rid); /* Font Interface */ @@ -241,6 +241,12 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_set_subpixel_positioning", "font_rid", "subpixel_positioning"), &TextServer::font_set_subpixel_positioning); ClassDB::bind_method(D_METHOD("font_get_subpixel_positioning", "font_rid"), &TextServer::font_get_subpixel_positioning); + ClassDB::bind_method(D_METHOD("font_set_embolden", "font_rid", "strength"), &TextServer::font_set_embolden); + ClassDB::bind_method(D_METHOD("font_get_embolden", "font_rid"), &TextServer::font_get_embolden); + + ClassDB::bind_method(D_METHOD("font_set_transform", "font_rid", "transform"), &TextServer::font_set_transform); + ClassDB::bind_method(D_METHOD("font_get_transform", "font_rid"), &TextServer::font_get_transform); + ClassDB::bind_method(D_METHOD("font_set_variation_coordinates", "font_rid", "variation_coordinates"), &TextServer::font_set_variation_coordinates); ClassDB::bind_method(D_METHOD("font_get_variation_coordinates", "font_rid"), &TextServer::font_get_variation_coordinates); @@ -487,13 +493,19 @@ void TextServer::_bind_methods() { BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_AUTO); BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_HALF); BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_QUARTER); + BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE); + BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE); /* Feature */ + BIND_ENUM_CONSTANT(FEATURE_SIMPLE_LAYOUT); BIND_ENUM_CONSTANT(FEATURE_BIDI_LAYOUT); BIND_ENUM_CONSTANT(FEATURE_VERTICAL_LAYOUT); BIND_ENUM_CONSTANT(FEATURE_SHAPING); BIND_ENUM_CONSTANT(FEATURE_KASHIDA_JUSTIFICATION); BIND_ENUM_CONSTANT(FEATURE_BREAK_ITERATORS); + BIND_ENUM_CONSTANT(FEATURE_FONT_BITMAP); + BIND_ENUM_CONSTANT(FEATURE_FONT_DYNAMIC); + BIND_ENUM_CONSTANT(FEATURE_FONT_MSDF); BIND_ENUM_CONSTANT(FEATURE_FONT_SYSTEM); BIND_ENUM_CONSTANT(FEATURE_FONT_VARIABLE); BIND_ENUM_CONSTANT(FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION); @@ -516,7 +528,7 @@ void TextServer::_bind_methods() { BIND_ENUM_CONSTANT(FONT_FIXED_WIDTH); } -Vector2 TextServer::get_hex_code_box_size(int p_size, char32_t p_index) const { +Vector2 TextServer::get_hex_code_box_size(int64_t p_size, int64_t p_index) const { int w = ((p_index <= 0xFF) ? 1 : ((p_index <= 0xFFFF) ? 2 : 3)); int sp = MAX(0, w - 1); int sz = MAX(1, Math::round(p_size / 15.f)); @@ -524,7 +536,7 @@ Vector2 TextServer::get_hex_code_box_size(int p_size, char32_t p_index) const { return Vector2(4 + 3 * w + sp + 1, 15) * sz; } -void TextServer::_draw_hex_code_box_number(RID p_canvas, int p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const { +void TextServer::_draw_hex_code_box_number(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const { static uint8_t chars[] = { 0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47, 0x00 }; uint8_t x = chars[p_index]; if (x & (1 << 6)) { @@ -550,7 +562,7 @@ void TextServer::_draw_hex_code_box_number(RID p_canvas, int p_size, const Vecto } } -void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const { +void TextServer::draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const { if (p_index == 0) { return; } @@ -594,7 +606,7 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po } } -PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint16_t /*TextBreakFlag*/ p_break_flags) const { +PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start, bool p_once, int64_t /*TextBreakFlag*/ p_break_flags) const { PackedInt32Array lines; ERR_FAIL_COND_V(p_width.is_empty(), lines); @@ -670,13 +682,13 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const return lines; } -PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start, uint16_t /*TextBreakFlag*/ p_break_flags) const { +PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start, int64_t /*TextBreakFlag*/ p_break_flags) const { PackedInt32Array lines; const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped); const Vector2i &range = shaped_text_get_range(p_shaped); - float width = 0.f; + double width = 0.f; int line_start = MAX(p_start, range.x); int last_safe_break = -1; int word_count = 0; @@ -738,7 +750,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w return lines; } -PackedInt32Array TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const { +PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags) const { PackedInt32Array words; const_cast<TextServer *>(this)->shaped_text_update_justification_ops(p_shaped); @@ -752,21 +764,25 @@ PackedInt32Array TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_gra for (int i = 0; i < l_size; i++) { if (l_gl[i].count > 0) { if ((l_gl[i].flags & p_grapheme_flags) != 0) { - words.push_back(word_start); - words.push_back(l_gl[i].start); + if (word_start != l_gl[i].start) { + words.push_back(word_start); + words.push_back(l_gl[i].start); + } word_start = l_gl[i].end; } } } if (l_size > 0) { - words.push_back(word_start); - words.push_back(range.y); + if (word_start != range.y) { + words.push_back(word_start); + words.push_back(range.y); + } } return words; } -CaretInfo TextServer::shaped_text_get_carets(RID p_shaped, int p_position) const { +CaretInfo TextServer::shaped_text_get_carets(const RID &p_shaped, int64_t p_position) const { Vector<Rect2> carets; TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); @@ -916,7 +932,7 @@ CaretInfo TextServer::shaped_text_get_carets(RID p_shaped, int p_position) const return caret; } -Dictionary TextServer::_shaped_text_get_carets_wrapper(RID p_shaped, int p_position) const { +Dictionary TextServer::_shaped_text_get_carets_wrapper(const RID &p_shaped, int64_t p_position) const { Dictionary ret; CaretInfo caret = shaped_text_get_carets(p_shaped, p_position); @@ -929,7 +945,7 @@ Dictionary TextServer::_shaped_text_get_carets_wrapper(RID p_shaped, int p_posit return ret; } -TextServer::Direction TextServer::shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const { +TextServer::Direction TextServer::shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const { if (p_start == p_end) { return DIRECTION_AUTO; } @@ -963,7 +979,7 @@ TextServer::Direction TextServer::shaped_text_get_dominant_direction_in_range(RI } } -Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const { +Vector<Vector2> TextServer::shaped_text_get_selection(const RID &p_shaped, int64_t p_start, int64_t p_end) const { Vector<Vector2> ranges; if (p_start == p_end) { @@ -1056,9 +1072,9 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start, return ranges; } -int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const { +int64_t TextServer::shaped_text_hit_test_grapheme(const RID &p_shaped, double p_coords) const { // Exact grapheme hit test, return -1 if missed. - float off = 0.0f; + double off = 0.0f; int v_size = shaped_text_get_glyph_count(p_shaped); const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); @@ -1074,7 +1090,7 @@ int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) cons return -1; } -int TextServer::shaped_text_hit_test_position(RID p_shaped, float p_coords) const { +int64_t TextServer::shaped_text_hit_test_position(const RID &p_shaped, double p_coords) const { int v_size = shaped_text_get_glyph_count(p_shaped); const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); @@ -1167,7 +1183,7 @@ int TextServer::shaped_text_hit_test_position(RID p_shaped, float p_coords) cons return 0; } -Vector2 TextServer::shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) const { +Vector2 TextServer::shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const { int v_size = shaped_text_get_glyph_count(p_shaped); const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); @@ -1188,7 +1204,7 @@ Vector2 TextServer::shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) con return Vector2(); } -int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const { +int64_t TextServer::shaped_text_next_grapheme_pos(const RID &p_shaped, int64_t p_pos) const { int v_size = shaped_text_get_glyph_count(p_shaped); const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); for (int i = 0; i < v_size; i++) { @@ -1199,7 +1215,7 @@ int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const { return p_pos; } -int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const { +int64_t TextServer::shaped_text_prev_grapheme_pos(const RID &p_shaped, int64_t p_pos) const { int v_size = shaped_text_get_glyph_count(p_shaped); const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); for (int i = 0; i < v_size; i++) { @@ -1211,7 +1227,7 @@ int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const { return p_pos; } -void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, const Color &p_color) const { +void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color) const { TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); bool hex_codes = shaped_text_get_preserve_control(p_shaped) || shaped_text_get_preserve_invalid(p_shaped); @@ -1257,11 +1273,11 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p if (p_clip_r > 0) { // Clip right / bottom. if (orientation == ORIENTATION_HORIZONTAL) { - if (ofs.x - p_pos.x > p_clip_r) { + if (ofs.x - p_pos.x + glyphs[i].advance > p_clip_r) { return; } } else { - if (ofs.y - p_pos.y > p_clip_r) { + if (ofs.y - p_pos.y + glyphs[i].advance > p_clip_r) { return; } } @@ -1308,7 +1324,7 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p } } -void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, int p_outline_size, const Color &p_color) const { +void TextServer::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, int64_t p_outline_size, const Color &p_color) const { TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); bool rtl = (shaped_text_get_inferred_direction(p_shaped) == DIRECTION_RTL); @@ -1352,11 +1368,11 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect if (p_clip_r > 0) { // Clip right / bottom. if (orientation == ORIENTATION_HORIZONTAL) { - if (ofs.x - p_pos.x > p_clip_r) { + if (ofs.x - p_pos.x + glyphs[i].advance > p_clip_r) { return; } } else { - if (ofs.y - p_pos.y > p_clip_r) { + if (ofs.y - p_pos.y + glyphs[i].advance > p_clip_r) { return; } } @@ -1528,7 +1544,7 @@ String TextServer::strip_diacritics(const String &p_string) const { return result; } -Array TextServer::_shaped_text_get_glyphs_wrapper(RID p_shaped) const { +Array TextServer::_shaped_text_get_glyphs_wrapper(const RID &p_shaped) const { Array ret; const Glyph *glyphs = shaped_text_get_glyphs(p_shaped); @@ -1553,7 +1569,7 @@ Array TextServer::_shaped_text_get_glyphs_wrapper(RID p_shaped) const { return ret; } -Array TextServer::_shaped_text_sort_logical_wrapper(RID p_shaped) { +Array TextServer::_shaped_text_sort_logical_wrapper(const RID &p_shaped) { Array ret; const Glyph *glyphs = shaped_text_sort_logical(p_shaped); @@ -1578,7 +1594,7 @@ Array TextServer::_shaped_text_sort_logical_wrapper(RID p_shaped) { return ret; } -Array TextServer::_shaped_text_get_ellipsis_glyphs_wrapper(RID p_shaped) const { +Array TextServer::_shaped_text_get_ellipsis_glyphs_wrapper(const RID &p_shaped) const { Array ret; const Glyph *glyphs = shaped_text_get_ellipsis_glyphs(p_shaped); diff --git a/servers/text_server.h b/servers/text_server.h index 38ad496490..365b7ff663 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -102,25 +102,29 @@ public: }; enum SubpixelPositioning { - SUBPIXEL_POSITIONING_DISABLED, - SUBPIXEL_POSITIONING_AUTO, - SUBPIXEL_POSITIONING_ONE_HALF, - SUBPIXEL_POSITIONING_ONE_QUARTER, - }; + SUBPIXEL_POSITIONING_DISABLED = 0, + SUBPIXEL_POSITIONING_AUTO = 1, + SUBPIXEL_POSITIONING_ONE_HALF = 2, + SUBPIXEL_POSITIONING_ONE_QUARTER = 3, - const int SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE = 20; - const int SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE = 16; + SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE = 20, + SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE = 16, + }; enum Feature { - FEATURE_BIDI_LAYOUT = 1 << 0, - FEATURE_VERTICAL_LAYOUT = 1 << 1, - FEATURE_SHAPING = 1 << 2, - FEATURE_KASHIDA_JUSTIFICATION = 1 << 3, - FEATURE_BREAK_ITERATORS = 1 << 4, - FEATURE_FONT_SYSTEM = 1 << 5, - FEATURE_FONT_VARIABLE = 1 << 6, - FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION = 1 << 7, - FEATURE_USE_SUPPORT_DATA = 1 << 8, + FEATURE_SIMPLE_LAYOUT = 1 << 0, + FEATURE_BIDI_LAYOUT = 1 << 1, + FEATURE_VERTICAL_LAYOUT = 1 << 2, + FEATURE_SHAPING = 1 << 3, + FEATURE_KASHIDA_JUSTIFICATION = 1 << 4, + FEATURE_BREAK_ITERATORS = 1 << 5, + FEATURE_FONT_BITMAP = 1 << 6, + FEATURE_FONT_DYNAMIC = 1 << 7, + FEATURE_FONT_MSDF = 1 << 8, + FEATURE_FONT_SYSTEM = 1 << 9, + FEATURE_FONT_VARIABLE = 1 << 10, + FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION = 1 << 11, + FEATURE_USE_SUPPORT_DATA = 1 << 12, }; enum ContourPointTag { @@ -142,62 +146,9 @@ public: FONT_FIXED_WIDTH = 1 << 2, }; - void _draw_hex_code_box_number(RID p_canvas, int p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const; + void _draw_hex_code_box_number(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const; protected: - struct TrimData { - int trim_pos = -1; - int ellipsis_pos = -1; - Vector<Glyph> ellipsis_glyph_buf; - }; - - struct ShapedTextData { - Mutex mutex; - - /* Source data */ - RID parent; // Substring parent ShapedTextData. - - int start = 0; // Substring start offset in the parent string. - int end = 0; // Substring end offset in the parent string. - - String text; - String custom_punct; - TextServer::Direction direction = DIRECTION_LTR; // Desired text direction. - TextServer::Orientation orientation = ORIENTATION_HORIZONTAL; - - struct EmbeddedObject { - int pos = 0; - InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER; - Rect2 rect; - }; - Map<Variant, EmbeddedObject> objects; - - /* Shaped data */ - TextServer::Direction para_direction = DIRECTION_LTR; // Detected text direction. - bool valid = false; // String is shaped. - bool line_breaks_valid = false; // Line and word break flags are populated (and virtual zero width spaces inserted). - bool justification_ops_valid = false; // Virtual elongation glyphs are added to the string. - bool sort_valid = false; - bool text_trimmed = false; - - bool preserve_invalid = true; // Draw hex code box instead of missing characters. - bool preserve_control = false; // Draw control characters. - - float ascent = 0.f; // Ascent for horizontal layout, 1/2 of width for vertical. - float descent = 0.f; // Descent for horizontal layout, 1/2 of width for vertical. - float width = 0.f; // Width for horizontal layout, height for vertical. - float width_trimmed = 0.f; - - float upos = 0.f; - float uthk = 0.f; - - TrimData overrun_trim_data; - bool fit_width_minimum_reached = false; - - Vector<Glyph> glyphs; - Vector<Glyph> glyphs_logical; - }; - Map<char32_t, char32_t> diacritics_map; void _diacritics_map_add(const String &p_from, char32_t p_to); void _init_diacritics_map(); @@ -207,10 +158,10 @@ protected: public: virtual bool has_feature(Feature p_feature) const = 0; virtual String get_name() const = 0; - virtual uint32_t get_features() const = 0; + virtual int64_t get_features() const = 0; - virtual void free(RID p_rid) = 0; - virtual bool has(RID p_rid) = 0; + virtual void free_rid(const RID &p_rid) = 0; + virtual bool has(const RID &p_rid) = 0; virtual bool load_support_data(const String &p_filename) = 0; virtual String get_support_data_filename() const = 0; @@ -219,245 +170,251 @@ public: virtual bool is_locale_right_to_left(const String &p_locale) const = 0; - virtual int32_t name_to_tag(const String &p_name) const { return 0; }; - virtual String tag_to_name(int32_t p_tag) const { return ""; }; + virtual int64_t name_to_tag(const String &p_name) const { return 0; }; + virtual String tag_to_name(int64_t p_tag) const { return ""; }; /* Font interface */ virtual RID create_font() = 0; - virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) = 0; - virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) = 0; + virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) = 0; + virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) = 0; - virtual void font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) = 0; - virtual uint32_t /*FontStyle*/ font_get_style(RID p_font_rid) const = 0; + virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) = 0; + virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const = 0; - virtual void font_set_name(RID p_font_rid, const String &p_name) = 0; - virtual String font_get_name(RID p_font_rid) const = 0; + virtual void font_set_name(const RID &p_font_rid, const String &p_name) = 0; + virtual String font_get_name(const RID &p_font_rid) const = 0; - virtual void font_set_style_name(RID p_font_rid, const String &p_name) = 0; - virtual String font_get_style_name(RID p_font_rid) const = 0; + virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) = 0; + virtual String font_get_style_name(const RID &p_font_rid) const = 0; - virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) = 0; - virtual bool font_is_antialiased(RID p_font_rid) const = 0; + virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) = 0; + virtual bool font_is_antialiased(const RID &p_font_rid) const = 0; - virtual void font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) = 0; - virtual bool font_is_multichannel_signed_distance_field(RID p_font_rid) const = 0; + virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) = 0; + virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const = 0; - virtual void font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) = 0; - virtual int font_get_msdf_pixel_range(RID p_font_rid) const = 0; + virtual void font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) = 0; + virtual int64_t font_get_msdf_pixel_range(const RID &p_font_rid) const = 0; - virtual void font_set_msdf_size(RID p_font_rid, int p_msdf_size) = 0; - virtual int font_get_msdf_size(RID p_font_rid) const = 0; + virtual void font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) = 0; + virtual int64_t font_get_msdf_size(const RID &p_font_rid) const = 0; - virtual void font_set_fixed_size(RID p_font_rid, int p_fixed_size) = 0; - virtual int font_get_fixed_size(RID p_font_rid) const = 0; + virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) = 0; + virtual int64_t font_get_fixed_size(const RID &p_font_rid) const = 0; - virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) = 0; - virtual bool font_is_force_autohinter(RID p_font_rid) const = 0; + virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) = 0; + virtual bool font_is_force_autohinter(const RID &p_font_rid) const = 0; - virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) = 0; - virtual Hinting font_get_hinting(RID p_font_rid) const = 0; + virtual void font_set_hinting(const RID &p_font_rid, Hinting p_hinting) = 0; + virtual Hinting font_get_hinting(const RID &p_font_rid) const = 0; - virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) = 0; - virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const = 0; + virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) = 0; + virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const = 0; - virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) = 0; - virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const = 0; + virtual void font_set_embolden(const RID &p_font_rid, double p_strength) = 0; + virtual double font_get_embolden(const RID &p_font_rid) const = 0; - virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) = 0; - virtual float font_get_oversampling(RID p_font_rid) const = 0; + virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) = 0; + virtual Transform2D font_get_transform(const RID &p_font_rid) const = 0; - virtual Array font_get_size_cache_list(RID p_font_rid) const = 0; - virtual void font_clear_size_cache(RID p_font_rid) = 0; - virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) = 0; + virtual void font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) = 0; + virtual Dictionary font_get_variation_coordinates(const RID &p_font_rid) const = 0; - virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) = 0; - virtual float font_get_ascent(RID p_font_rid, int p_size) const = 0; + virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) = 0; + virtual double font_get_oversampling(const RID &p_font_rid) const = 0; - virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) = 0; - virtual float font_get_descent(RID p_font_rid, int p_size) const = 0; + virtual Array font_get_size_cache_list(const RID &p_font_rid) const = 0; + virtual void font_clear_size_cache(const RID &p_font_rid) = 0; + virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) = 0; - virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) = 0; - virtual float font_get_underline_position(RID p_font_rid, int p_size) const = 0; + virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) = 0; + virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const = 0; - virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) = 0; - virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const = 0; + virtual void font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) = 0; + virtual double font_get_descent(const RID &p_font_rid, int64_t p_size) const = 0; - virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) = 0; - virtual float font_get_scale(RID p_font_rid, int p_size) const = 0; + virtual void font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) = 0; + virtual double font_get_underline_position(const RID &p_font_rid, int64_t p_size) const = 0; - virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) = 0; - virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const = 0; + virtual void font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) = 0; + virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const = 0; - virtual int font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const = 0; - virtual void font_clear_textures(RID p_font_rid, const Vector2i &p_size) = 0; - virtual void font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) = 0; + virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) = 0; + virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const = 0; - virtual void font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) = 0; - virtual Ref<Image> font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const = 0; + virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) = 0; + virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const = 0; - virtual void font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) = 0; - virtual PackedInt32Array font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const = 0; + virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const = 0; + virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) = 0; + virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) = 0; - virtual Array font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const = 0; - virtual void font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) = 0; - virtual void font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) = 0; + virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) = 0; + virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const = 0; - virtual Vector2 font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const = 0; - virtual void font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) = 0; + virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) = 0; + virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const = 0; - virtual Vector2 font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0; - virtual void font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) = 0; + virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const = 0; + virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) = 0; + virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) = 0; - virtual Vector2 font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0; - virtual void font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) = 0; + virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const = 0; + virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) = 0; - virtual Rect2 font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0; - virtual void font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) = 0; + virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const = 0; + virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) = 0; - virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0; - virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) = 0; + virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const = 0; + virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) = 0; - virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const = 0; + virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const = 0; + virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) = 0; - virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const = 0; - virtual void font_clear_kerning_map(RID p_font_rid, int p_size) = 0; - virtual void font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) = 0; + virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const = 0; + virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) = 0; - virtual void font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) = 0; - virtual Vector2 font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const = 0; + virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const = 0; - virtual int32_t font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const = 0; + virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const = 0; + virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) = 0; + virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) = 0; - virtual bool font_has_char(RID p_font_rid, char32_t p_char) const = 0; - virtual String font_get_supported_chars(RID p_font_rid) const = 0; + virtual void font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) = 0; + virtual Vector2 font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const = 0; - virtual void font_render_range(RID p_font, const Vector2i &p_size, char32_t p_start, char32_t p_end) = 0; - virtual void font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) = 0; + virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const = 0; - virtual void font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0; - virtual void font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0; + virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const = 0; + virtual String font_get_supported_chars(const RID &p_font_rid) const = 0; - virtual bool font_is_language_supported(RID p_font_rid, const String &p_language) const = 0; - virtual void font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) = 0; - virtual bool font_get_language_support_override(RID p_font_rid, const String &p_language) = 0; - virtual void font_remove_language_support_override(RID p_font_rid, const String &p_language) = 0; - virtual Vector<String> font_get_language_support_overrides(RID p_font_rid) = 0; + virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) = 0; + virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) = 0; - virtual bool font_is_script_supported(RID p_font_rid, const String &p_script) const = 0; - virtual void font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) = 0; - virtual bool font_get_script_support_override(RID p_font_rid, const String &p_script) = 0; - virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) = 0; - virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) = 0; + virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0; + virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0; - virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) = 0; - virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const = 0; + virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const = 0; + virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) = 0; + virtual bool font_get_language_support_override(const RID &p_font_rid, const String &p_language) = 0; + virtual void font_remove_language_support_override(const RID &p_font_rid, const String &p_language) = 0; + virtual PackedStringArray font_get_language_support_overrides(const RID &p_font_rid) = 0; - virtual Dictionary font_supported_feature_list(RID p_font_rid) const = 0; - virtual Dictionary font_supported_variation_list(RID p_font_rid) const = 0; + virtual bool font_is_script_supported(const RID &p_font_rid, const String &p_script) const = 0; + virtual void font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) = 0; + virtual bool font_get_script_support_override(const RID &p_font_rid, const String &p_script) = 0; + virtual void font_remove_script_support_override(const RID &p_font_rid, const String &p_script) = 0; + virtual PackedStringArray font_get_script_support_overrides(const RID &p_font_rid) = 0; - virtual float font_get_global_oversampling() const = 0; - virtual void font_set_global_oversampling(float p_oversampling) = 0; + virtual void font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) = 0; + virtual Dictionary font_get_opentype_feature_overrides(const RID &p_font_rid) const = 0; - virtual Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const; - virtual void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const; + virtual Dictionary font_supported_feature_list(const RID &p_font_rid) const = 0; + virtual Dictionary font_supported_variation_list(const RID &p_font_rid) const = 0; + + virtual double font_get_global_oversampling() const = 0; + virtual void font_set_global_oversampling(double p_oversampling) = 0; + + virtual Vector2 get_hex_code_box_size(int64_t p_size, int64_t p_index) const; + virtual void draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const; /* Shaped text buffer interface */ virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0; - virtual void shaped_text_clear(RID p_shaped) = 0; + virtual void shaped_text_clear(const RID &p_shaped) = 0; - virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) = 0; - virtual Direction shaped_text_get_direction(RID p_shaped) const = 0; - virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const = 0; + virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) = 0; + virtual Direction shaped_text_get_direction(const RID &p_shaped) const = 0; + virtual Direction shaped_text_get_inferred_direction(const RID &p_shaped) const = 0; - virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) = 0; + virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) = 0; - virtual void shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) = 0; - virtual String shaped_text_get_custom_punctuation(RID p_shaped) const = 0; + virtual void shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) = 0; + virtual String shaped_text_get_custom_punctuation(const RID &p_shaped) const = 0; - virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0; - virtual Orientation shaped_text_get_orientation(RID p_shaped) const = 0; + virtual void shaped_text_set_orientation(const RID &p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0; + virtual Orientation shaped_text_get_orientation(const RID &p_shaped) const = 0; - virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) = 0; - virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const = 0; + virtual void shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) = 0; + virtual bool shaped_text_get_preserve_invalid(const RID &p_shaped) const = 0; - virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) = 0; - virtual bool shaped_text_get_preserve_control(RID p_shaped) const = 0; + virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) = 0; + virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const = 0; - virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0; - virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) = 0; - virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0; + virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0; + virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) = 0; + virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0; - virtual int shaped_get_span_count(RID p_shaped) const = 0; - virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const = 0; - virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) = 0; + virtual int64_t shaped_get_span_count(const RID &p_shaped) const = 0; + virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const = 0; + virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) = 0; - virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range. - virtual RID shaped_text_get_parent(RID p_shaped) const = 0; + virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range. + virtual RID shaped_text_get_parent(const RID &p_shaped) const = 0; - virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0; - virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) = 0; + virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0; + virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) = 0; - virtual bool shaped_text_shape(RID p_shaped) = 0; - virtual bool shaped_text_update_breaks(RID p_shaped) = 0; - virtual bool shaped_text_update_justification_ops(RID p_shaped) = 0; + virtual bool shaped_text_shape(const RID &p_shaped) = 0; + virtual bool shaped_text_update_breaks(const RID &p_shaped) = 0; + virtual bool shaped_text_update_justification_ops(const RID &p_shaped) = 0; - virtual bool shaped_text_is_ready(RID p_shaped) const = 0; + virtual bool shaped_text_is_ready(const RID &p_shaped) const = 0; - virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const = 0; - Array _shaped_text_get_glyphs_wrapper(RID p_shaped) const; - virtual const Glyph *shaped_text_sort_logical(RID p_shaped) = 0; - Array _shaped_text_sort_logical_wrapper(RID p_shaped); - virtual int shaped_text_get_glyph_count(RID p_shaped) const = 0; + virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const = 0; + Array _shaped_text_get_glyphs_wrapper(const RID &p_shaped) const; + virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) = 0; + Array _shaped_text_sort_logical_wrapper(const RID &p_shaped); + virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const = 0; - virtual Vector2i shaped_text_get_range(RID p_shaped) const = 0; + virtual Vector2i shaped_text_get_range(const RID &p_shaped) const = 0; - virtual PackedInt32Array shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start = 0, bool p_once = true, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const; - virtual PackedInt32Array shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const; - virtual PackedInt32Array shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const; + virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const; + virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const; + virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const; - virtual int shaped_text_get_trim_pos(RID p_shaped) const = 0; - virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const = 0; - virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const = 0; - Array _shaped_text_get_ellipsis_glyphs_wrapper(RID p_shaped) const; - virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const = 0; + virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const = 0; + virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const = 0; + virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const = 0; + Array _shaped_text_get_ellipsis_glyphs_wrapper(const RID &p_shaped) const; + virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const = 0; - virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) = 0; + virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) = 0; - virtual Array shaped_text_get_objects(RID p_shaped) const = 0; - virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const = 0; + virtual Array shaped_text_get_objects(const RID &p_shaped) const = 0; + virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const = 0; - virtual Size2 shaped_text_get_size(RID p_shaped) const = 0; - virtual float shaped_text_get_ascent(RID p_shaped) const = 0; - virtual float shaped_text_get_descent(RID p_shaped) const = 0; - virtual float shaped_text_get_width(RID p_shaped) const = 0; - virtual float shaped_text_get_underline_position(RID p_shaped) const = 0; - virtual float shaped_text_get_underline_thickness(RID p_shaped) const = 0; + virtual Size2 shaped_text_get_size(const RID &p_shaped) const = 0; + virtual double shaped_text_get_ascent(const RID &p_shaped) const = 0; + virtual double shaped_text_get_descent(const RID &p_shaped) const = 0; + virtual double shaped_text_get_width(const RID &p_shaped) const = 0; + virtual double shaped_text_get_underline_position(const RID &p_shaped) const = 0; + virtual double shaped_text_get_underline_thickness(const RID &p_shaped) const = 0; - virtual Direction shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const; + virtual Direction shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const; - virtual CaretInfo shaped_text_get_carets(RID p_shaped, int p_position) const; - Dictionary _shaped_text_get_carets_wrapper(RID p_shaped, int p_position) const; + virtual CaretInfo shaped_text_get_carets(const RID &p_shaped, int64_t p_position) const; + Dictionary _shaped_text_get_carets_wrapper(const RID &p_shaped, int64_t p_position) const; - virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const; + virtual Vector<Vector2> shaped_text_get_selection(const RID &p_shaped, int64_t p_start, int64_t p_end) const; - virtual int shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const; // Return grapheme index. - virtual int shaped_text_hit_test_position(RID p_shaped, float p_coords) const; // Return caret/selection position. + virtual int64_t shaped_text_hit_test_grapheme(const RID &p_shaped, double p_coords) const; // Return grapheme index. + virtual int64_t shaped_text_hit_test_position(const RID &p_shaped, double p_coords) const; // Return caret/selection position. - virtual Vector2 shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) const; - virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const; - virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const; + virtual Vector2 shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const; + virtual int64_t shaped_text_next_grapheme_pos(const RID &p_shaped, int64_t p_pos) const; + virtual int64_t shaped_text_prev_grapheme_pos(const RID &p_shaped, int64_t p_pos) const; // The pen position is always placed on the baseline and moveing left to right. - virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const; - virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const; + virtual void shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1)) const; + virtual void shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const; // Number conversion. - virtual String format_number(const String &p_string, const String &p_language = "") const { return p_string; }; - virtual String parse_number(const String &p_string, const String &p_language = "") const { return p_string; }; - virtual String percent_sign(const String &p_language = "") const { return "%"; }; + virtual String format_number(const String &p_string, const String &p_language = "") const = 0; + virtual String parse_number(const String &p_string, const String &p_language = "") const = 0; + virtual String percent_sign(const String &p_language = "") const = 0; virtual String strip_diacritics(const String &p_string) const; @@ -501,23 +458,6 @@ struct CaretInfo { TextServer::Direction t_dir; }; -struct GlyphCompare { // For line breaking reordering. - _FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const { - if (l.start == r.start) { - if (l.count == r.count) { - if ((l.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) { - return false; - } else { - return true; - } - } - return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant. - } else { - return l.start < r.start; - } - } -}; - /*************************************************************************/ class TextServerManager : public Object { diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 6e105ffc26..62eba2f00b 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -45,7 +45,7 @@ struct BlitToScreen; If the user wants to enable AR/VR the choose the interface they want to use and initialize it. - Note that we may make this into a fully instantiable class for GDNative support. + Note that we may make this into a fully instantiable class for GDExtension support. */ class XRInterface : public RefCounted { diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index 7b21eeba04..4857167a8e 100644 --- a/servers/xr/xr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -49,6 +49,10 @@ void XRPositionalTracker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tracker_desc", "description"), &XRPositionalTracker::set_tracker_desc); ADD_PROPERTY(PropertyInfo(Variant::STRING, "description"), "set_tracker_desc", "get_tracker_desc"); + ClassDB::bind_method(D_METHOD("get_tracker_profile"), &XRPositionalTracker::get_tracker_profile); + ClassDB::bind_method(D_METHOD("set_tracker_profile", "profile"), &XRPositionalTracker::set_tracker_profile); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "profile"), "set_tracker_profile", "get_tracker_profile"); + ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRPositionalTracker::get_tracker_hand); ClassDB::bind_method(D_METHOD("set_tracker_hand", "hand"), &XRPositionalTracker::set_tracker_hand); ADD_PROPERTY(PropertyInfo(Variant::INT, "hand", PROPERTY_HINT_ENUM, "Unknown,Left,Right"), "set_tracker_hand", "get_tracker_hand"); @@ -65,10 +69,7 @@ void XRPositionalTracker::_bind_methods() { ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::STRING, "name"))); ADD_SIGNAL(MethodInfo("input_value_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "value"))); ADD_SIGNAL(MethodInfo("input_axis_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::VECTOR2, "vector"))); - - ClassDB::bind_method(D_METHOD("get_rumble"), &XRPositionalTracker::get_rumble); - ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRPositionalTracker::set_rumble); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble"), "set_rumble", "get_rumble"); + ADD_SIGNAL(MethodInfo("profile_changed", PropertyInfo(Variant::STRING, "role"))); }; void XRPositionalTracker::set_tracker_type(XRServer::TrackerType p_type) { @@ -99,6 +100,18 @@ String XRPositionalTracker::get_tracker_desc() const { return description; } +void XRPositionalTracker::set_tracker_profile(const String &p_profile) { + if (profile != p_profile) { + profile = p_profile; + + emit_signal("profile_changed", profile); + } +} + +String XRPositionalTracker::get_tracker_profile() const { + return profile; +} + XRPositionalTracker::TrackerHand XRPositionalTracker::get_tracker_hand() const { return hand; }; @@ -206,21 +219,8 @@ void XRPositionalTracker::set_input(const StringName &p_action_name, const Varia } } -real_t XRPositionalTracker::get_rumble() const { - return rumble; -}; - -void XRPositionalTracker::set_rumble(real_t p_rumble) { - if (p_rumble > 0.0) { - rumble = p_rumble; - } else { - rumble = 0.0; - }; -}; - XRPositionalTracker::XRPositionalTracker() { type = XRServer::TRACKER_UNKNOWN; name = "Unknown"; hand = TRACKER_HAND_UNKNOWN; - rumble = 0.0; }; diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index 2f358cbb21..cd06d4a087 100644 --- a/servers/xr/xr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -56,16 +56,13 @@ public: private: XRServer::TrackerType type; // type of tracker StringName name; // (unique) name of the tracker - String description; // description of the tracker, this is interface dependent, for OpenXR this will be the interaction profile bound for to the tracker + String description; // description of the tracker + String profile; // this is interface dependent, for OpenXR this will be the interaction profile bound for to the tracker TrackerHand hand; // if known, the hand this tracker is held in Map<StringName, Ref<XRPose>> poses; Map<StringName, Variant> inputs; - int joy_id; // if we also have a related joystick entity, the id of the joystick - Ref<Mesh> mesh; // when available, a mesh that can be used to render this tracker - real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, xr_interface is responsible for execution - protected: static void _bind_methods(); @@ -76,6 +73,8 @@ public: StringName get_tracker_name() const; void set_tracker_desc(const String &p_desc); String get_tracker_desc() const; + void set_tracker_profile(const String &p_profile); + String get_tracker_profile() const; XRPositionalTracker::TrackerHand get_tracker_hand() const; void set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand); @@ -87,10 +86,6 @@ public: Variant get_input(const StringName &p_action_name) const; void set_input(const StringName &p_action_name, const Variant &p_value); - // TODO replace by new implementation - real_t get_rumble() const; - void set_rumble(real_t p_rumble); - XRPositionalTracker(); ~XRPositionalTracker() {} }; diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index dbfe76a127..e32b41c7ae 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -348,9 +348,10 @@ PackedStringArray XRServer::get_suggested_pose_names(const StringName &p_tracker } void XRServer::_process() { - /* called from renderer_viewport.draw_viewports right before we start drawing our viewports */ + // called from our main game loop before we handle physics and game logic + // note that we can have multiple interfaces active if we have interfaces that purely handle tracking - /* process all active interfaces */ + // process all active interfaces for (int i = 0; i < interfaces.size(); i++) { if (!interfaces[i].is_valid()) { // ignore, not a valid reference |