diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index af5e989..139c46f 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -117,6 +117,7 @@ void content_mapnode_init() f->setInventoryTextureCube("stone.png", "stone.png", "stone.png"); f->param_type = CPT_MINERAL; f->is_ground_content = true; + f->often_contains_mineral = true; f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 1"; setStoneLikeDiggingProperties(f->digging_properties, 1.0); if(invisible_stone) diff --git a/src/main.cpp b/src/main.cpp index be98367..df1347f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1278,6 +1278,9 @@ int main(int argc, char *argv[]) // Initial call with g_texturesource not set. init_mapnode(); + // Must be called before g_texturesource is created + // (for texture atlas making) + init_mineral(); /* Run unit tests @@ -1475,7 +1478,6 @@ int main(int argc, char *argv[]) */ init_mapnode(); // Second call with g_texturesource set - init_mineral(); /* GUI stuff diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 170500f..484fcbe 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -42,6 +42,8 @@ ContentFeatures::~ContentFeatures() #ifndef SERVER void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha) { + used_texturenames[name] = true; + if(g_texturesource) { tiles[i].texture = g_texturesource->getTexture(name); diff --git a/src/mapnode.h b/src/mapnode.h index 5db3379..61f172e 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -103,6 +103,9 @@ class NodeMetadata; struct ContentFeatures { #ifndef SERVER + // List of all block textures that have been used (value is dummy) + core::map used_texturenames; + /* 0: up 1: down @@ -151,6 +154,10 @@ struct ContentFeatures // If true, node is equivalent to air. Torches are, air is. Water is not. // Is used for example to check whether a mud block can have grass on. bool air_equivalent; + // Whether this content type often contains mineral. + // Used for texture atlas creation. + // Currently only enabled for CONTENT_STONE. + bool often_contains_mineral; // Inventory item string as which the node appears in inventory when dug. // Mineral overrides this. @@ -207,6 +214,7 @@ struct ContentFeatures liquid_type = LIQUID_NONE; wall_mounted = false; air_equivalent = false; + often_contains_mineral = false; dug_item = ""; initial_metadata = NULL; liquid_alternative_flowing = CONTENT_IGNORE; diff --git a/src/tile.cpp b/src/tile.cpp index e274d2d..366f2df 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include #include "log.h" +#include "mapnode.h" // For texture atlas making +#include "mineral.h" // For texture atlas making /* A cache from texture name to texture path @@ -507,52 +509,62 @@ void TextureSource::buildMainAtlas() } /* - A list of stuff to include in the texture atlas. - - It is a single-dimensional texture atlas due to the need to tile - textures. - - It should contain as much of the stuff shown in game as possible, - to minimize texture changes. - - It fills up quickly, so do not add anything that isn't contained - in most MapBlocks. E.g. mese isn't suitable but stone is. + Grab list of stuff to include in the texture atlas from the + main content features */ - core::array sourcelist; + core::map sourcelist; - sourcelist.push_back("stone.png"); - sourcelist.push_back("mud.png"); - sourcelist.push_back("sand.png"); - sourcelist.push_back("grass.png"); - sourcelist.push_back("grass_footsteps.png"); - sourcelist.push_back("tree.png"); - sourcelist.push_back("tree_top.png"); - sourcelist.push_back("water.png"); - sourcelist.push_back("leaves.png"); - sourcelist.push_back("glass.png"); - sourcelist.push_back("mud.png^grass_side.png"); - sourcelist.push_back("cobble.png"); - sourcelist.push_back("mossycobble.png"); - sourcelist.push_back("gravel.png"); - sourcelist.push_back("jungletree.png"); - - sourcelist.push_back("stone.png^mineral_coal.png"); - sourcelist.push_back("stone.png^mineral_iron.png"); + for(u16 j=0; j::Iterator + i = f->used_texturenames.getIterator(); + i.atEnd() == false; i++) + { + std::string name = i.getNode()->getKey(); + sourcelist[name] = true; + + if(f->often_contains_mineral){ + for(int k=1; k::Iterator + i = sourcelist.getIterator(); + i.atEnd() == false; i++) + { + std::string name = i.getNode()->getKey(); + infostream<<"\""< pos_in_atlas(0,0); - pos_in_atlas.Y += padding; + pos_in_atlas.Y = padding; - for(u32 i=0; i::Iterator + i = sourcelist.getIterator(); + i.atEnd() == false; i++) { - std::string name = sourcelist[i]; + std::string name = i.getNode()->getKey(); /*video::IImage *img = driver->createImageFromFile( getTexturePath(name.c_str()).c_str()); @@ -586,20 +598,26 @@ void TextureSource::buildMainAtlas() continue; } - // Stop making atlas if atlas is full + // Wrap columns and stop making atlas if atlas is full if(pos_in_atlas.Y + dim.Height > atlas_dim.Height) { - infostream<<"TextureSource::buildMainAtlas(): " - <<"Atlas is full, not adding more textures." - < (s32)atlas_dim.Width - 256 - padding){ + errorstream<<"TextureSource::buildMainAtlas(): " + <<"Atlas is full, not adding more textures." + < 16) // Limit to 16 (more gives no benefit) + xwise_tiling = 16; for(u32 j=0; jgetPixel(x, src_y); atlas_img->setPixel(x,dst_y,c); } @@ -668,9 +686,11 @@ void TextureSource::buildMainAtlas() /* Second pass: set texture pointer in generated AtlasPointers */ - for(u32 i=0; i::Iterator + i = sourcelist.getIterator(); + i.atEnd() == false; i++) { - std::string name = sourcelist[i]; + std::string name = i.getNode()->getKey(); if(m_name_to_id.find(name) == NULL) continue; u32 id = m_name_to_id[name]; @@ -681,8 +701,12 @@ void TextureSource::buildMainAtlas() /* Write image to file so that it can be inspected */ - /*driver->writeImageToFile(atlas_img, - getTexturePath("main_atlas.png").c_str());*/ + /*std::string atlaspath = porting::path_userdata + + DIR_DELIM + "generated_texture_atlas.png"; + infostream<<"Removing and writing texture atlas for inspection to " + <writeImageToFile(atlas_img, atlaspath.c_str());*/ } video::IImage* generate_image_from_scratch(std::string name,