improve texture atlas generation

This commit is contained in:
darkrose 2013-12-09 20:00:49 +10:00
parent 13a48277d0
commit d46e855f90
1 changed files with 37 additions and 5 deletions

View File

@ -386,6 +386,9 @@ void TextureSource::buildMainAtlas()
// Create an image of the right size
core::dimension2d<u32> atlas_dim(2048,2048);
core::dimension2d<u32> max_dim = driver->getMaxTextureSize();
atlas_dim.Width = MYMIN(atlas_dim.Width, max_dim.Width);
atlas_dim.Height = MYMIN(atlas_dim.Height, max_dim.Height);
video::IImage *atlas_img =
driver->createImage(video::ECF_A8R8G8B8, atlas_dim);
//assert(atlas_img);
@ -446,6 +449,7 @@ void TextureSource::buildMainAtlas()
*/
core::position2d<s32> pos_in_atlas(0,0);
pos_in_atlas.X = column_padding;
pos_in_atlas.Y = padding;
for(core::map<std::string, bool>::Iterator
@ -477,7 +481,7 @@ void TextureSource::buildMainAtlas()
core::dimension2d<u32> dim = img2->getDimension();
// Don't add to atlas if image is large
core::dimension2d<u32> max_size_in_atlas(32,32);
core::dimension2d<u32> max_size_in_atlas(64,64);
if(dim.Width > max_size_in_atlas.Width
|| dim.Height > max_size_in_atlas.Height)
{
@ -489,14 +493,14 @@ void TextureSource::buildMainAtlas()
// 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 - 256 - padding){
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;
pos_in_atlas.X += column_width + column_padding*2;
}
infostream<<"TextureSource::buildMainAtlas(): Adding \""<<name
@ -509,13 +513,18 @@ void TextureSource::buildMainAtlas()
for(u32 j=0; j<xwise_tiling; j++)
{
// Copy the copy to the atlas
img2->copyToWithAlpha(atlas_img,
//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),
video::SColor(255,255,255,255),
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++)
@ -538,6 +547,29 @@ void TextureSource::buildMainAtlas()
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(pos_in_atlas.Y, MYMIN(pos_in_atlas.Y + (s32)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();
/*