-
- // Wrap columns and stop making atlas if atlas is full
- if(pos_in_atlas.Y + dim.Height > atlas_dim.Height)
- {
- if(pos_in_atlas.X > (s32)atlas_dim.Width - column_width - column_padding){
- errorstream<<"TextureSource::buildMainAtlas(): "
- <<"Atlas is full, not adding more textures."
- <<std::endl;
- break;
- }
- pos_in_atlas.Y = padding;
- pos_in_atlas.X += column_width + column_padding*2;
- }
-
- /*infostream<<"TextureSource::buildMainAtlas(): Adding \""<<name
- <<"\" to texture atlas"<<std::endl;*/
-
- // Tile it a few times in the X direction
- u16 xwise_tiling = column_width / dim.Width;
- if(xwise_tiling > 16) // Limit to 16 (more gives no benefit)
- xwise_tiling = 16;
- for(u32 j=0; j<xwise_tiling; j++)
- {
- // Copy the copy to the atlas
- /*img2->copyToWithAlpha(atlas_img,
- pos_in_atlas + v2s32(j*dim.Width,0),
- core::rect<s32>(v2s32(0,0), dim),
- video::SColor(255,255,255,255),
- NULL);*/
- img2->copyTo(atlas_img,
- pos_in_atlas + v2s32(j*dim.Width,0),
- core::rect<s32>(v2s32(0,0), dim),
- NULL);
- }
-
- // Copy the borders a few times to disallow texture bleeding
- for(u32 side=0; side<2; side++) // top and bottom
- for(s32 y0=0; y0<padding; y0++)
- for(s32 x0=0; x0<(s32)xwise_tiling*(s32)dim.Width; x0++)
- {
- s32 dst_y;
- s32 src_y;
- if(side==0)
- {
- dst_y = y0 + pos_in_atlas.Y + dim.Height;
- src_y = pos_in_atlas.Y + dim.Height - 1;
- }
- else
- {
- dst_y = -y0 + pos_in_atlas.Y-1;
- src_y = pos_in_atlas.Y;
- }
- s32 x = x0 + pos_in_atlas.X;
- video::SColor c = atlas_img->getPixel(x, src_y);
- atlas_img->setPixel(x,dst_y,c);
- }
-
- for(u32 side=0; side<2; side++) // left and right
- for(s32 x0=0; x0<column_padding; x0++)
- for(s32 y0=-padding; y0<(s32)dim.Height+padding; y0++)
- {
- s32 dst_x;
- s32 src_x;
- if(side==0)
- {
- dst_x = x0 + pos_in_atlas.X + dim.Width*xwise_tiling;
- src_x = pos_in_atlas.X + dim.Width*xwise_tiling - 1;
- }
- else
- {
- dst_x = -x0 + pos_in_atlas.X-1;
- src_x = pos_in_atlas.X;
- }
- s32 y = y0 + pos_in_atlas.Y;
- s32 src_y = MYMAX((int)pos_in_atlas.Y, MYMIN((int)pos_in_atlas.Y + (int)dim.Height - 1, y));
- s32 dst_y = y;
- video::SColor c = atlas_img->getPixel(src_x, src_y);
- atlas_img->setPixel(dst_x,dst_y,c);
- }
-
- img2->drop();
-
- /*
- Add texture to caches
- */
-
- bool reuse_old_id = false;
- u32 id = m_atlaspointer_cache.size();
- // Check old id without fetching a texture
- std::map<std::string, u32>::iterator n;
- n = m_name_to_id.find(name);
- // If it exists, we will replace the old definition
- if(n != m_name_to_id.end()){
- id = n->second;
- reuse_old_id = true;
- /*infostream<<"TextureSource::buildMainAtlas(): "
- <<"Replacing old AtlasPointer"<<std::endl;*/
- }
-
- // Create AtlasPointer
- AtlasPointer ap(id);
- ap.atlas = NULL; // Set on the second pass
- ap.pos = v2f((float)pos_in_atlas.X/(float)atlas_dim.Width,
- (float)pos_in_atlas.Y/(float)atlas_dim.Height);
- ap.size = v2f((float)dim.Width/(float)atlas_dim.Width,
- (float)dim.Width/(float)atlas_dim.Height);
- ap.tiled = xwise_tiling;
-
- // Create SourceAtlasPointer and add to containers
- SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim);
- if(reuse_old_id)
- m_atlaspointer_cache[id] = nap;
- else
- m_atlaspointer_cache.push_back(nap);
- m_name_to_id[name] = id;
-
- // Increment position
- pos_in_atlas.Y += dim.Height + padding * 2;