Skip to content

Instantly share code, notes, and snippets.

@numberZero
Last active September 22, 2018 22:36
Show Gist options
  • Save numberZero/f77ec029b86dd31b00d3b70c06907fa5 to your computer and use it in GitHub Desktop.
Save numberZero/f77ec029b86dd31b00d3b70c06907fa5 to your computer and use it in GitHub Desktop.
diff --git a/src/client/tile.cpp b/src/client/tile.cpp
index fe26832d4..ee20a687b 100644
--- a/src/client/tile.cpp
+++ b/src/client/tile.cpp
@@ -770,9 +770,9 @@ void TextureSource::rebuildImagesAndTextures()
}
}
-inline static void applyShadeFactor(video::SColor &color, float factor)
+inline static void applyShadeFactor(video::SColor &color, u32 factor)
{
- u8 f = core::clamp<u32>(256 * factor, 0, 256);
+ u32 f = core::clamp<u32>(factor, 0, 256);
color.setRed(color.getRed() * f / 256);
color.setGreen(color.getGreen() * f / 256);
color.setBlue(color.getBlue() * f / 256);
@@ -802,8 +802,8 @@ static video::IImage *createInventoryCubeImage(
// With such parameters, the cube fits exactly, touching each image line
// from `0` to `cube_size - 1`. (Note that division is exact here).
- u32 cube_size = 4 * size + size / 2;
- u32 offset = size / 4 - 1;
+ u32 cube_size = 9 * size;
+ u32 offset = size / 2;
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
@@ -828,84 +828,65 @@ static video::IImage *createInventoryCubeImage(
video::IImage *result = driver->createImage(video::ECF_A8R8G8B8, {cube_size, cube_size});
sanity_check(result->getPitch() == 4 * cube_size);
result->fill(video::SColor(0x00000000u));
-
u32 *target = reinterpret_cast<u32 *>(result->lock());
- u32 const *source;
- u32 j;
-#define TARGET(u,v) target[(v) * cube_size + (u) + offset]
-
- /* Draw top image.
- *
- * Left edge spans lines `0` to `size - 1`, and whole image spans
- * lines from `0` to `2 * size - 2` inclusive.
- */
- source = lock_image(top);
- for (int v = 0; v < size; v++) {
- for (int u = 0; u < size; u++) {
- video::SColor pixel(*source);
- TARGET(2 * u + 2 * (size - 1 - v) + 0, u + v) = pixel.color;
- TARGET(2 * u + 2 * (size - 1 - v) + 1, u + v) = pixel.color;
- TARGET(2 * u + 2 * (size - 1 - v) + 2, u + v) = pixel.color;
- TARGET(2 * u + 2 * (size - 1 - v) + 3, u + v) = pixel.color;
- source++;
- }
- }
- free_image(top);
-
- /* Draw left image.
- *
- * Line height on TARGET is alternating between 2 and 3 pixels,
- * leading to `2.5 * size` resulting height—*exactly*. Plus starting
- * offset of `size`, plus skew (`0` to `size - 1`), so it touches scan
- * lines from `size` to `4.5 * size - 2` *exactly*.
- */
- source = lock_image(left);
- j = size;
- for (int v = 0; v < size; v++) {
- bool flag = v % 2;
- for (int u = 0; u < size; u++) {
- video::SColor pixel(*source);
- applyShadeFactor(pixel, 0.836660f);
- TARGET(2 * u + 0, j + u + 0) = pixel.color;
- TARGET(2 * u + 1, j + u + 0) = pixel.color;
- TARGET(2 * u + 0, j + u + 1) = pixel.color;
- TARGET(2 * u + 1, j + u + 1) = pixel.color;
- if (flag) {
- TARGET(2 * u + 0, j + u + 2) = pixel.color;
- TARGET(2 * u + 1, j + u + 2) = pixel.color;
- }
- source++;
- }
- j += flag ? 3 : 2;
- }
- free_image(left);
- /* Draw right image.
- *
- * Works the same way as for left image, touching the same lines.
- */
- source = lock_image(right);
- j = size;
- for (int v = 0; v < size; v++) {
- bool flag = v % 2;
- for (int u = 0; u < size; u++) {
- video::SColor pixel(*source);
- applyShadeFactor(pixel, 0.670820f);
- TARGET(2 * u + 2 * size + 0, j + size - u - 1) = pixel.color;
- TARGET(2 * u + 2 * size + 1, j + size - u - 1) = pixel.color;
- TARGET(2 * u + 2 * size + 0, j + size - u + 0) = pixel.color;
- TARGET(2 * u + 2 * size + 1, j + size - u + 0) = pixel.color;
- if (flag) {
- TARGET(2 * u + 2 * size + 0, j + size - u + 1) = pixel.color;
- TARGET(2 * u + 2 * size + 1, j + size - u + 1) = pixel.color;
+ // Draws single cube face
+ // `shade_factor` is face brightness, in range [0.0, 1.0]
+ // (xu, xv, x1; yu, yv, y1) form coordinate transformation matrix
+ // `offsets` list pixels to be drawn for single source pixel
+ auto draw_image = [=] (video::IImage *image, float shade_factor,
+ s16 xu, s16 xv, s16 x1,
+ s16 yu, s16 yv, s16 y1,
+ std::initializer_list<v2s16> offsets) -> void {
+ u32 brightness = core::clamp<u32>(256 * shade_factor, 0, 256);
+ u32 const *source = lock_image(image);
+ for (u16 v = 0; v < size; v++) {
+ for (u16 u = 0; u < size; u++) {
+ video::SColor pixel(*source);
+ applyShadeFactor(pixel, brightness);
+ s16 x = xu * u + xv * v + x1;
+ s16 y = yu * u + yv * v + y1;
+ for (auto const &off: offsets)
+ target[(y + off.Y) * cube_size + (x + off.X) + offset] = pixel.color;
+ source++;
}
- source++;
}
- j += flag ? 3 : 2;
- }
- free_image(right);
+ free_image(image);
+ };
+
+ draw_image(top, 1.000000f,
+ 4, -4, 4 * (size - 1),
+ 2, 2, 0,
+ {
+ {2, 0}, {3, 0}, {4, 0}, {5, 0},
+ {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1},
+ {2, 2}, {3, 2}, {4, 2}, {5, 2},
+ });
+
+ draw_image(left, 0.836660f,
+ 4, 0, 0,
+ 2, 5, 2 * size,
+ {
+ {0, 0}, {1, 0},
+ {0, 1}, {1, 1}, {2, 1}, {3, 1},
+ {0, 2}, {1, 2}, {2, 2}, {3, 2},
+ {0, 3}, {1, 3}, {2, 3}, {3, 3},
+ {0, 4}, {1, 4}, {2, 4}, {3, 4},
+ {2, 5}, {3, 5},
+ });
+
+ draw_image(right, 0.670820f,
+ 4, 0, 4 * size,
+ -2, 5, 4 * size - 2,
+ {
+ {2, 0}, {3, 0},
+ {0, 1}, {1, 1}, {2, 1}, {3, 1},
+ {0, 2}, {1, 2}, {2, 2}, {3, 2},
+ {0, 3}, {1, 3}, {2, 3}, {3, 3},
+ {0, 4}, {1, 4}, {2, 4}, {3, 4},
+ {0, 5}, {1, 5},
+ });
-#undef TARGET
result->unlock();
return result;
}
diff --git a/src/client/tile.cpp b/src/client/tile.cpp
index 58908a08c..fd8145f22 100644
--- a/src/client/tile.cpp
+++ b/src/client/tile.cpp
@@ -802,8 +802,8 @@ static video::IImage *createInventoryCubeImage(
// With such parameters, the cube fits exactly, touching each image line
// from `0` to `cube_size - 1`. (Note that division is exact here).
- u32 cube_size = 4 * size + size / 2;
- u32 offset = size / 4;
+ u32 cube_size = 9 * size;
+ u32 offset = size / 2;
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
@@ -834,74 +834,91 @@ static video::IImage *createInventoryCubeImage(
u32 j;
#define TARGET(u,v) target[(v) * cube_size + (u) + offset]
- /* Draw top image.
- *
- * Left edge spans lines `0` to `size - 1`, and whole image spans
- * lines from `0` to `2 * size - 2` inclusive.
- */
+ // Draw top image
source = lock_image(top);
for (int v = 0; v < size; v++) {
for (int u = 0; u < size; u++) {
video::SColor pixel(*source);
- TARGET(2 * u + 2 * (size - 1 - v) + 0, u + v) = pixel.color;
- TARGET(2 * u + 2 * (size - 1 - v) + 1, u + v) = pixel.color;
- TARGET(2 * u + 2 * (size - 1 - v) + 2, u + v) = pixel.color;
- TARGET(2 * u + 2 * (size - 1 - v) + 3, u + v) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 2, 2 * u + 2 * v + 0) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 3, 2 * u + 2 * v + 0) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 4, 2 * u + 2 * v + 0) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 5, 2 * u + 2 * v + 0) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 0, 2 * u + 2 * v + 1) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 1, 2 * u + 2 * v + 1) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 2, 2 * u + 2 * v + 1) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 3, 2 * u + 2 * v + 1) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 4, 2 * u + 2 * v + 1) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 5, 2 * u + 2 * v + 1) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 6, 2 * u + 2 * v + 1) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 7, 2 * u + 2 * v + 1) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 2, 2 * u + 2 * v + 2) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 3, 2 * u + 2 * v + 2) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 4, 2 * u + 2 * v + 2) = pixel.color;
+ TARGET(4 * u + 4 * (size - 1 - v) + 5, 2 * u + 2 * v + 2) = pixel.color;
source++;
}
}
free_image(top);
- /* Draw left image.
- *
- * Line height on TARGET is alternating between 2 and 3 pixels,
- * leading to `2.5 * size` resulting height—*exactly*. Plus starting
- * offset of `size`, plus skew (`0` to `size - 1`), so it touches scan
- * lines from `size` to `4.5 * size - 2` *exactly*.
- */
+ // Draw left image
source = lock_image(left);
- j = size;
for (int v = 0; v < size; v++) {
- bool flag = v % 2;
for (int u = 0; u < size; u++) {
video::SColor pixel(*source);
applyShadeFactor(pixel, 0.836660f);
- TARGET(2 * u + 0, j + u + 0) = pixel.color;
- TARGET(2 * u + 1, j + u + 0) = pixel.color;
- TARGET(2 * u + 0, j + u + 1) = pixel.color;
- TARGET(2 * u + 1, j + u + 1) = pixel.color;
- if (flag) {
- TARGET(2 * u + 0, j + u + 2) = pixel.color;
- TARGET(2 * u + 1, j + u + 2) = pixel.color;
- }
+ TARGET(4 * u + 0, 2 * size + 5 * v + 2 * u + 0) = pixel.color;
+ TARGET(4 * u + 1, 2 * size + 5 * v + 2 * u + 0) = pixel.color;
+ TARGET(4 * u + 2, 2 * size + 5 * v + 2 * u + 1) = pixel.color;
+ TARGET(4 * u + 3, 2 * size + 5 * v + 2 * u + 1) = pixel.color;
+ TARGET(4 * u + 0, 2 * size + 5 * v + 2 * u + 1) = pixel.color;
+ TARGET(4 * u + 1, 2 * size + 5 * v + 2 * u + 1) = pixel.color;
+ TARGET(4 * u + 2, 2 * size + 5 * v + 2 * u + 2) = pixel.color;
+ TARGET(4 * u + 3, 2 * size + 5 * v + 2 * u + 2) = pixel.color;
+ TARGET(4 * u + 0, 2 * size + 5 * v + 2 * u + 2) = pixel.color;
+ TARGET(4 * u + 1, 2 * size + 5 * v + 2 * u + 2) = pixel.color;
+ TARGET(4 * u + 2, 2 * size + 5 * v + 2 * u + 3) = pixel.color;
+ TARGET(4 * u + 3, 2 * size + 5 * v + 2 * u + 3) = pixel.color;
+ TARGET(4 * u + 0, 2 * size + 5 * v + 2 * u + 3) = pixel.color;
+ TARGET(4 * u + 1, 2 * size + 5 * v + 2 * u + 3) = pixel.color;
+ TARGET(4 * u + 2, 2 * size + 5 * v + 2 * u + 4) = pixel.color;
+ TARGET(4 * u + 3, 2 * size + 5 * v + 2 * u + 4) = pixel.color;
+ TARGET(4 * u + 0, 2 * size + 5 * v + 2 * u + 4) = pixel.color;
+ TARGET(4 * u + 1, 2 * size + 5 * v + 2 * u + 4) = pixel.color;
+ TARGET(4 * u + 2, 2 * size + 5 * v + 2 * u + 5) = pixel.color;
+ TARGET(4 * u + 3, 2 * size + 5 * v + 2 * u + 5) = pixel.color;
source++;
}
- j += flag ? 3 : 2;
}
free_image(left);
- /* Draw right image.
- *
- * Works the same way as for left image, touching the same lines.
- */
+ // Draw right image
source = lock_image(right);
- j = size;
for (int v = 0; v < size; v++) {
- bool flag = v % 2;
for (int u = 0; u < size; u++) {
video::SColor pixel(*source);
applyShadeFactor(pixel, 0.670820f);
- TARGET(2 * u + 2 * size + 0, j + size - u - 1) = pixel.color;
- TARGET(2 * u + 2 * size + 1, j + size - u - 1) = pixel.color;
- TARGET(2 * u + 2 * size + 0, j + size - u + 0) = pixel.color;
- TARGET(2 * u + 2 * size + 1, j + size - u + 0) = pixel.color;
- if (flag) {
- TARGET(2 * u + 2 * size + 0, j + size - u + 1) = pixel.color;
- TARGET(2 * u + 2 * size + 1, j + size - u + 1) = pixel.color;
- }
+ TARGET(4 * u + 4 * size + 0, 4 * size + 5 * v - 2 * u - 1) = pixel.color;
+ TARGET(4 * u + 4 * size + 1, 4 * size + 5 * v - 2 * u - 1) = pixel.color;
+ TARGET(4 * u + 4 * size + 2, 4 * size + 5 * v - 2 * u - 2) = pixel.color;
+ TARGET(4 * u + 4 * size + 3, 4 * size + 5 * v - 2 * u - 2) = pixel.color;
+ TARGET(4 * u + 4 * size + 0, 4 * size + 5 * v - 2 * u + 0) = pixel.color;
+ TARGET(4 * u + 4 * size + 1, 4 * size + 5 * v - 2 * u + 0) = pixel.color;
+ TARGET(4 * u + 4 * size + 2, 4 * size + 5 * v - 2 * u - 1) = pixel.color;
+ TARGET(4 * u + 4 * size + 3, 4 * size + 5 * v - 2 * u - 1) = pixel.color;
+ TARGET(4 * u + 4 * size + 0, 4 * size + 5 * v - 2 * u + 1) = pixel.color;
+ TARGET(4 * u + 4 * size + 1, 4 * size + 5 * v - 2 * u + 1) = pixel.color;
+ TARGET(4 * u + 4 * size + 2, 4 * size + 5 * v - 2 * u + 0) = pixel.color;
+ TARGET(4 * u + 4 * size + 3, 4 * size + 5 * v - 2 * u + 0) = pixel.color;
+ TARGET(4 * u + 4 * size + 0, 4 * size + 5 * v - 2 * u + 2) = pixel.color;
+ TARGET(4 * u + 4 * size + 1, 4 * size + 5 * v - 2 * u + 2) = pixel.color;
+ TARGET(4 * u + 4 * size + 2, 4 * size + 5 * v - 2 * u + 1) = pixel.color;
+ TARGET(4 * u + 4 * size + 3, 4 * size + 5 * v - 2 * u + 1) = pixel.color;
+ TARGET(4 * u + 4 * size + 0, 4 * size + 5 * v - 2 * u + 3) = pixel.color;
+ TARGET(4 * u + 4 * size + 1, 4 * size + 5 * v - 2 * u + 3) = pixel.color;
+ TARGET(4 * u + 4 * size + 2, 4 * size + 5 * v - 2 * u + 2) = pixel.color;
+ TARGET(4 * u + 4 * size + 3, 4 * size + 5 * v - 2 * u + 2) = pixel.color;
source++;
}
- j += flag ? 3 : 2;
}
free_image(right);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment