mirror of
https://github.com/minetest/minetestmapper.git
synced 2025-07-01 16:10:23 +02:00
Add alpha transparency ability for blocks
This commit is contained in:
@ -54,9 +54,14 @@ static inline uint16_t readU16(const unsigned char *data)
|
||||
return data[0] << 8 | data[1];
|
||||
}
|
||||
|
||||
static inline int rgb2int(uint8_t r, uint8_t g, uint8_t b)
|
||||
static inline int rgb2int(uint8_t r, uint8_t g, uint8_t b, uint8_t a=0xFF)
|
||||
{
|
||||
return (r << 16) + (g << 8) + b;
|
||||
return (a << 24) + (r << 16) + (g << 8) + b;
|
||||
}
|
||||
|
||||
static inline int color2int(Color c)
|
||||
{
|
||||
return rgb2int(c.r, c.g, c.b, c.a);
|
||||
}
|
||||
|
||||
static inline int readBlockContent(const unsigned char *mapData, int version, int datapos)
|
||||
@ -93,6 +98,19 @@ static inline int colorSafeBounds(int color)
|
||||
}
|
||||
}
|
||||
|
||||
static inline Color mixColors(Color a, Color b)
|
||||
{
|
||||
Color result;
|
||||
double a1 = a.a / 255.0;
|
||||
double a2 = b.a / 255.0;
|
||||
|
||||
result.r = (int) (a1 * a.r + a2 * (1 - a1) * b.r);
|
||||
result.g = (int) (a1 * a.g + a2 * (1 - a1) * b.g);
|
||||
result.b = (int) (a1 * a.b + a2 * (1 - a1) * b.b);
|
||||
result.a = (int) (255 * (a1 + a2 * (1 - a1)));
|
||||
return result;
|
||||
}
|
||||
|
||||
TileGenerator::TileGenerator():
|
||||
m_bgColor(255, 255, 255),
|
||||
m_scaleColor(0, 0, 0),
|
||||
@ -101,6 +119,7 @@ TileGenerator::TileGenerator():
|
||||
m_drawOrigin(false),
|
||||
m_drawPlayers(false),
|
||||
m_drawScale(false),
|
||||
m_drawAlpha(false),
|
||||
m_shading(true),
|
||||
m_border(0),
|
||||
m_backend("sqlite3"),
|
||||
@ -178,6 +197,11 @@ void TileGenerator::setDrawScale(bool drawScale)
|
||||
}
|
||||
}
|
||||
|
||||
void TileGenerator::setDrawAlpha(bool drawAlpha)
|
||||
{
|
||||
m_drawAlpha = drawAlpha;
|
||||
}
|
||||
|
||||
void TileGenerator::setShading(bool shading)
|
||||
{
|
||||
m_shading = shading;
|
||||
@ -268,7 +292,7 @@ void TileGenerator::parseColorsStream(std::istream &in)
|
||||
{
|
||||
while (in.good()) {
|
||||
string name;
|
||||
Color color;
|
||||
ColorEntry color;
|
||||
in >> name;
|
||||
if (name[0] == '#') {
|
||||
in.ignore(65536, '\n');
|
||||
@ -277,14 +301,20 @@ void TileGenerator::parseColorsStream(std::istream &in)
|
||||
while (name == "\n" && in.good()) {
|
||||
in >> name;
|
||||
}
|
||||
int r, g, b;
|
||||
int r, g, b, a, t;
|
||||
in >> r;
|
||||
in >> g;
|
||||
in >> b;
|
||||
if(in.peek() != '\n') {
|
||||
in >> a;
|
||||
if(in.peek() != '\n')
|
||||
in >> t;
|
||||
else
|
||||
t = 0;
|
||||
} else
|
||||
a = 0xFF;
|
||||
if (in.good()) {
|
||||
color.r = r;
|
||||
color.g = g;
|
||||
color.b = b;
|
||||
color = ColorEntry(r,g,b,a,t);
|
||||
m_colors[name] = color;
|
||||
}
|
||||
}
|
||||
@ -352,7 +382,7 @@ void TileGenerator::createImage()
|
||||
m_image = gdImageCreateTrueColor(m_mapWidth + m_border, m_mapHeight + m_border);
|
||||
m_blockPixelAttributes.setWidth(m_mapWidth);
|
||||
// Background
|
||||
gdImageFilledRectangle(m_image, 0, 0, m_mapWidth + m_border - 1, m_mapHeight + m_border -1, rgb2int(m_bgColor.r, m_bgColor.g, m_bgColor.b));
|
||||
gdImageFilledRectangle(m_image, 0, 0, m_mapWidth + m_border - 1, m_mapHeight + m_border -1, color2int(m_bgColor));
|
||||
}
|
||||
|
||||
std::map<int, TileGenerator::BlockList> TileGenerator::getBlocksOnZ(int zPos)
|
||||
@ -496,6 +526,8 @@ inline void TileGenerator::renderMapBlock(const unsigned_string &mapBlock, const
|
||||
const unsigned char *mapData = mapBlock.c_str();
|
||||
int minY = (pos.y * 16 > m_yMin) ? 0 : m_yMin - pos.y * 16;
|
||||
int maxY = (pos.y * 16 < m_yMax) ? 15 : m_yMax - pos.y * 16;
|
||||
Color col;
|
||||
uint8_t th;
|
||||
for (int z = 0; z < 16; ++z) {
|
||||
int imageY = getImageY(zBegin + 15 - z);
|
||||
for (int x = 0; x < 16; ++x) {
|
||||
@ -503,6 +535,10 @@ inline void TileGenerator::renderMapBlock(const unsigned_string &mapBlock, const
|
||||
continue;
|
||||
}
|
||||
int imageX = getImageX(xBegin + x);
|
||||
if(m_drawAlpha) {
|
||||
col = Color(0,0,0,0);
|
||||
th = 0;
|
||||
}
|
||||
|
||||
for (int y = maxY; y >= minY; --y) {
|
||||
int position = x + (y << 4) + (z << 8);
|
||||
@ -511,20 +547,33 @@ inline void TileGenerator::renderMapBlock(const unsigned_string &mapBlock, const
|
||||
continue;
|
||||
}
|
||||
std::map<int, std::string>::iterator blockName = m_nameMap.find(content);
|
||||
if (blockName != m_nameMap.end()) {
|
||||
const string &name = blockName->second;
|
||||
ColorMap::const_iterator color = m_colors.find(name);
|
||||
if (color != m_colors.end()) {
|
||||
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;
|
||||
} else {
|
||||
m_unknownNodes.insert(name);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
if (blockName == m_nameMap.end())
|
||||
continue;
|
||||
const string &name = blockName->second;
|
||||
ColorMap::const_iterator color = m_colors.find(name);
|
||||
if (color != m_colors.end()) {
|
||||
const Color c = color->second.to_color();
|
||||
if (m_drawAlpha) {
|
||||
if (col.a == 0)
|
||||
col = c;
|
||||
else
|
||||
col = mixColors(col, c);
|
||||
if(col.a == 0xFF) {
|
||||
m_image->tpixels[imageY][imageX] = color2int(col);
|
||||
m_blockPixelAttributes.attribute(15 - z, xBegin + x).thicken = th;
|
||||
} else {
|
||||
th = (th + color->second.t) / 2.0;
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
m_image->tpixels[imageY][imageX] = color2int(c);
|
||||
m_readedPixels[z] |= (1 << x);
|
||||
m_blockPixelAttributes.attribute(15 - z, xBegin + x).height = pos.y * 16 + y;
|
||||
} else {
|
||||
m_unknownNodes.insert(name);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -550,13 +599,16 @@ inline void TileGenerator::renderShading(int zPos)
|
||||
if (d > 36) {
|
||||
d = 36;
|
||||
}
|
||||
if (m_drawAlpha)
|
||||
d = d * ((0xFF - m_blockPixelAttributes.attribute(z, x).thicken) / 255.0);
|
||||
int sourceColor = m_image->tpixels[imageY][getImageX(x)] & 0xffffff;
|
||||
int r = (sourceColor & 0xff0000) >> 16;
|
||||
int g = (sourceColor & 0x00ff00) >> 8;
|
||||
int b = (sourceColor & 0x0000ff);
|
||||
uint8_t r = (sourceColor & 0xff0000) >> 16;
|
||||
uint8_t g = (sourceColor & 0x00ff00) >> 8;
|
||||
uint8_t b = (sourceColor & 0x0000ff);
|
||||
r = colorSafeBounds(r + d);
|
||||
g = colorSafeBounds(g + d);
|
||||
b = colorSafeBounds(b + d);
|
||||
|
||||
m_image->tpixels[imageY][getImageX(x)] = rgb2int(r, g, b);
|
||||
}
|
||||
}
|
||||
@ -565,7 +617,7 @@ inline void TileGenerator::renderShading(int zPos)
|
||||
|
||||
void TileGenerator::renderScale()
|
||||
{
|
||||
int color = rgb2int(m_scaleColor.r, m_scaleColor.g, m_scaleColor.b);
|
||||
int color = color2int(m_scaleColor);
|
||||
gdImageString(m_image, gdFontGetMediumBold(), 24, 0, reinterpret_cast<unsigned char *>(const_cast<char *>("X")), color);
|
||||
gdImageString(m_image, gdFontGetMediumBold(), 2, 24, reinterpret_cast<unsigned char *>(const_cast<char *>("Z")), color);
|
||||
|
||||
@ -596,12 +648,12 @@ void TileGenerator::renderOrigin()
|
||||
{
|
||||
int imageX = -m_xMin * 16 + m_border;
|
||||
int imageY = m_mapHeight - m_zMin * -16 + m_border;
|
||||
gdImageArc(m_image, imageX, imageY, 12, 12, 0, 360, rgb2int(m_originColor.r, m_originColor.g, m_originColor.b));
|
||||
gdImageArc(m_image, imageX, imageY, 12, 12, 0, 360, color2int(m_originColor));
|
||||
}
|
||||
|
||||
void TileGenerator::renderPlayers(const std::string &inputPath)
|
||||
{
|
||||
int color = rgb2int(m_playerColor.r, m_playerColor.g, m_playerColor.b);
|
||||
int color = color2int(m_playerColor);
|
||||
|
||||
PlayerAttributes players(inputPath);
|
||||
for (PlayerAttributes::Players::iterator player = players.begin(); player != players.end(); ++player) {
|
||||
|
Reference in New Issue
Block a user