mirror of
https://github.com/moparisthebest/minetest
synced 2024-11-05 17:05:05 -05:00
Improve texture atlas generation
This commit is contained in:
parent
e8e73d37fb
commit
1b078efd5f
41
src/tile.cpp
41
src/tile.cpp
@ -830,7 +830,10 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
|||||||
JMutexAutoLock lock(m_atlaspointer_cache_mutex);
|
JMutexAutoLock lock(m_atlaspointer_cache_mutex);
|
||||||
|
|
||||||
// Create an image of the right size
|
// Create an image of the right size
|
||||||
core::dimension2d<u32> atlas_dim(1024,1024);
|
core::dimension2d<u32> max_dim = driver->getMaxTextureSize();
|
||||||
|
core::dimension2d<u32> atlas_dim(2048,2048);
|
||||||
|
atlas_dim.Width = MYMIN(atlas_dim.Width, max_dim.Width);
|
||||||
|
atlas_dim.Height = MYMIN(atlas_dim.Height, max_dim.Height);
|
||||||
video::IImage *atlas_img =
|
video::IImage *atlas_img =
|
||||||
driver->createImage(video::ECF_A8R8G8B8, atlas_dim);
|
driver->createImage(video::ECF_A8R8G8B8, atlas_dim);
|
||||||
//assert(atlas_img);
|
//assert(atlas_img);
|
||||||
@ -871,16 +874,17 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
|||||||
infostream<<std::endl;
|
infostream<<std::endl;
|
||||||
|
|
||||||
// Padding to disallow texture bleeding
|
// Padding to disallow texture bleeding
|
||||||
|
// (16 needed if mipmapping is used; otherwise less will work too)
|
||||||
s32 padding = 16;
|
s32 padding = 16;
|
||||||
|
|
||||||
s32 column_width = 256;
|
|
||||||
s32 column_padding = 16;
|
s32 column_padding = 16;
|
||||||
|
s32 column_width = 256; // Space for 16 pieces of 16x16 textures
|
||||||
|
|
||||||
/*
|
/*
|
||||||
First pass: generate almost everything
|
First pass: generate almost everything
|
||||||
*/
|
*/
|
||||||
core::position2d<s32> pos_in_atlas(0,0);
|
core::position2d<s32> pos_in_atlas(0,0);
|
||||||
|
|
||||||
|
pos_in_atlas.X = column_padding;
|
||||||
pos_in_atlas.Y = padding;
|
pos_in_atlas.Y = padding;
|
||||||
|
|
||||||
for(core::map<std::string, bool>::Iterator
|
for(core::map<std::string, bool>::Iterator
|
||||||
@ -901,8 +905,8 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
|||||||
|
|
||||||
core::dimension2d<u32> dim = img2->getDimension();
|
core::dimension2d<u32> dim = img2->getDimension();
|
||||||
|
|
||||||
// Don't add to atlas if image is large
|
// Don't add to atlas if image is too 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
|
if(dim.Width > max_size_in_atlas.Width
|
||||||
|| dim.Height > max_size_in_atlas.Height)
|
|| dim.Height > max_size_in_atlas.Height)
|
||||||
{
|
{
|
||||||
@ -914,14 +918,14 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
|||||||
// Wrap columns and 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)
|
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(): "
|
errorstream<<"TextureSource::buildMainAtlas(): "
|
||||||
<<"Atlas is full, not adding more textures."
|
<<"Atlas is full, not adding more textures."
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pos_in_atlas.Y = padding;
|
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
|
/*infostream<<"TextureSource::buildMainAtlas(): Adding \""<<name
|
||||||
@ -967,6 +971,29 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
|
|||||||
atlas_img->setPixel(x,dst_y,c);
|
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 + 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();
|
img2->drop();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user