From 1aee3688374b78771b68a2aec4c433e5c09e4298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bend=C3=ADk?= Date: Sat, 25 Aug 2012 13:19:58 +0200 Subject: [PATCH] Implemented shading. --- CMakeLists.txt | 2 ++ PixelAttributes.cpp | 29 +++++++++++++++++++++++ PixelAttributes.h | 33 ++++++++++++++++++++++++++ TileGenerator.cpp | 56 ++++++++++++++++++++++++++++++++++++++++----- TileGenerator.h | 8 +++++-- 5 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 PixelAttributes.cpp create mode 100644 PixelAttributes.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d65a36d..d355230 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,11 +35,13 @@ include_directories( ) set(mapper_HDRS + PixelAttributes.h TileGenerator.h ) set(mapper_SRCS mapper.cpp + PixelAttributes.cpp TileGenerator.cpp ) diff --git a/PixelAttributes.cpp b/PixelAttributes.cpp new file mode 100644 index 0000000..b610619 --- /dev/null +++ b/PixelAttributes.cpp @@ -0,0 +1,29 @@ +/* + * ===================================================================== + * Version: 1.0 + * Created: 25.08.2012 10:55:27 + * Author: Miroslav Bendík + * Company: LinuxOS.sk + * ===================================================================== + */ + +#include "PixelAttributes.h" + + +PixelAttributes::PixelAttributes() +{ + m_blockPixelAttributes.resize(18); // 16px + 2px gradient calculation +} + +void PixelAttributes::setWidth(int width) +{ + for (size_t i = 0; i < 18; ++i) { + m_blockPixelAttributes[i].resize(width + 2); // Width + 1 px gradient calculation on both sides + } +} + +void PixelAttributes::scroll() +{ + m_blockPixelAttributes[17] = m_blockPixelAttributes[1]; +} + diff --git a/PixelAttributes.h b/PixelAttributes.h new file mode 100644 index 0000000..2029450 --- /dev/null +++ b/PixelAttributes.h @@ -0,0 +1,33 @@ +/* + * ===================================================================== + * Version: 1.0 + * Created: 25.08.2012 10:55:29 + * Author: Miroslav Bendík + * Company: LinuxOS.sk + * ===================================================================== + */ + +#ifndef PIXELATTRIBUTES_H_ADZ35GYF +#define PIXELATTRIBUTES_H_ADZ35GYF + +#include + +struct PixelAttribute { + PixelAttribute(): height(0) {}; + int height; +}; + +class PixelAttributes +{ +public: + PixelAttributes(); + void setWidth(int width); + void scroll(); + inline PixelAttribute &attribute(int z, int x) { return m_blockPixelAttributes[z + 1][x + 1]; }; + +private: + std::vector > m_blockPixelAttributes; +}; + +#endif /* end of include guard: PIXELATTRIBUTES_H_ADZ35GYF */ + diff --git a/TileGenerator.cpp b/TileGenerator.cpp index e731283..827b9fc 100644 --- a/TileGenerator.cpp +++ b/TileGenerator.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "TileGenerator.h" @@ -101,6 +100,19 @@ static inline std::string zlibDecompress(const char *data, std::size_t size, std return buffer; } +static inline int colorSafeBounds(int color) +{ + if (color > 255) { + return 255; + } + else if (color < 0) { + return 0; + } + else { + return color; + } +} + TileGenerator::TileGenerator(): m_bgColor(255, 255, 255), m_scaleColor(0, 0, 0), @@ -288,11 +300,12 @@ inline BlockPos TileGenerator::decodeBlockPos(sqlite3_int64 blockId) const void TileGenerator::createImage() { - m_imgWidth = (m_xMax - m_xMin + 1) * 16; - m_imgHeight = (m_zMax - m_zMin + 1) * 16; - m_image = gdImageCreateTrueColor(m_imgWidth, m_imgHeight); + m_mapWidth = (m_xMax - m_xMin + 1) * 16; + m_mapHeight = (m_zMax - m_zMin + 1) * 16; + m_image = gdImageCreateTrueColor(m_mapWidth, m_mapHeight); + m_blockPixelAttributes.setWidth(m_mapWidth); // Background - gdImageFilledRectangle(m_image, 0, 0, m_imgWidth - 1, m_imgHeight -1, rgb2int(m_bgColor.r, m_bgColor.g, m_bgColor.b)); + gdImageFilledRectangle(m_image, 0, 0, m_mapWidth - 1, m_mapHeight -1, rgb2int(m_bgColor.r, m_bgColor.g, m_bgColor.b)); } void TileGenerator::renderMap() @@ -414,6 +427,7 @@ void TileGenerator::renderMap() } } } + renderShading(zPos); } } @@ -423,7 +437,7 @@ inline void TileGenerator::renderMapBlock(const std::string &mapBlock, const Blo int zBegin = (m_zMax - pos.z) * 16; const unsigned char *mapData = reinterpret_cast(mapBlock.c_str()); for (int z = 0; z < 16; ++z) { - int imageY = zBegin + 16 - z; + int imageY = zBegin + 15 - z; for (int x = 0; x < 16; ++x) { if (m_readedPixels[z] & (1 << x)) { continue; @@ -443,6 +457,7 @@ inline void TileGenerator::renderMapBlock(const std::string &mapBlock, const Blo const Color &c = color->second; m_image->tpixels[imageY][imageX] = rgb2int(c.r, c.g, c.b); m_readedPixels[z] |= (1 << x); + m_blockPixelAttributes.attribute(15 - z, xBegin + x).height = pos.y * 16 + y; } break; } @@ -451,6 +466,35 @@ inline void TileGenerator::renderMapBlock(const std::string &mapBlock, const Blo } } +inline void TileGenerator::renderShading(int zPos) +{ + int zBegin = (m_zMax - zPos) * 16; + for (int z = 1; z < 17; ++z) { + int imageY = zBegin + z; + if (imageY >= m_mapHeight) { + continue; + } + for (int x = 0; x < m_mapWidth; ++x) { + int y = m_blockPixelAttributes.attribute(z, x).height; + int y1 = m_blockPixelAttributes.attribute(z, x - 1).height; + int y2 = m_blockPixelAttributes.attribute(z - 1, x).height; + int d = ((y - y1) + (y - y2)) * 12; + if (d > 36) { + d = 36; + } + int sourceColor = m_image->tpixels[imageY][x] & 0xffffff; + int r = (sourceColor & 0xff0000) >> 16; + int g = (sourceColor & 0x00ff00) >> 8; + int b = (sourceColor & 0x0000ff); + r = colorSafeBounds(r + d); + g = colorSafeBounds(g + d); + b = colorSafeBounds(b + d); + m_image->tpixels[imageY][x] = rgb2int(r, g, b); + } + } + m_blockPixelAttributes.scroll(); +} + inline std::list TileGenerator::getZValueList() const { std::list zlist; diff --git a/TileGenerator.h b/TileGenerator.h index e9bcafa..fdf7ee9 100644 --- a/TileGenerator.h +++ b/TileGenerator.h @@ -16,6 +16,7 @@ #include #include #include +#include "PixelAttributes.h" struct Color { Color(): r(255), g(255), b(255) {}; @@ -65,6 +66,7 @@ class DecompressError { class VersionError { }; + class TileGenerator { private: @@ -95,6 +97,7 @@ private: std::list getZValueList() const; std::map getBlocksOnZ(int zPos, sqlite3_stmt *statement) const; void renderMapBlock(const std::string &mapBlock, const BlockPos &pos, int version); + void renderShading(int zPos); void writeImage(const std::string &output); private: @@ -109,12 +112,13 @@ private: sqlite3 *m_db; gdImagePtr m_image; + PixelAttributes m_blockPixelAttributes; int m_xMin; int m_xMax; int m_zMin; int m_zMax; - int m_imgWidth; - int m_imgHeight; + int m_mapWidth; + int m_mapHeight; std::list > m_positions; std::map m_nameMap; ColorMap m_colors;