Skip to content

Commit f9be832

Browse files
committed
Merge pull request godotengine#110257 from BlueCube3310/mip-gen-all-formats
Image: Support generating mipmaps for all uncompressed formats
2 parents 4866264 + f64ccad commit f9be832

File tree

2 files changed

+59
-34
lines changed

2 files changed

+59
-34
lines changed

core/io/image.cpp

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,7 +1969,7 @@ static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint3
19691969
average_func(dst_ptr[j], rup_ptr[j], rup_ptr[j + right_step], rdown_ptr[j], rdown_ptr[j + right_step]);
19701970
}
19711971

1972-
if (renormalize) {
1972+
if constexpr (renormalize) {
19731973
renormalize_func(dst_ptr);
19741974
}
19751975

@@ -2015,6 +2015,12 @@ void Image::_generate_mipmap_from_format(Image::Format p_format, const uint8_t *
20152015
_generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(p_src, p_dst, p_width, p_height);
20162016
}
20172017
} break;
2018+
case Image::FORMAT_RGBA4444: {
2019+
_generate_po2_mipmap<uint16_t, 1, false, Image::average_4_rgba4444, nullptr>(src_u16, dst_u16, p_width, p_height);
2020+
} break;
2021+
case Image::FORMAT_RGB565: {
2022+
_generate_po2_mipmap<uint16_t, 1, false, Image::average_4_rgb565, nullptr>(src_u16, dst_u16, p_width, p_height);
2023+
} break;
20182024
case Image::FORMAT_RF:
20192025
_generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(src_float, dst_float, p_width, p_height);
20202026
break;
@@ -2056,7 +2062,7 @@ void Image::_generate_mipmap_from_format(Image::Format p_format, const uint8_t *
20562062
}
20572063
} break;
20582064
case Image::FORMAT_RGBE9995:
2059-
_generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(src_u32, dst_u32, p_width, p_height);
2065+
_generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, nullptr>(src_u32, dst_u32, p_width, p_height);
20602066
break;
20612067
case Image::FORMAT_R16:
20622068
case Image::FORMAT_R16I:
@@ -2141,7 +2147,6 @@ void Image::normalize() {
21412147

21422148
Error Image::generate_mipmaps(bool p_renormalize) {
21432149
ERR_FAIL_COND_V_MSG(is_compressed(), ERR_UNAVAILABLE, "Cannot generate mipmaps from compressed image formats.");
2144-
ERR_FAIL_COND_V_MSG(format == FORMAT_RGBA4444, ERR_UNAVAILABLE, "Cannot generate mipmaps from RGBA4444 format.");
21452150
ERR_FAIL_COND_V_MSG(width == 0 || height == 0, ERR_UNCONFIGURED, "Cannot generate mipmaps with width or height equal to 0.");
21462151

21472152
int gen_mipmap_count;
@@ -3376,6 +3381,42 @@ void Image::_copy_internals_from(const Image &p_image) {
33763381
data = p_image.data;
33773382
}
33783383

3384+
_FORCE_INLINE_ Color color_from_rgba4444(uint16_t p_col) {
3385+
float r = ((p_col >> 12) & 0xF) / 15.0;
3386+
float g = ((p_col >> 8) & 0xF) / 15.0;
3387+
float b = ((p_col >> 4) & 0xF) / 15.0;
3388+
float a = (p_col & 0xF) / 15.0;
3389+
return Color(r, g, b, a);
3390+
}
3391+
3392+
_FORCE_INLINE_ uint16_t color_to_rgba4444(Color p_col) {
3393+
uint16_t rgba = 0;
3394+
3395+
rgba = uint16_t(CLAMP(p_col.r * 15.0, 0, 15)) << 12;
3396+
rgba |= uint16_t(CLAMP(p_col.g * 15.0, 0, 15)) << 8;
3397+
rgba |= uint16_t(CLAMP(p_col.b * 15.0, 0, 15)) << 4;
3398+
rgba |= uint16_t(CLAMP(p_col.a * 15.0, 0, 15));
3399+
3400+
return rgba;
3401+
}
3402+
3403+
_FORCE_INLINE_ Color color_from_rgb565(uint16_t p_col) {
3404+
float r = ((p_col >> 11) & 0x1F) / 31.0;
3405+
float g = ((p_col >> 5) & 0x3F) / 63.0;
3406+
float b = (p_col & 0x1F) / 31.0;
3407+
return Color(r, g, b, 1.0);
3408+
}
3409+
3410+
_FORCE_INLINE_ uint16_t color_to_rgb565(Color p_col) {
3411+
uint16_t rgba = 0;
3412+
3413+
rgba = uint16_t(CLAMP(p_col.r * 31.0, 0, 31)) << 11;
3414+
rgba |= uint16_t(CLAMP(p_col.g * 63.0, 0, 63)) << 5;
3415+
rgba |= uint16_t(CLAMP(p_col.b * 31.0, 0, 31));
3416+
3417+
return rgba;
3418+
}
3419+
33793420
Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const {
33803421
switch (format) {
33813422
case FORMAT_L8: {
@@ -3410,19 +3451,10 @@ Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const {
34103451
return Color(r, g, b, a);
34113452
}
34123453
case FORMAT_RGBA4444: {
3413-
uint16_t u = ((uint16_t *)ptr)[ofs];
3414-
float r = ((u >> 12) & 0xF) / 15.0;
3415-
float g = ((u >> 8) & 0xF) / 15.0;
3416-
float b = ((u >> 4) & 0xF) / 15.0;
3417-
float a = (u & 0xF) / 15.0;
3418-
return Color(r, g, b, a);
3454+
return color_from_rgba4444(((uint16_t *)ptr)[ofs]);
34193455
}
34203456
case FORMAT_RGB565: {
3421-
uint16_t u = ((uint16_t *)ptr)[ofs];
3422-
float r = ((u >> 11) & 0x1F) / 31.0;
3423-
float g = ((u >> 5) & 0x3F) / 63.0;
3424-
float b = (u & 0x1F) / 31.0;
3425-
return Color(r, g, b, 1.0);
3457+
return color_from_rgb565(((uint16_t *)ptr)[ofs]);
34263458
}
34273459
case FORMAT_RF: {
34283460
float r = ((float *)ptr)[ofs];
@@ -3550,23 +3582,10 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color)
35503582
ptr[ofs * 4 + 3] = uint8_t(CLAMP(p_color.a * 255.0, 0, 255));
35513583
} break;
35523584
case FORMAT_RGBA4444: {
3553-
uint16_t rgba = 0;
3554-
3555-
rgba = uint16_t(CLAMP(p_color.r * 15.0, 0, 15)) << 12;
3556-
rgba |= uint16_t(CLAMP(p_color.g * 15.0, 0, 15)) << 8;
3557-
rgba |= uint16_t(CLAMP(p_color.b * 15.0, 0, 15)) << 4;
3558-
rgba |= uint16_t(CLAMP(p_color.a * 15.0, 0, 15));
3559-
3560-
((uint16_t *)ptr)[ofs] = rgba;
3585+
((uint16_t *)ptr)[ofs] = color_to_rgba4444(p_color);
35613586
} break;
35623587
case FORMAT_RGB565: {
3563-
uint16_t rgba = 0;
3564-
3565-
rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31)) << 11;
3566-
rgba |= uint16_t(CLAMP(p_color.g * 63.0, 0, 63)) << 5;
3567-
rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31));
3568-
3569-
((uint16_t *)ptr)[ofs] = rgba;
3588+
((uint16_t *)ptr)[ofs] = color_to_rgb565(p_color);
35703589
} break;
35713590
case FORMAT_RF: {
35723591
((float *)ptr)[ofs] = p_color.r;
@@ -4540,6 +4559,14 @@ void Image::average_4_uint16(uint16_t &p_out, const uint16_t &p_a, const uint16_
45404559
p_out = static_cast<uint16_t>((p_a + p_b + p_c + p_d + 2) >> 2);
45414560
}
45424561

4562+
void Image::average_4_rgba4444(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d) {
4563+
p_out = color_to_rgba4444((color_from_rgba4444(p_a) + color_from_rgba4444(p_b) + color_from_rgba4444(p_c) + color_from_rgba4444(p_d)) * 0.25f);
4564+
}
4565+
4566+
void Image::average_4_rgb565(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d) {
4567+
p_out = color_to_rgb565((color_from_rgb565(p_a) + color_from_rgb565(p_b) + color_from_rgb565(p_c) + color_from_rgb565(p_d)) * 0.25f);
4568+
}
4569+
45434570
void Image::renormalize_uint8(uint8_t *p_rgb) {
45444571
Vector3 n(p_rgb[0] / 255.0, p_rgb[1] / 255.0, p_rgb[2] / 255.0);
45454572
n *= 2.0;
@@ -4569,10 +4596,6 @@ void Image::renormalize_half(uint16_t *p_rgb) {
45694596
p_rgb[2] = Math::make_half_float(n.z);
45704597
}
45714598

4572-
void Image::renormalize_rgbe9995(uint32_t *p_rgb) {
4573-
// Never used.
4574-
}
4575-
45764599
void Image::renormalize_uint16(uint16_t *p_rgb) {
45774600
Vector3 n(p_rgb[0] / 65535.0, p_rgb[1] / 65535.0, p_rgb[2] / 65535.0);
45784601
n *= 2.0;

core/io/image.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,12 @@ class Image : public Resource {
291291
static void average_4_half(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d);
292292
static void average_4_rgbe9995(uint32_t &p_out, const uint32_t &p_a, const uint32_t &p_b, const uint32_t &p_c, const uint32_t &p_d);
293293
static void average_4_uint16(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d);
294+
static void average_4_rgba4444(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d);
295+
static void average_4_rgb565(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d);
296+
294297
static void renormalize_uint8(uint8_t *p_rgb);
295298
static void renormalize_float(float *p_rgb);
296299
static void renormalize_half(uint16_t *p_rgb);
297-
static void renormalize_rgbe9995(uint32_t *p_rgb);
298300
static void renormalize_uint16(uint16_t *p_rgb);
299301

300302
public:

0 commit comments

Comments
 (0)