mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-26 13:47:12 +01:00
Add an use_hdr
property to GradientTexture to allow storing HDR colors
This is disabled by default to save some memory and preserve the existing behavior of clamping colors.
This commit is contained in:
parent
089135783e
commit
c751d9dc17
@ -14,6 +14,9 @@
|
||||
<member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient">
|
||||
The [Gradient] that will be used to fill the texture.
|
||||
</member>
|
||||
<member name="use_hdr" type="bool" setter="set_use_hdr" getter="is_using_hdr" default="false">
|
||||
If [code]true[/code], the generated texture will support high dynamic range ([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/code], the generated texture will use low dynamic range; overbright colors will be clamped ([constant Image.FORMAT_RGBA8] format).
|
||||
</member>
|
||||
<member name="width" type="int" setter="set_width" getter="get_width" default="2048">
|
||||
The number of color samples that will be obtained from the [Gradient].
|
||||
</member>
|
||||
|
@ -1724,11 +1724,16 @@ void GradientTexture::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_gradient"), &GradientTexture::get_gradient);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture::set_width);
|
||||
// The `get_width()` method is already exposed by the parent class Texture.
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_use_hdr", "enabled"), &GradientTexture::set_use_hdr);
|
||||
ClassDB::bind_method(D_METHOD("is_using_hdr"), &GradientTexture::is_using_hdr);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
|
||||
}
|
||||
|
||||
void GradientTexture::set_gradient(Ref<Gradient> p_gradient) {
|
||||
@ -1766,28 +1771,44 @@ void GradientTexture::_update() {
|
||||
return;
|
||||
}
|
||||
|
||||
PoolVector<uint8_t> data;
|
||||
data.resize(width * 4);
|
||||
{
|
||||
PoolVector<uint8_t>::Write wd8 = data.write();
|
||||
if (use_hdr) {
|
||||
// High dynamic range.
|
||||
Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBAF));
|
||||
Gradient &g = **gradient;
|
||||
|
||||
// `create()` isn't available for non-uint8_t data, so fill in the data manually.
|
||||
image->lock();
|
||||
for (int i = 0; i < width; i++) {
|
||||
float ofs = float(i) / (width - 1);
|
||||
Color color = g.get_color_at_offset(ofs);
|
||||
|
||||
wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255));
|
||||
wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255));
|
||||
wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255));
|
||||
wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255));
|
||||
image->set_pixel(i, 0, g.get_color_at_offset(ofs));
|
||||
}
|
||||
image->unlock();
|
||||
|
||||
VS::get_singleton()->texture_allocate(texture, width, 1, 0, Image::FORMAT_RGBAF, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
|
||||
VS::get_singleton()->texture_set_data(texture, image);
|
||||
} else {
|
||||
// Low dynamic range. "Overbright" colors will be clamped.
|
||||
PoolVector<uint8_t> data;
|
||||
data.resize(width * 4);
|
||||
{
|
||||
PoolVector<uint8_t>::Write wd8 = data.write();
|
||||
Gradient &g = **gradient;
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
float ofs = float(i) / (width - 1);
|
||||
Color color = g.get_color_at_offset(ofs);
|
||||
|
||||
wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255));
|
||||
wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255));
|
||||
wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255));
|
||||
wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255));
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
|
||||
VS::get_singleton()->texture_allocate(texture, width, 1, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
|
||||
VS::get_singleton()->texture_set_data(texture, image);
|
||||
}
|
||||
|
||||
Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
|
||||
|
||||
VS::get_singleton()->texture_allocate(texture, width, 1, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
|
||||
VS::get_singleton()->texture_set_data(texture, image);
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
@ -1799,6 +1820,19 @@ int GradientTexture::get_width() const {
|
||||
return width;
|
||||
}
|
||||
|
||||
void GradientTexture::set_use_hdr(bool p_enabled) {
|
||||
if (p_enabled == use_hdr) {
|
||||
return;
|
||||
}
|
||||
|
||||
use_hdr = p_enabled;
|
||||
_queue_update();
|
||||
}
|
||||
|
||||
bool GradientTexture::is_using_hdr() const {
|
||||
return use_hdr;
|
||||
}
|
||||
|
||||
Ref<Image> GradientTexture::get_data() const {
|
||||
return VisualServer::get_singleton()->texture_get_data(texture);
|
||||
}
|
||||
|
@ -620,6 +620,7 @@ private:
|
||||
bool update_pending;
|
||||
RID texture;
|
||||
int width;
|
||||
bool use_hdr = false;
|
||||
|
||||
void _queue_update();
|
||||
void _update();
|
||||
@ -634,6 +635,9 @@ public:
|
||||
void set_width(int p_width);
|
||||
int get_width() const;
|
||||
|
||||
void set_use_hdr(bool p_enabled);
|
||||
bool is_using_hdr() const;
|
||||
|
||||
virtual RID get_rid() const { return texture; }
|
||||
virtual int get_height() const { return 1; }
|
||||
virtual bool has_alpha() const { return true; }
|
||||
|
Loading…
Reference in New Issue
Block a user