Generalize processing of air and ignore nodes

This commit is contained in:
Rogier 2014-05-22 18:57:08 +02:00
parent f832530bf8
commit 60b39e7d4b
4 changed files with 54 additions and 39 deletions

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -217,13 +217,12 @@ private:
int m_pictHeight;
std::list<BlockPos> 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<std::string> m_unknownNodes;
std::vector<DrawObject> m_drawObjects;
int m_blockAirId;
int m_blockIgnoreId;
}; /* ----- end of class TileGenerator ----- */
#endif /* end of include guard: TILEGENERATOR_H_JJNUCARH */

View File

@ -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"