Browse Source

Palette blending: minor cleanups

1. Removes stray comments.
2. Loops only over half of the matrix.
3. Adds tests for `paletteTransparencyLookupBlack16`.
pull/8028/head
Gleb Mazovetskiy 10 months ago
parent
commit
c8106a7f6d
  1. 13
      Source/engine/palette.cpp
  2. 36
      Source/utils/palette_blending.cpp
  3. 19
      test/palette_blending_test.cpp

13
Source/engine/palette.cpp

@ -39,19 +39,6 @@ void LoadBrightness()
GetOptions().Graphics.brightness.SetValue(brightnessValue - brightnessValue % 5);
}
/**
* @brief Generate lookup table for transparency
*
* This is based of the same technique found in Quake2.
*
* To mimic 50% transparency we figure out what colors in the existing palette are the best match for the combination of any 2 colors.
* We save this into a lookup table for use during rendering.
*
* @param palette The colors to operate on
* @param skipFrom Do not use colors between this index and skipTo
* @param skipTo Do not use colors between skipFrom and this index
* @param toUpdate Only update the first n colors
*/
/**
* @brief Cycle the given range of colors in the palette
* @param from First color index of the range

36
Source/utils/palette_blending.cpp

@ -53,20 +53,25 @@ RGB BlendColors(const SDL_Color &a, const SDL_Color &b)
};
}
#if DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT
void SetPaletteTransparencyLookupBlack16(unsigned i, unsigned j)
{
paletteTransparencyLookupBlack16[i | (j << 8U)] = paletteTransparencyLookup[0][i] | (paletteTransparencyLookup[0][j] << 8U);
}
#endif
} // namespace
void GenerateBlendedLookupTable(SDL_Color palette[256], int skipFrom, int skipTo)
{
for (unsigned i = 0; i < 256; i++) {
for (unsigned j = 0; j < 256; j++) {
if (i == j) { // No need to calculate transparency between 2 identical colors
paletteTransparencyLookup[i][j] = j;
continue;
}
if (i > j) { // Half the blends will be mirror identical ([i][j] is the same as [j][i]), so simply copy the existing combination.
paletteTransparencyLookup[i][j] = paletteTransparencyLookup[j][i];
continue;
}
paletteTransparencyLookup[i][i] = i;
unsigned j = 0;
for (; j < i; j++) {
paletteTransparencyLookup[i][j] = paletteTransparencyLookup[j][i];
}
++j;
for (; j < 256; j++) {
const uint8_t best = FindBestMatchForColor(palette, BlendColors(palette[i], palette[j]), skipFrom, skipTo);
paletteTransparencyLookup[i][j] = best;
}
@ -74,9 +79,10 @@ void GenerateBlendedLookupTable(SDL_Color palette[256], int skipFrom, int skipTo
#if DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT
for (unsigned i = 0; i < 256; ++i) {
for (unsigned j = 0; j < 256; ++j) {
const uint16_t index = i | (j << 8U);
paletteTransparencyLookupBlack16[index] = paletteTransparencyLookup[0][i] | (paletteTransparencyLookup[0][j] << 8);
SetPaletteTransparencyLookupBlack16(i, i);
for (unsigned j = 0; j < i; ++j) {
SetPaletteTransparencyLookupBlack16(i, j);
SetPaletteTransparencyLookupBlack16(j, i);
}
}
#endif
@ -104,10 +110,8 @@ void UpdateTransparencyLookupBlack16(unsigned from, unsigned to)
{
for (unsigned i = from; i <= to; i++) {
for (unsigned j = 0; j < 256; j++) {
const uint16_t index = i | (j << 8U);
const uint16_t reverseIndex = j | (i << 8U);
paletteTransparencyLookupBlack16[index] = paletteTransparencyLookup[0][i] | (paletteTransparencyLookup[0][j] << 8);
paletteTransparencyLookupBlack16[reverseIndex] = paletteTransparencyLookup[0][j] | (paletteTransparencyLookup[0][i] << 8);
SetPaletteTransparencyLookupBlack16(i, j);
SetPaletteTransparencyLookupBlack16(j, i);
}
}
}

19
test/palette_blending_test.cpp

@ -47,6 +47,8 @@ TEST(GenerateBlendedLookupTableTest, BasicTest)
GenerateBlendedLookupTable(palette, /*skipFrom=*/-1, /*skipTo=*/-1);
EXPECT_EQ(paletteTransparencyLookup[100][100], 100);
EXPECT_THAT(palette[17], ColorIs(17, 0, 34));
EXPECT_THAT(palette[150], ColorIs(44, 44, 44));
EXPECT_THAT(palette[86], ColorIs(22, 22, 44));
@ -58,6 +60,23 @@ TEST(GenerateBlendedLookupTableTest, BasicTest)
EXPECT_THAT(palette[15], ColorIs(15, 0, 30));
EXPECT_EQ(paletteTransparencyLookup[27][130], 15);
EXPECT_EQ(paletteTransparencyLookup[130][27], 15);
EXPECT_THAT(palette[0], ColorIs(0, 0, 0));
EXPECT_THAT(palette[100], ColorIs(36, 36, 72));
EXPECT_THAT(palette[82], ColorIs(18, 18, 36));
EXPECT_EQ(paletteTransparencyLookup[0][100], 82);
EXPECT_EQ(paletteTransparencyLookup[100][0], 82);
EXPECT_THAT(palette[0], ColorIs(0, 0, 0));
EXPECT_THAT(palette[200], ColorIs(24, 24, 16));
EXPECT_THAT(palette[196], ColorIs(12, 12, 8));
EXPECT_EQ(paletteTransparencyLookup[0][200], 196);
EXPECT_EQ(paletteTransparencyLookup[200][0], 196);
#if DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT
EXPECT_EQ(paletteTransparencyLookupBlack16[100 | (100 << 8)], 82 | (82 << 8));
EXPECT_EQ(paletteTransparencyLookupBlack16[100 | (200 << 8)], 82 | (196 << 8));
#endif
}
} // namespace

Loading…
Cancel
Save