Image: Add a method for detecting signed values
This commit is contained in:
parent
db76de5de8
commit
76c8211653
|
@ -3824,6 +3824,33 @@ void Image::bump_map_to_normal_map(float bump_scale) {
|
||||||
data = result_image;
|
data = result_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Image::detect_signed(bool p_include_mips) const {
|
||||||
|
ERR_FAIL_COND_V(is_compressed(), false);
|
||||||
|
|
||||||
|
if (format >= Image::FORMAT_RH && format <= Image::FORMAT_RGBAH) {
|
||||||
|
const uint16_t *img_data = reinterpret_cast<const uint16_t *>(data.ptr());
|
||||||
|
const uint64_t img_size = p_include_mips ? (data.size() / 2) : (width * height * get_format_pixel_size(format) / 2);
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < img_size; i++) {
|
||||||
|
if ((img_data[i] & 0x8000) != 0 && (img_data[i] & 0x7fff) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (format >= Image::FORMAT_RF && format <= Image::FORMAT_RGBAF) {
|
||||||
|
const uint32_t *img_data = reinterpret_cast<const uint32_t *>(data.ptr());
|
||||||
|
const uint64_t img_size = p_include_mips ? (data.size() / 4) : (width * height * get_format_pixel_size(format) / 4);
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < img_size; i++) {
|
||||||
|
if ((img_data[i] & 0x80000000) != 0 && (img_data[i] & 0x7fffffff) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Image::srgb_to_linear() {
|
void Image::srgb_to_linear() {
|
||||||
if (data.size() == 0) {
|
if (data.size() == 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -391,6 +391,8 @@ public:
|
||||||
Ref<Image> get_image_from_mipmap(int p_mipmap) const;
|
Ref<Image> get_image_from_mipmap(int p_mipmap) const;
|
||||||
void bump_map_to_normal_map(float bump_scale = 1.0);
|
void bump_map_to_normal_map(float bump_scale = 1.0);
|
||||||
|
|
||||||
|
bool detect_signed(bool p_include_mips = true) const;
|
||||||
|
|
||||||
void blit_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest);
|
void blit_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest);
|
||||||
void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2i &p_src_rect, const Point2i &p_dest);
|
void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2i &p_src_rect, const Point2i &p_dest);
|
||||||
void blend_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest);
|
void blend_rect(const Ref<Image> &p_src, const Rect2i &p_src_rect, const Point2i &p_dest);
|
||||||
|
|
|
@ -49,31 +49,6 @@ static int get_next_multiple(int n, int m) {
|
||||||
return n + (m - (n % m));
|
return n + (m - (n % m));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_image_signed(const Image *r_img) {
|
|
||||||
if (r_img->get_format() >= Image::FORMAT_RH && r_img->get_format() <= Image::FORMAT_RGBAH) {
|
|
||||||
const uint16_t *img_data = reinterpret_cast<const uint16_t *>(r_img->ptr());
|
|
||||||
const uint64_t img_size = r_img->get_data_size() / 2;
|
|
||||||
|
|
||||||
for (uint64_t i = 0; i < img_size; i++) {
|
|
||||||
if ((img_data[i] & 0x8000) != 0 && (img_data[i] & 0x7fff) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (r_img->get_format() >= Image::FORMAT_RF && r_img->get_format() <= Image::FORMAT_RGBAF) {
|
|
||||||
const uint32_t *img_data = reinterpret_cast<const uint32_t *>(r_img->ptr());
|
|
||||||
const uint64_t img_size = r_img->get_data_size() / 4;
|
|
||||||
|
|
||||||
for (uint64_t i = 0; i < img_size; i++) {
|
|
||||||
if ((img_data[i] & 0x80000000) != 0 && (img_data[i] & 0x7fffffff) != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error _compress_betsy(BetsyFormat p_format, Image *r_img) {
|
Error _compress_betsy(BetsyFormat p_format, Image *r_img) {
|
||||||
uint64_t start_time = OS::get_singleton()->get_ticks_msec();
|
uint64_t start_time = OS::get_singleton()->get_ticks_msec();
|
||||||
|
|
||||||
|
@ -125,7 +100,7 @@ Error _compress_betsy(BetsyFormat p_format, Image *r_img) {
|
||||||
case BETSY_FORMAT_BC6: {
|
case BETSY_FORMAT_BC6: {
|
||||||
err = compute_shader->parse_versions_from_text(bc6h_shader_glsl);
|
err = compute_shader->parse_versions_from_text(bc6h_shader_glsl);
|
||||||
|
|
||||||
if (is_image_signed(r_img)) {
|
if (r_img->detect_signed(true)) {
|
||||||
dest_format = Image::FORMAT_BPTC_RGBF;
|
dest_format = Image::FORMAT_BPTC_RGBF;
|
||||||
version = "signed";
|
version = "signed";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -174,17 +174,7 @@ void image_compress_cvtt(Image *p_image, Image::UsedChannels p_channels) {
|
||||||
p_image->convert(Image::FORMAT_RGBH);
|
p_image->convert(Image::FORMAT_RGBH);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *rb = p_image->get_data().ptr();
|
is_signed = p_image->detect_signed();
|
||||||
|
|
||||||
const uint16_t *source_data = reinterpret_cast<const uint16_t *>(&rb[0]);
|
|
||||||
int pixel_element_count = w * h * 3;
|
|
||||||
for (int i = 0; i < pixel_element_count; i++) {
|
|
||||||
if ((source_data[i] & 0x8000) != 0 && (source_data[i] & 0x7fff) != 0) {
|
|
||||||
is_signed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
target_format = is_signed ? Image::FORMAT_BPTC_RGBF : Image::FORMAT_BPTC_RGBFU;
|
target_format = is_signed ? Image::FORMAT_BPTC_RGBF : Image::FORMAT_BPTC_RGBFU;
|
||||||
} else {
|
} else {
|
||||||
p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
|
p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
|
||||||
|
|
Loading…
Reference in New Issue