From 60b39e7d4b24f39778e263e4c53740bd5eef61e4 Mon Sep 17 00:00:00 2001 From: Rogier Date: Thu, 22 May 2014 18:57:08 +0200 Subject: [PATCH] Generalize processing of air and ignore nodes --- PixelAttributes.cpp | 26 +++++++++++--------- TileGenerator.cpp | 60 +++++++++++++++++++++++++++------------------ TileGenerator.h | 5 ++-- config.h | 2 ++ 4 files changed, 54 insertions(+), 39 deletions(-) diff --git a/PixelAttributes.cpp b/PixelAttributes.cpp index f6faa8c..550140a 100644 --- a/PixelAttributes.cpp +++ b/PixelAttributes.cpp @@ -129,12 +129,14 @@ void PixelAttributes::renderShading(bool drawAlpha) d = 3; } d = d * 12 / 255; + #define pixel (m_pixelAttributes[y][x]) + //PixelAttribute &pixel = m_pixelAttributes[y][x]; if (drawAlpha) - d = d * (1 - m_pixelAttributes[y][x].t); - PixelAttribute &pixel = m_pixelAttributes[y][x]; + d = d * (1 - pixel.t); pixel.r = colorSafeBounds(pixel.r + d); pixel.g = colorSafeBounds(pixel.g + d); pixel.b = colorSafeBounds(pixel.b + d); + #undef pixel } } m_firstUnshadedY = y - yCoord2Line(0); @@ -142,7 +144,6 @@ void PixelAttributes::renderShading(bool drawAlpha) void PixelAttribute::mixUnder(const PixelAttribute &p) { - int prev_alpha = alpha(); if (!is_valid() || a == 0) { if (!is_valid() || p.a != 0) { r = p.r; @@ -154,6 +155,7 @@ void PixelAttribute::mixUnder(const PixelAttribute &p) h = p.h; } else { + int prev_alpha = alpha(); r = (a * r + p.a * (1 - a) * p.r); g = (a * g + p.a * (1 - a) * p.g); b = (a * b + p.a * (1 - a) * p.b); @@ -161,15 +163,15 @@ void PixelAttribute::mixUnder(const PixelAttribute &p) if (p.a != 1) t = (t + p.t) / 2; h = p.h; - } - if (prev_alpha >= 254 && p.alpha() < 255) { - // Darken - // Parameters make deep water look good :-) - r = r * 0.95; - g = g * 0.95; - b = b * 0.95; - if (p.a != 1) - t = (t + p.t) / 2; + if (prev_alpha >= 254 && p.alpha() < 255) { + // Darken + // Parameters make deep water look good :-) + r = r * 0.95; + g = g * 0.95; + b = b * 0.95; + if (p.a != 1) + t = (t + p.t) / 2; + } } } diff --git a/TileGenerator.cpp b/TileGenerator.cpp index 5abdaae..b263852 100644 --- a/TileGenerator.cpp +++ b/TileGenerator.cpp @@ -116,6 +116,9 @@ static inline int readBlockContent(const unsigned char *mapData, int version, in } } +static const ColorEntry nodeColorNotDrawnObject; +const ColorEntry *TileGenerator::NodeColorNotDrawn = &nodeColorNotDrawnObject; + TileGenerator::TileGenerator(): verboseCoordinates(0), verboseReadColors(0), @@ -806,7 +809,8 @@ void TileGenerator::pushPixelRows(int zPosLimit) { for (int x = m_mapXStartNodeOffset; x < worldBlockX2StoredX(m_xMax + 1) + m_mapXEndNodeOffset; x++) { int mapX = x - m_mapXStartNodeOffset; int mapY = y - m_mapYStartNodeOffset; - PixelAttribute &pixel = m_blockPixelAttributes.attribute(y, x); + #define pixel m_blockPixelAttributes.attribute(y, x) + //PixelAttribute &pixel = m_blockPixelAttributes.attribute(y, x); if (pixel.next16Empty) { x += 15; continue; @@ -817,6 +821,7 @@ void TileGenerator::pushPixelRows(int zPosLimit) { #endif if (pixel.is_valid() || pixel.color().to_uint()) m_image->tpixels[mapY2ImageY(mapY)][mapX2ImageX(mapX)] = pixel.color().to_libgd(); + #undef pixel } } int yLimit = worldBlockZ2StoredY(zPosLimit); @@ -1079,8 +1084,6 @@ void TileGenerator::processMapBlock(const DB::Block &block) } dataOffset += 4; // Skip timestamp - m_blockAirId = -1; - m_blockIgnoreId = -1; // Read mapping if (version >= 22) { dataOffset++; // mapping version @@ -1093,17 +1096,24 @@ void TileGenerator::processMapBlock(const DB::Block &block) dataOffset += 2; string name; readString(name, data, dataOffset, nameLen, length); - name = name.c_str(); // Truncate any trailing NUL bytes - if (name == "air") { - ColorMap::const_iterator color = m_colors.find(name); - if (!m_drawAir || color == m_colors.end()) - m_blockAirId = nodeId; + size_t end = name.find_first_of('\0'); + if (end != std::string::npos) + name.erase(end); + ColorMap::const_iterator color = m_colors.find(name); + if (name == "air" && !(m_drawAir && color != m_colors.end())) { + m_nodeIDColor[nodeId] = NodeColorNotDrawn; } else if (name == "ignore") { - m_blockIgnoreId = nodeId; + m_nodeIDColor[nodeId] = NodeColorNotDrawn; } else { - m_nameMap[nodeId] = name; + if (color != m_colors.end()) { + m_nodeIDColor[nodeId] = &color->second; + } + else { + m_nameMap[nodeId] = name; + m_nodeIDColor[nodeId] = NULL; + } } dataOffset += nameLen; } @@ -1219,34 +1229,36 @@ inline void TileGenerator::renderMapBlock(const ustring &mapBlock, const BlockPo if (m_readedPixels[z] & (1 << x)) { continue; } - if (m_blockDefaultColor.to_uint() && !m_blockPixelAttributes.attribute(zBegin + 15 - z,xBegin + x).color().to_uint()) { - PixelAttribute pixel = PixelAttribute(m_blockDefaultColor, NAN); - m_blockPixelAttributes.attribute(zBegin + 15 - z,xBegin + x) = pixel; + // The #define of pixel performs *significantly* *better* than the definition of PixelAttribute &pixel ... + #define pixel m_blockPixelAttributes.attribute(zBegin + 15 - z,xBegin + x) + //PixelAttribute &pixel = m_blockPixelAttributes.attribute(zBegin + 15 - z,xBegin + x); + if (m_blockDefaultColor.to_uint() && !pixel.color().to_uint()) { rowIsEmpty = false; + pixel = PixelAttribute(m_blockDefaultColor, NAN); } for (int y = maxY; y >= minY; --y) { int position = x + (y << 4) + (z << 8); int content = readBlockContent(mapData, version, position); - if (content == m_blockIgnoreId || content == m_blockAirId) { + if (m_nodeIDColor[content] == NodeColorNotDrawn) { continue; } - NodeID2NameMap::iterator blockName = m_nameMap.find(content); - if (blockName == m_nameMap.end()) - continue; - const string &name = blockName->second; - ColorMap::const_iterator color = m_colors.find(name); - if (color != m_colors.end()) { + if (m_nodeIDColor[content]) { rowIsEmpty = false; - PixelAttribute pixel = PixelAttribute(color->second, pos.y * 16 + y); - m_blockPixelAttributes.attribute(zBegin + 15 - z,xBegin + x).mixUnder(pixel); - if ((m_drawAlpha && pixel.alpha() == 0xff) || (!m_drawAlpha && pixel.alpha() != 0)) { + #define nodeColor (*m_nodeIDColor[content]) + //const ColorEntry &nodeColor = *m_nodeIDColor[content]; + pixel.mixUnder(PixelAttribute(nodeColor, pos.y * 16 + y)); + if ((m_drawAlpha && nodeColor.a == 0xff) || (!m_drawAlpha && nodeColor.a != 0)) { m_readedPixels[z] |= (1 << x); break; } + #undef nodeColor } else { - m_unknownNodes.insert(name); + NodeID2NameMap::iterator blockName = m_nameMap.find(content); + if (blockName != m_nameMap.end()) + m_unknownNodes.insert(blockName->second); } } + #undef pixel } if (!rowIsEmpty) m_blockPixelAttributes.attribute(zBegin + 15 - z,xBegin).next16Empty = false; diff --git a/TileGenerator.h b/TileGenerator.h index b7b2582..dfcfb5c 100644 --- a/TileGenerator.h +++ b/TileGenerator.h @@ -217,13 +217,12 @@ private: int m_pictHeight; std::list m_positions; NodeID2NameMap m_nameMap; + static const ColorEntry *NodeColorNotDrawn; + const ColorEntry *m_nodeIDColor[MAPBLOCK_MAXCOLORS]; ColorMap m_colors; uint16_t m_readedPixels[16]; std::set m_unknownNodes; std::vector m_drawObjects; - - int m_blockAirId; - int m_blockIgnoreId; }; /* ----- end of class TileGenerator ----- */ #endif /* end of include guard: TILEGENERATOR_H_JJNUCARH */ diff --git a/config.h b/config.h index 81d5506..2a28afc 100644 --- a/config.h +++ b/config.h @@ -17,6 +17,8 @@ #define MAPBLOCK_MIN (-2048) #define MAPBLOCK_MAX 2047 +// Max number of node name -> color mappings stored in a mapblock +#define MAPBLOCK_MAXCOLORS 65536 #ifdef USE_CMAKE_CONFIG_H #include "cmake_config.h"