optimize alphamap updates

This commit is contained in:
T1ti
2025-10-16 22:50:07 +02:00
parent 0d600577da
commit 061c18e069
2 changed files with 47 additions and 17 deletions

View File

@@ -1506,11 +1506,21 @@ void MapTile::setAlphaImage(QImage const& baseimage, unsigned layer, bool cleanu
chunk->texture_set->create_temporary_alphamaps_if_needed();
auto& temp_alphamaps = *chunk->texture_set->getTempAlphamaps();
for (int i = 0; i < 64; ++i)
float* dst = temp_alphamaps[layer].data();
const int base_x = k * 64;
const int base_y = l * 64;
for (int j = 0; j < 64; ++j)
{
for (int j = 0; j < 64; ++j)
const int row_offset = j * 64;
const int img_y = base_y + j;
for (int i = 0; i < 64; ++i)
{
temp_alphamaps[layer][64 * j + i] = static_cast<float>(qGray(image.pixel((k * 64) + i, (l * 64) + j)));
const int img_x = base_x + i;
QRgb px = image.pixel(img_x, img_y);
dst[row_offset + i] = static_cast<float>(qGray(px));
}
}

View File

@@ -1528,23 +1528,34 @@ void TextureSet::updateDoodadMapping()
if (debug_test)
blizzard_mapping_readable = getDoodadMappingReadable();
// 8x8 bits per unit
for (int unit_x = 0; unit_x < 8; unit_x++)
constexpr int TILE_SIZE = 64;
constexpr int UNIT_SIZE = 8;
constexpr int NUM_UNITS = TILE_SIZE / UNIT_SIZE; // 8
for (int unit_x = 0; unit_x < NUM_UNITS; unit_x++)
{
for (int unit_y = 0; unit_y < 8; unit_y++)
for (int unit_y = 0; unit_y < NUM_UNITS; unit_y++)
{
int layer_totals[4]{ 0,0,0,0 };
const int unit_base_y = unit_y * UNIT_SIZE;
const int unit_base_x = unit_x * UNIT_SIZE;
// 8x8 bits per unit
for (int x = 0; x < 8; x++)
for (int y = 0; y < UNIT_SIZE; y++)
{
for (int y = 0; y < 8; y++)
const int row_base = (unit_base_y + y) * TILE_SIZE + unit_base_x;
for (int x = 0; x < UNIT_SIZE; x++)
{
int base_alpha = 255;
const int alpha_pos = row_base + x;
// const int alpha_pos = (unit_y * 8 + y) * 64 + (unit_x * 8 + x);
for (int alpha_layer = 0; alpha_layer < (nTextures - 1); ++alpha_layer)
{
int alpha = static_cast<int>(alphamaps[alpha_layer]->getAlpha((unit_y * 8 + y) * 64 + (unit_x * 8 + x)));
const int alpha = static_cast<int>(alphamaps[alpha_layer]->getAlpha(alpha_pos));
layer_totals[alpha_layer+1] += alpha;
@@ -1637,7 +1648,12 @@ namespace
{
std::uint8_t float_alpha_to_uint8(float a)
{
return static_cast<std::uint8_t>(std::max(0.f, std::min(255.f, std::round(a))));
// return static_cast<std::uint8_t>(std::max(0.f, std::min(255.f, std::round(a))));
int v = static_cast<int>(a + 0.5f);
if (static_cast<unsigned>(v) > 255u)
v = v < 0 ? 0 : 255;
return static_cast<std::uint8_t>(v);
}
}
@@ -1648,25 +1664,29 @@ bool TextureSet::apply_alpha_changes()
tmp_edit_values.reset();
return false;
}
constexpr int ALPHA_SIZE = 64 * 64;
auto& new_amaps = *tmp_edit_values;
std::array<std::uint16_t, 64 * 64> totals;
std::array<std::uint16_t, ALPHA_SIZE> totals;
totals.fill(0);
for (int alpha_layer = 0; alpha_layer < nTextures - 1; ++alpha_layer)
{
std::array<std::uint8_t, 64 * 64> values;
std::array<std::uint8_t, ALPHA_SIZE> values;
for (int i = 0; i < 64 * 64; ++i)
auto& tmp_layer = new_amaps[alpha_layer + 1];
for (int i = 0; i < ALPHA_SIZE; ++i)
{
values[i] = float_alpha_to_uint8(new_amaps[alpha_layer + 1][i]);
totals[i] += values[i];
uint8_t new_value = float_alpha_to_uint8(tmp_layer[i]);
values[i] = new_value;
uint16_t total = totals[i] += new_value;
// remove the possible overflow with rounding
// max 2 if all 4 values round up so it won't change the layer's alpha much
if (totals[i] > 255)
if (total > 255)
{
values[i] -= static_cast<std::uint8_t>(totals[i] - 255);
new_value -= static_cast<std::uint8_t>(total - 255);
}
}