mirror of
https://github.com/godotengine/godot.git
synced 2026-01-06 10:11:57 +03: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:
@@ -1758,11 +1758,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 Texture2D.
|
||||
|
||||
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) {
|
||||
@@ -1800,30 +1805,49 @@ void GradientTexture::_update() {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<uint8_t> data;
|
||||
data.resize(width * 4);
|
||||
{
|
||||
uint8_t *wd8 = data.ptrw();
|
||||
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.
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
|
||||
|
||||
if (texture.is_valid()) {
|
||||
RID new_texture = RS::get_singleton()->texture_2d_create(image);
|
||||
RS::get_singleton()->texture_replace(texture, new_texture);
|
||||
if (texture.is_valid()) {
|
||||
RID new_texture = RS::get_singleton()->texture_2d_create(image);
|
||||
RS::get_singleton()->texture_replace(texture, new_texture);
|
||||
} else {
|
||||
texture = RS::get_singleton()->texture_2d_create(image);
|
||||
}
|
||||
} else {
|
||||
texture = RS::get_singleton()->texture_2d_create(image);
|
||||
// Low dynamic range. "Overbright" colors will be clamped.
|
||||
Vector<uint8_t> data;
|
||||
data.resize(width * 4);
|
||||
{
|
||||
uint8_t *wd8 = data.ptrw();
|
||||
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));
|
||||
|
||||
if (texture.is_valid()) {
|
||||
RID new_texture = RS::get_singleton()->texture_2d_create(image);
|
||||
RS::get_singleton()->texture_replace(texture, new_texture);
|
||||
} else {
|
||||
texture = RS::get_singleton()->texture_2d_create(image);
|
||||
}
|
||||
}
|
||||
|
||||
emit_changed();
|
||||
@@ -1839,6 +1863,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_image() const {
|
||||
if (!texture.is_valid()) {
|
||||
return Ref<Image>();
|
||||
|
||||
Reference in New Issue
Block a user