# Enable smooth lighting with simple ambient occlusion;
# disable for speed or for different looks.
#smooth_lighting = true
-# Enable combining mainly used textures to a bigger one for improved speed
-# disable if it causes graphics glitches.
-#enable_texture_atlas = false
# Path to texture directory. All textures are first searched from here.
#texture_path =
# Video back-end.
m_playerpos_send_timer = 0.0;
m_ignore_damage_timer = 0.0;
- // Build main texture atlas, now that the GameDef exists (that is, us)
- if(g_settings->getBool("enable_texture_atlas"))
- m_tsrc->buildMainAtlas(this);
- else
- infostream<<"Not building texture atlas."<<std::endl;
-
/*
Add local player
*/
infostream<<"- Rebuilding images and textures"<<std::endl;
m_tsrc->rebuildImagesAndTextures();
- // Update texture atlas
- infostream<<"- Updating texture atlas"<<std::endl;
- if(g_settings->getBool("enable_texture_atlas"))
- m_tsrc->buildMainAtlas(this);
-
// Rebuild shaders
m_shsrc->rebuildShaders();
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
- buf->getMaterial().setTexture(0, tsrc->getTextureRaw("rat.png"));
+ buf->getMaterial().setTexture(0, tsrc->getTexture("rat.png"));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
// Initialize with a generated placeholder texture
- buf->getMaterial().setTexture(0, tsrc->getTextureRaw(""));
+ buf->getMaterial().setTexture(0, tsrc->getTexture(""));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
m_spritenode = smgr->addBillboardSceneNode(
NULL, v2f(1, 1), v3f(0,0,0), -1);
m_spritenode->setMaterialTexture(0,
- tsrc->getTextureRaw("unknown_node.png"));
+ tsrc->getTexture("unknown_node.png"));
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
texturestring = m_prop.textures[0];
texturestring += mod;
m_spritenode->setMaterialTexture(0,
- tsrc->getTextureRaw(texturestring));
+ tsrc->getTexture(texturestring));
// This allows setting per-material colors. However, until a real lighting
// system is added, the code below will have no effect. Once MineTest
if(texturestring == "")
continue; // Empty texture string means don't modify that material
texturestring += mod;
- video::ITexture* texture = tsrc->getTextureRaw(texturestring);
+ video::ITexture* texture = tsrc->getTexture(texturestring);
if(!texture)
{
errorstream<<"GenericCAO::updateTextures(): Could not load texture "<<texturestring<<std::endl;
if(m_prop.textures.size() > i)
texturestring = m_prop.textures[i];
texturestring += mod;
- AtlasPointer ap = tsrc->getTexture(texturestring);
- // Get the tile texture and atlas transformation
- video::ITexture* atlas = ap.atlas;
- v2f pos = ap.pos;
- v2f size = ap.size;
// Set material flags and texture
video::SMaterial& material = m_meshnode->getMaterial(i);
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_BILINEAR_FILTER, false);
- material.setTexture(0, atlas);
- material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
- material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
+ material.setTexture(0,
+ tsrc->getTexture(texturestring));
+ material.getTextureMatrix(0).makeIdentity();
// This allows setting per-material colors. However, until a real lighting
// system is added, the code below will have no effect. Once MineTest
tname += mod;
scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
buf->getMaterial().setTexture(0,
- tsrc->getTextureRaw(tname));
+ tsrc->getTexture(tname));
// This allows setting per-material colors. However, until a real lighting
// system is added, the code below will have no effect. Once MineTest
tname += mod;
scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
buf->getMaterial().setTexture(0,
- tsrc->getTextureRaw(tname));
+ tsrc->getTexture(tname));
// This allows setting per-material colors. However, until a real lighting
// system is added, the code below will have no effect. Once MineTest
m_spritenode = smgr->addBillboardSceneNode(
NULL, v2f(1,1), pos, -1);
m_spritenode->setMaterialTexture(0,
- env->getGameDef()->tsrc()->getTextureRaw("smoke_puff.png"));
+ env->getGameDef()->tsrc()->getTexture("smoke_puff.png"));
m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
//m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
video::S3DVertex(min.X,min.Y,min.Z, 0,0,-1, c, txc[20],txc[23]),
};
- v2f t;
for(int i = 0; i < tilecount; i++)
{
switch (tiles[i].rotation)
vertices[i*4+x].TCoords.rotateBy(270,irr::core::vector2df(0, 0));
break;
case 4: //FXR90
- for (int x = 0; x < 4; x++)
+ for (int x = 0; x < 4; x++){
+ vertices[i*4+x].TCoords.X = 1.0 - vertices[i*4+x].TCoords.X;
vertices[i*4+x].TCoords.rotateBy(90,irr::core::vector2df(0, 0));
-
- tiles[i].texture.pos.Y += tiles[i].texture.size.Y;
- tiles[i].texture.size.Y *= -1;
+ }
break;
case 5: //FXR270
- for (int x = 0; x < 4; x++)
+ for (int x = 0; x < 4; x++){
+ vertices[i*4+x].TCoords.X = 1.0 - vertices[i*4+x].TCoords.X;
vertices[i*4+x].TCoords.rotateBy(270,irr::core::vector2df(0, 0));
- t=vertices[i*4].TCoords;
- tiles[i].texture.pos.Y += tiles[i].texture.size.Y;
- tiles[i].texture.size.Y *= -1;
+ }
break;
case 6: //FYR90
- for (int x = 0; x < 4; x++)
+ for (int x = 0; x < 4; x++){
+ vertices[i*4+x].TCoords.Y = 1.0 - vertices[i*4+x].TCoords.Y;
vertices[i*4+x].TCoords.rotateBy(90,irr::core::vector2df(0, 0));
- tiles[i].texture.pos.X += tiles[i].texture.size.X;
- tiles[i].texture.size.X *= -1;
+ }
break;
case 7: //FYR270
- for (int x = 0; x < 4; x++)
+ for (int x = 0; x < 4; x++){
+ vertices[i*4+x].TCoords.Y = 1.0 - vertices[i*4+x].TCoords.Y;
vertices[i*4+x].TCoords.rotateBy(270,irr::core::vector2df(0, 0));
- tiles[i].texture.pos.X += tiles[i].texture.size.X;
- tiles[i].texture.size.X *= -1;
+ }
break;
case 8: //FX
- tiles[i].texture.pos.Y += tiles[i].texture.size.Y;
- tiles[i].texture.size.Y *= -1;
+ for (int x = 0; x < 4; x++){
+ vertices[i*4+x].TCoords.X = 1.0 - vertices[i*4+x].TCoords.X;
+ }
break;
case 9: //FY
- tiles[i].texture.pos.X += tiles[i].texture.size.X;
- tiles[i].texture.size.X *= -1;
+ for (int x = 0; x < 4; x++){
+ vertices[i*4+x].TCoords.Y = 1.0 - vertices[i*4+x].TCoords.Y;
+ }
break;
default:
break;
}
}
- for(s32 j=0; j<24; j++)
- {
- int tileindex = MYMIN(j/4, tilecount-1);
- vertices[j].TCoords *= tiles[tileindex].texture.size;
- vertices[j].TCoords += tiles[tileindex].texture.pos;
- }
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
for(s32 j=0; j<24; j+=4)
*/
TileSpec tile_liquid = f.special_tiles[0];
TileSpec tile_liquid_bfculled = getNodeTile(n, p, v3s16(0,0,0), data);
- AtlasPointer &pa_liquid = tile_liquid.texture;
bool top_is_same_liquid = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2,0,BS/2,0,0,0, c,
- pa_liquid.x0(), pa_liquid.y1()),
- video::S3DVertex(BS/2,0,BS/2,0,0,0, c,
- pa_liquid.x1(), pa_liquid.y1()),
- video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x1(), pa_liquid.y0()),
- video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x0(), pa_liquid.y0()),
+ video::S3DVertex(-BS/2,0,BS/2,0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,0,BS/2,0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),
};
/*
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x0(), pa_liquid.y1()),
- video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x1(), pa_liquid.y1()),
- video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c,
- pa_liquid.x1(), pa_liquid.y0()),
- video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c,
- pa_liquid.x0(), pa_liquid.y0()),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,0),
};
v3f offset(p.X*BS, p.Y*BS + (-0.5+node_liquid_level)*BS, p.Z*BS);
*/
TileSpec tile_liquid = f.special_tiles[0];
TileSpec tile_liquid_bfculled = f.special_tiles[1];
- AtlasPointer &pa_liquid = tile_liquid.texture;
bool top_is_same_liquid = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x0(), pa_liquid.y1()),
- video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x1(), pa_liquid.y1()),
- video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x1(), pa_liquid.y0()),
- video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x0(), pa_liquid.y0()),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),
};
/*
{
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x0(), pa_liquid.y1()),
- video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
- pa_liquid.x1(), pa_liquid.y1()),
- video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c,
- pa_liquid.x1(), pa_liquid.y0()),
- video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c,
- pa_liquid.x0(), pa_liquid.y0()),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,0),
};
// To get backface culling right, the vertices need to go
case NDT_GLASSLIKE:
{
TileSpec tile = getNodeTile(n, p, v3s16(0,0,0), data);
- AtlasPointer ap = tile.texture;
u16 l = getInteriorLight(n, 1, data);
video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
// The face at Z+
video::S3DVertex vertices[4] = {
- video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c,
- ap.x0(), ap.y1()),
- video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c,
- ap.x1(), ap.y1()),
- video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c,
- ap.x1(), ap.y0()),
- video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c,
- ap.x0(), ap.y0()),
+ video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c, 0,0),
};
// Rotations in the g_6dirs format
{
TileSpec tile_leaves = getNodeTile(n, p,
v3s16(0,0,0), data);
- AtlasPointer pa_leaves = tile_leaves.texture;
u16 l = getInteriorLight(n, 1, data);
video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
- AtlasPointer ap = tile.texture;
-
u16 l = getInteriorLight(n, 1, data);
video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
// Wall at X+ of node
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
- ap.x0(), ap.y1()),
- video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
- ap.x1(), ap.y1()),
- video::S3DVertex(BS/2,BS/2,0, 0,0,0, c,
- ap.x1(), ap.y0()),
- video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c,
- ap.x0(), ap.y0()),
+ video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
};
for(s32 i=0; i<4; i++)
TileSpec tile = getNodeTileN(n, p, 0, data);
tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
- AtlasPointer ap = tile.texture;
u16 l = getInteriorLight(n, 0, data);
video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
// Wall at X+ of node
video::S3DVertex vertices[4] =
{
- video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c,
- ap.x0(), ap.y0()),
- video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c,
- ap.x1(), ap.y0()),
- video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c,
- ap.x1(), ap.y1()),
- video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c,
- ap.x0(), ap.y1()),
+ video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c, 0,0),
+ video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c, 0,1),
};
v3s16 dir = n.getWallMountedDir(nodedef);
{
TileSpec tile = getNodeTileN(n, p, 0, data);
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
- AtlasPointer ap = tile.texture;
u16 l = getInteriorLight(n, 1, data);
video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
{
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2*f.visual_scale,-BS/2,0, 0,0,0, c,
- ap.x0(), ap.y1()),
- video::S3DVertex( BS/2*f.visual_scale,-BS/2,0, 0,0,0, c,
- ap.x1(), ap.y1()),
+ video::S3DVertex(-BS/2*f.visual_scale,-BS/2,0, 0,0,0, c, 0,1),
+ video::S3DVertex( BS/2*f.visual_scale,-BS/2,0, 0,0,0, c, 1,1),
video::S3DVertex( BS/2*f.visual_scale,
- -BS/2 + f.visual_scale*BS,0, 0,0,0, c,
- ap.x1(), ap.y0()),
+ -BS/2 + f.visual_scale*BS,0, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2*f.visual_scale,
- -BS/2 + f.visual_scale*BS,0, 0,0,0, c,
- ap.x0(), ap.y0()),
+ -BS/2 + f.visual_scale*BS,0, 0,0,0, c, 0,0),
};
if(j == 0)
// A hack to put wood the right way around in the posts
ITextureSource *tsrc = data->m_gamedef->tsrc();
+ std::string texturestring_rot = tsrc->getTextureName(
+ tile.texture_id) + "^[transformR90";
TileSpec tile_rot = tile;
- tile_rot.texture = tsrc->getTexture(tsrc->getTextureName(
- tile.texture.id) + "^[transformR90");
-
+ tile_rot.texture = tsrc->getTexture(
+ texturestring_rot,
+ &tile_rot.texture_id);
+
u16 l = getInteriorLight(n, 1, data);
video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
tile.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY;
- AtlasPointer ap = tile.texture;
-
u16 l = getInteriorLight(n, 0, data);
video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2,-BS/2+d,-BS/2, 0,0,0, c,
- ap.x0(), ap.y1()),
- video::S3DVertex(BS/2,-BS/2+d,-BS/2, 0,0,0, c,
- ap.x1(), ap.y1()),
- video::S3DVertex(BS/2,g*BS/2+d,BS/2, 0,0,0, c,
- ap.x1(), ap.y0()),
- video::S3DVertex(-BS/2,g*BS/2+d,BS/2, 0,0,0, c,
- ap.x0(), ap.y0()),
+ video::S3DVertex(-BS/2,-BS/2+d,-BS/2, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,-BS/2+d,-BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,g*BS/2+d,BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,g*BS/2+d,BS/2, 0,0,0, c, 0,0),
};
for(s32 i=0; i<4; i++)
settings->setDefault("new_style_water", "false");
settings->setDefault("new_style_leaves", "true");
settings->setDefault("smooth_lighting", "true");
- settings->setDefault("enable_texture_atlas", "false");
settings->setDefault("texture_path", "");
settings->setDefault("shader_path", "");
settings->setDefault("video_driver", "opengl");
m_materials[1].setFlag(video::EMF_BACK_FACE_CULLING, false);
m_materials[1].setFlag(video::EMF_BILINEAR_FILTER, false);
m_materials[1].setFlag(video::EMF_FOG_ENABLE, false);
- m_materials[1].setTexture(0, client->tsrc()->getTextureRaw("treeprop.png"));
+ m_materials[1].setTexture(0, client->tsrc()->getTexture("treeprop.png"));
m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
m_materials[1].setFlag(video::EMF_FOG_ENABLE, true);
*/
int crack_animation_length = 5;
{
- video::ITexture *t = tsrc->getTextureRaw("crack_anylength.png");
+ video::ITexture *t = tsrc->getTexture("crack_anylength.png");
v2u32 size = t->getOriginalSize();
crack_animation_length = size.Y / size.X;
}
else if(event.type == CE_SPAWN_PARTICLE)
{
LocalPlayer* player = client.getEnv().getLocalPlayer();
- AtlasPointer ap =
+ video::ITexture *texture =
gamedef->tsrc()->getTexture(*(event.spawn_particle.texture));
new Particle(gamedef, smgr, player, client.getEnv(),
*event.spawn_particle.acc,
event.spawn_particle.expirationtime,
event.spawn_particle.size,
- event.spawn_particle.collisiondetection, ap);
+ event.spawn_particle.collisiondetection,
+ texture,
+ v2f(0.0, 0.0),
+ v2f(1.0, 1.0));
}
else if(event.type == CE_ADD_PARTICLESPAWNER)
{
LocalPlayer* player = client.getEnv().getLocalPlayer();
- AtlasPointer ap =
+ video::ITexture *texture =
gamedef->tsrc()->getTexture(*(event.add_particlespawner.texture));
new ParticleSpawner(gamedef, smgr, player,
event.add_particlespawner.minsize,
event.add_particlespawner.maxsize,
event.add_particlespawner.collisiondetection,
- ap,
+ texture,
event.add_particlespawner.id);
}
else if(event.type == CE_DELETE_PARTICLESPAWNER)
if(type == "image_button_exit")
spec.is_exit = true;
- video::ITexture *texture = m_gamedef->tsrc()->getTextureRaw(fimage);
+ video::ITexture *texture = m_gamedef->tsrc()->getTexture(fimage);
gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
e->setUseAlphaChannel(true);
e->setImage(texture);
{
const ImageDrawSpec &spec = m_backgrounds[i];
video::ITexture *texture =
- m_gamedef->tsrc()->getTextureRaw(spec.name);
+ m_gamedef->tsrc()->getTexture(spec.name);
// Image size on screen
core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
// Image rectangle on screen
{
const ImageDrawSpec &spec = m_images[i];
video::ITexture *texture =
- m_gamedef->tsrc()->getTextureRaw(spec.name);
+ m_gamedef->tsrc()->getTexture(spec.name);
// Image size on screen
core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
// Image rectangle on screen
v2s32 pos(e->pos.X * screensize.X, e->pos.Y * screensize.Y);
switch (e->type) {
case HUD_ELEM_IMAGE: {
- video::ITexture *texture = tsrc->getTextureRaw(e->text);
+ video::ITexture *texture = tsrc->getTexture(e->text);
if (!texture)
continue;
const video::SColor color(255, 255, 255, 255);
const video::SColor colors[] = {color, color, color, color};
- video::ITexture *stat_texture = tsrc->getTextureRaw(texture);
+ video::ITexture *stat_texture = tsrc->getTexture(texture);
if (!stat_texture)
return;
return;
if (use_crosshair_image) {
- video::ITexture *crosshair = tsrc->getTextureRaw("crosshair.png");
+ video::ITexture *crosshair = tsrc->getTexture("crosshair.png");
v2u32 size = crosshair->getOriginalSize();
v2s32 lsize = v2s32(displaycenter.X - (size.X / 2),
displaycenter.Y - (size.Y / 2));
cc->inventory_texture = NULL;
if(def->inventory_image != "")
{
- cc->inventory_texture = tsrc->getTextureRaw(def->inventory_image);
+ cc->inventory_texture = tsrc->getTexture(def->inventory_image);
}
else if(def->type == ITEM_NODE)
{
imagename = def->inventory_image;
cc->wield_mesh = createExtrudedMesh(
- tsrc->getTextureRaw(imagename),
+ tsrc->getTexture(imagename),
driver,
def->wield_scale * v3f(40.0, 40.0, 4.0));
if(cc->wield_mesh == NULL)
if(cc->inventory_texture == NULL)
{
cc->inventory_texture =
- tsrc->getTextureRaw(f.tiledef[0].name);
+ tsrc->getTexture(f.tiledef[0].name);
}
}
else
// Position is at the center of the cube.
v3f pos = p * BS;
+ float x0 = 0.0;
+ float y0 = 0.0;
+ float w = 1.0;
+ float h = 1.0;
+
v3f vertex_pos[4];
v3s16 vertex_dirs[4];
getNodeVertexDirs(dir, vertex_dirs);
vertex_dirs[3] = vertex_dirs[2];
vertex_dirs[2] = vertex_dirs[1];
vertex_dirs[1] = t;
- tile.texture.pos.Y += tile.texture.size.Y;
- tile.texture.size.Y *= -1;
+ y0 += h;
+ h *= -1;
break;
case 5: //FXR270
t = vertex_dirs[0];
vertex_dirs[1] = vertex_dirs[2];
vertex_dirs[2] = vertex_dirs[3];
vertex_dirs[3] = t;
- tile.texture.pos.Y += tile.texture.size.Y;
- tile.texture.size.Y *= -1;
+ y0 += h;
+ h *= -1;
break;
case 6: //FYR90
t = vertex_dirs[0];
vertex_dirs[3] = vertex_dirs[2];
vertex_dirs[2] = vertex_dirs[1];
vertex_dirs[1] = t;
- tile.texture.pos.X += tile.texture.size.X;
- tile.texture.size.X *= -1;
+ x0 += w;
+ w *= -1;
break;
case 7: //FYR270
t = vertex_dirs[0];
vertex_dirs[1] = vertex_dirs[2];
vertex_dirs[2] = vertex_dirs[3];
vertex_dirs[3] = t;
- tile.texture.pos.X += tile.texture.size.X;
- tile.texture.size.X *= -1;
+ x0 += w;
+ w *= -1;
break;
case 8: //FX
- tile.texture.pos.Y += tile.texture.size.Y;
- tile.texture.size.Y *= -1;
+ y0 += h;
+ h *= -1;
break;
case 9: //FY
- tile.texture.pos.X += tile.texture.size.X;
- tile.texture.size.X *= -1;
+ x0 += w;
+ w *= -1;
break;
default:
break;
u8 alpha = tile.alpha;
- float x0 = tile.texture.pos.X;
- float y0 = tile.texture.pos.Y;
- float w = tile.texture.size.X;
- float h = tile.texture.size.Y;
-
face.vertices[0] = video::S3DVertex(vertex_pos[0], normal,
MapBlock_LightColor(alpha, li0, light_source),
core::vector2d<f32>(x0+w*abs_scale, y0+h));
if(p == data->m_crack_pos_relative)
{
spec.material_flags |= MATERIAL_FLAG_CRACK;
- spec.texture = data->m_gamedef->tsrc()->getTextureRawAP(spec.texture);
- }
- // If animated, replace tile texture with one without texture atlas
- if(spec.material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
- {
- spec.texture = data->m_gamedef->tsrc()->getTextureRawAP(spec.texture);
}
return spec;
}
u16 tile_index=facedir*16 + dir_i;
TileSpec spec = getNodeTileN(mn, p, dir_to_tile[tile_index], data);
spec.rotation=dir_to_tile[tile_index + 1];
- spec.texture = data->m_gamedef->tsrc()->getTexture(spec.texture.id);
+ spec.texture = data->m_gamedef->tsrc()->getTexture(spec.texture_id);
return spec;
}
continuous_tiles_count++;
- // This is set to true if the texture doesn't allow more tiling
- bool end_of_texture = false;
- /*
- If there is no texture, it can be tiled infinitely.
- If tiled==0, it means the texture can be tiled infinitely.
- Otherwise check tiled agains continuous_tiles_count.
- */
- if(tile.texture.atlas != NULL && tile.texture.tiled != 0)
- {
- if(tile.texture.tiled <= continuous_tiles_count)
- end_of_texture = true;
- }
-
- // Do this to disable tiling textures
- //end_of_texture = true; //DEBUG
-
- if(next_is_different || end_of_texture)
+ if(next_is_different)
{
/*
Create a face if there should be one
const u16 indices[] = {0,1,2,2,3,0};
const u16 indices_alternate[] = {0,1,3,2,3,1};
- if(f.tile.texture.atlas == NULL)
+ if(f.tile.texture == NULL)
continue;
const u16 *indices_p = indices;
if(p.tile.material_flags & MATERIAL_FLAG_CRACK)
{
ITextureSource *tsrc = data->m_gamedef->tsrc();
- std::string crack_basename = tsrc->getTextureName(p.tile.texture.id);
+ std::string crack_basename = tsrc->getTextureName(p.tile.texture_id);
if(p.tile.material_flags & MATERIAL_FLAG_CRACK_OVERLAY)
crack_basename += "^[cracko";
else
}
// Replace tile texture with the first animation frame
std::ostringstream os(std::ios::binary);
- os<<tsrc->getTextureName(p.tile.texture.id);
+ os<<tsrc->getTextureName(p.tile.texture_id);
os<<"^[verticalframe:"<<(int)p.tile.animation_frame_count<<":0";
- p.tile.texture = tsrc->getTexture(os.str());
+ p.tile.texture = tsrc->getTexture(
+ os.str(),
+ &p.tile.texture_id);
}
// - Classic lighting (shaders handle this by themselves)
if(!enable_shaders)
//material.setFlag(video::EMF_ANTI_ALIASING, video::EAAM_SIMPLE);
material.MaterialType
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
- material.setTexture(0, p.tile.texture.atlas);
+ material.setTexture(0, p.tile.texture);
if(enable_shaders)
p.tile.applyMaterialOptionsWithShaders(material, shadermat1, shadermat2, shadermat3);
else
ITextureSource *tsrc = m_gamedef->getTextureSource();
std::ostringstream os;
os<<basename<<crack;
- AtlasPointer ap = tsrc->getTexture(os.str());
- buf->getMaterial().setTexture(0, ap.atlas);
+ buf->getMaterial().setTexture(0,
+ tsrc->getTexture(os.str()));
}
m_last_crack = crack;
// Create new texture name from original
std::ostringstream os(std::ios::binary);
- os<<tsrc->getTextureName(tile.texture.id);
+ os<<tsrc->getTextureName(tile.texture_id);
os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
// Set the texture
- AtlasPointer ap = tsrc->getTexture(os.str());
- buf->getMaterial().setTexture(0, ap.atlas);
+ buf->getMaterial().setTexture(0, tsrc->getTexture(os.str()));
}
// Day-night transition
// Tiles (fill in f->tiles[])
for(u16 j=0; j<6; j++){
// Texture
- f->tiles[j].texture = tsrc->getTexture(tiledef[j].name);
+ f->tiles[j].texture = tsrc->getTexture(
+ tiledef[j].name,
+ &f->tiles[j].texture_id);
// Alpha
f->tiles[j].alpha = f->alpha;
// Material type
if(f->tiles[j].material_flags &
MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
{
- // Get raw texture size to determine frame count by
+ // Get texture size to determine frame count by
// aspect ratio
- video::ITexture *t = tsrc->getTextureRaw(tiledef[j].name);
- v2u32 size = t->getOriginalSize();
+ v2u32 size = f->tiles[j].texture->getOriginalSize();
int frame_height = (float)size.X /
(float)tiledef[j].animation.aspect_w *
(float)tiledef[j].animation.aspect_h;
// Special tiles (fill in f->special_tiles[])
for(u16 j=0; j<CF_SPECIAL_COUNT; j++){
// Texture
- f->special_tiles[j].texture =
- tsrc->getTexture(f->tiledef_special[j].name);
+ f->special_tiles[j].texture = tsrc->getTexture(
+ f->tiledef_special[j].name,
+ &f->special_tiles[j].texture_id);
// Alpha
f->special_tiles[j].alpha = f->alpha;
// Material type
if(f->special_tiles[j].material_flags &
MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
{
- // Get raw texture size to determine frame count by
+ // Get texture size to determine frame count by
// aspect ratio
- video::ITexture *t = tsrc->getTextureRaw(f->tiledef_special[j].name);
- v2u32 size = t->getOriginalSize();
+ v2u32 size = f->special_tiles[j].texture->getOriginalSize();
int frame_height = (float)size.X /
(float)f->tiledef_special[j].animation.aspect_w *
(float)f->tiledef_special[j].animation.aspect_h;
/*
Update tile textures to latest return values of TextueSource.
- Call after updating the texture atlas of a TextureSource.
*/
virtual void updateTextures(ITextureSource *tsrc)=0;
float expirationtime,
float size,
bool collisiondetection,
- AtlasPointer ap
+ video::ITexture *texture,
+ v2f texpos,
+ v2f texsize
):
scene::ISceneNode(smgr->getRootSceneNode(), smgr)
{
m_material.setFlag(video::EMF_BILINEAR_FILTER, false);
m_material.setFlag(video::EMF_FOG_ENABLE, true);
m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
- m_material.setTexture(0, ap.atlas);
- m_ap = ap;
+ m_material.setTexture(0, texture);
+ m_texpos = texpos;
+ m_texsize = texsize;
// Particle related
void Particle::updateVertices()
{
video::SColor c(255, m_light, m_light, m_light);
+ f32 tx0 = m_texpos.X;
+ f32 tx1 = m_texpos.X + m_texsize.X;
+ f32 ty0 = m_texpos.Y;
+ f32 ty1 = m_texpos.Y + m_texsize.Y;
+
m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0,
- c, m_ap.x0(), m_ap.y1());
+ c, tx0, ty1);
m_vertices[1] = video::S3DVertex(m_size/2,-m_size/2,0, 0,0,0,
- c, m_ap.x1(), m_ap.y1());
+ c, tx1, ty1);
m_vertices[2] = video::S3DVertex(m_size/2,m_size/2,0, 0,0,0,
- c, m_ap.x1(), m_ap.y0());
+ c, tx1, ty0);
m_vertices[3] = video::S3DVertex(-m_size/2,m_size/2,0, 0,0,0,
- c ,m_ap.x0(), m_ap.y0());
+ c, tx0, ty0);
for(u16 i=0; i<4; i++)
{
{
// Texture
u8 texid = myrand_range(0,5);
- AtlasPointer ap = tiles[texid].texture;
- float size = rand()%64/512.;
- float visual_size = BS*size;
- float texsize = size*2;
+ video::ITexture *texture = tiles[texid].texture;
- float x1 = ap.x1();
- float y1 = ap.y1();
+ // Only use first frame of animated texture
+ f32 ymax = 1;
+ if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
+ ymax /= tiles[texid].animation_frame_count;
- ap.size.X = (ap.x1() - ap.x0()) * texsize;
- ap.size.Y = (ap.x1() - ap.x0()) * texsize;
-
- ap.pos.X = ap.x0() + (x1 - ap.x0()) * ((rand()%64)/64.-texsize);
- ap.pos.Y = ap.y0() + (y1 - ap.y0()) * ((rand()%64)/64.-texsize);
+ float size = rand()%64/512.;
+ float visual_size = BS*size;
+ v2f texsize(size*2, ymax*size*2);
+ v2f texpos;
+ texpos.X = ((rand()%64)/64.-texsize.X);
+ texpos.Y = ymax*((rand()%64)/64.-texsize.Y);
// Physics
v3f velocity( (rand()%100/50.-1)/1.5,
rand()%100/100., // expiration time
visual_size,
true,
- ap);
+ texture,
+ texpos,
+ texsize);
}
/*
u16 amount, float time,
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
float minexptime, float maxexptime, float minsize, float maxsize,
- bool collisiondetection, AtlasPointer ap, u32 id)
+ bool collisiondetection, video::ITexture *texture, u32 id)
{
m_gamedef = gamedef;
m_smgr = smgr;
m_minsize = minsize;
m_maxsize = maxsize;
m_collisiondetection = collisiondetection;
- m_ap = ap;
+ m_texture = texture;
m_time = 0;
for (u16 i = 0; i<=m_amount; i++)
exptime,
size,
m_collisiondetection,
- m_ap);
+ m_texture,
+ v2f(0.0, 0.0),
+ v2f(1.0, 1.0));
m_spawntimes.erase(i);
}
else
exptime,
size,
m_collisiondetection,
- m_ap);
+ m_texture,
+ v2f(0.0, 0.0),
+ v2f(1.0, 1.0));
}
}
}
float expirationtime,
float size,
bool collisiondetection,
- AtlasPointer texture
+ video::ITexture *texture,
+ v2f texpos,
+ v2f texsize
);
~Particle();
core::aabbox3d<f32> m_box;
core::aabbox3d<f32> m_collisionbox;
video::SMaterial m_material;
+ v2f m_texpos;
+ v2f m_texsize;
v3f m_pos;
v3f m_velocity;
v3f m_acceleration;
- float tex_x0;
- float tex_x1;
- float tex_y0;
- float tex_y1;
LocalPlayer *m_player;
float m_size;
- AtlasPointer m_ap;
u8 m_light;
bool m_collisiondetection;
};
float minexptime, float maxexptime,
float minsize, float maxsize,
bool collisiondetection,
- AtlasPointer ap,
+ video::ITexture *texture,
u32 id);
~ParticleSpawner();
float m_maxexptime;
float m_minsize;
float m_maxsize;
- AtlasPointer m_ap;
+ video::ITexture *m_texture;
std::vector<float> m_spawntimes;
bool m_collisiondetection;
};
#include "mesh.h"
#include <ICameraSceneNode.h>
#include "log.h"
-#include "mapnode.h" // For texture atlas making
-#include "nodedef.h" // For texture atlas making
#include "gamedef.h"
#include "util/string.h"
#include "util/container.h"
}
/*
- An internal variant of AtlasPointer with more data.
- (well, more like a wrapper)
+ Stores internal information about a texture.
*/
-struct SourceAtlasPointer
+struct TextureInfo
{
std::string name;
- AtlasPointer a;
- video::IImage *atlas_img; // The source image of the atlas
- // Integer variants of position and size
- v2s32 intpos;
- v2u32 intsize;
+ video::ITexture *texture;
+ video::IImage *img; // The source image
- SourceAtlasPointer(
+ TextureInfo(
const std::string &name_,
- AtlasPointer a_=AtlasPointer(0, NULL),
- video::IImage *atlas_img_=NULL,
- v2s32 intpos_=v2s32(0,0),
- v2u32 intsize_=v2u32(0,0)
+ video::ITexture *texture_=NULL,
+ video::IImage *img_=NULL
):
name(name_),
- a(a_),
- atlas_img(atlas_img_),
- intpos(intpos_),
- intsize(intsize_)
+ texture(texture_),
+ img(img_)
{
}
};
Example case #2:
- Assume a texture with the id 1 exists, and has the name
- "stone.png^mineral1" and is specified as a part of some atlas.
+ "stone.png^mineral_coal.png".
- Now getNodeTile() stumbles upon a node which uses
texture id 1, and determines that MATERIAL_FLAG_CRACK
must be applied to the tile
has received the current crack level 0 from the client. It
finds out the name of the texture with getTextureName(1),
appends "^crack0" to it and gets a new texture id with
- getTextureId("stone.png^mineral1^crack0").
+ getTextureId("stone.png^mineral_coal.png^crack0").
*/
and not found in cache, the call is queued to the main thread
for processing.
*/
- AtlasPointer getTexture(u32 id);
-
- AtlasPointer getTexture(const std::string &name)
- {
- return getTexture(getTextureId(name));
- }
-
- // Gets a separate texture
- video::ITexture* getTextureRaw(const std::string &name)
- {
- AtlasPointer ap = getTexture(name + m_forcesingle_suffix);
- return ap.atlas;
- }
+ video::ITexture* getTexture(u32 id);
- // Gets a separate texture atlas pointer
- AtlasPointer getTextureRawAP(const AtlasPointer &ap)
- {
- return getTexture(getTextureName(ap.id) + m_forcesingle_suffix);
- }
+ video::ITexture* getTexture(const std::string &name, u32 *id);
// Returns a pointer to the irrlicht device
virtual IrrlichtDevice* getDevice()
return m_device;
}
- // Update new texture pointer and texture coordinates to an
- // AtlasPointer based on it's texture id
- void updateAP(AtlasPointer &ap);
-
bool isKnownSourceImage(const std::string &name)
{
bool is_known = false;
// Rebuild images and textures from the current set of source images
// Shall be called from the main thread.
void rebuildImagesAndTextures();
-
- // Build the main texture atlas which contains most of the
- // textures.
- void buildMainAtlas(class IGameDef *gamedef);
private:
// A texture id is index in this array.
// The first position contains a NULL texture.
- std::vector<SourceAtlasPointer> m_atlaspointer_cache;
+ std::vector<TextureInfo> m_textureinfo_cache;
// Maps a texture name to an index in the former.
std::map<std::string, u32> m_name_to_id;
// The two former containers are behind this mutex
- JMutex m_atlaspointer_cache_mutex;
+ JMutex m_textureinfo_cache_mutex;
- // Main texture atlas. This is filled at startup and is then not touched.
- video::IImage *m_main_atlas_image;
- video::ITexture *m_main_atlas_texture;
- std::string m_forcesingle_suffix;
-
// Queued texture fetches (to be processed by the main thread)
RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
}
TextureSource::TextureSource(IrrlichtDevice *device):
- m_device(device),
- m_main_atlas_image(NULL),
- m_main_atlas_texture(NULL)
+ m_device(device)
{
assert(m_device);
- m_atlaspointer_cache_mutex.Init();
+ m_textureinfo_cache_mutex.Init();
m_main_thread = get_current_thread_id();
- // Add a NULL AtlasPointer as the first index, named ""
- m_atlaspointer_cache.push_back(SourceAtlasPointer(""));
+ // Add a NULL TextureInfo as the first index, named ""
+ m_textureinfo_cache.push_back(TextureInfo(""));
m_name_to_id[""] = 0;
}
unsigned int textures_before = driver->getTextureCount();
- for (std::vector<SourceAtlasPointer>::iterator iter =
- m_atlaspointer_cache.begin(); iter != m_atlaspointer_cache.end();
- iter++)
+ for (std::vector<TextureInfo>::iterator iter =
+ m_textureinfo_cache.begin();
+ iter != m_textureinfo_cache.end(); iter++)
{
- video::ITexture *t = driver->getTexture(iter->name.c_str());
-
//cleanup texture
- if (t)
- driver->removeTexture(t);
+ if (iter->texture)
+ driver->removeTexture(iter->texture);
//cleanup source image
- if (iter->atlas_img)
- iter->atlas_img->drop();
+ if (iter->img)
+ iter->img->drop();
}
- m_atlaspointer_cache.clear();
+ m_textureinfo_cache.clear();
for (std::list<video::ITexture*>::iterator iter =
m_texture_trash.begin(); iter != m_texture_trash.end();
/*
See if texture already exists
*/
- JMutexAutoLock lock(m_atlaspointer_cache_mutex);
+ JMutexAutoLock lock(m_textureinfo_cache_mutex);
std::map<std::string, u32>::iterator n;
n = m_name_to_id.find(name);
if(n != m_name_to_id.end())
/*
Generates an image from a full string like
"stone.png^mineral_coal.png^[crack0".
-
- This is used by buildMainAtlas().
*/
video::IImage* generate_image_from_scratch(std::string name,
IrrlichtDevice *device, SourceImageCache *sourcecache);
See if texture already exists
*/
{
- JMutexAutoLock lock(m_atlaspointer_cache_mutex);
+ JMutexAutoLock lock(m_textureinfo_cache_mutex);
std::map<std::string, u32>::iterator n;
n = m_name_to_id.find(name);
// If a base image was found, copy it to baseimg
if(base_image_id != 0)
{
- JMutexAutoLock lock(m_atlaspointer_cache_mutex);
-
- SourceAtlasPointer ap = m_atlaspointer_cache[base_image_id];
+ JMutexAutoLock lock(m_textureinfo_cache_mutex);
- video::IImage *image = ap.atlas_img;
+ TextureInfo *ti = &m_textureinfo_cache[base_image_id];
- if(image == NULL)
+ if(ti->img == NULL)
{
infostream<<"getTextureIdDirect(): WARNING: NULL image in "
<<"cache: \""<<base_image_name<<"\""
}
else
{
- core::dimension2d<u32> dim = ap.intsize;
+ core::dimension2d<u32> dim = ti->img->getDimension();
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
- core::position2d<s32> pos_to(0,0);
- core::position2d<s32> pos_from = ap.intpos;
-
- image->copyTo(
+ ti->img->copyTo(
baseimg, // target
v2s32(0,0), // position in target
- core::rect<s32>(pos_from, dim) // from
+ core::rect<s32>(v2s32(0,0), dim) // from
);
/*infostream<<"getTextureIdDirect(): Loaded \""
Add texture to caches (add NULL textures too)
*/
- JMutexAutoLock lock(m_atlaspointer_cache_mutex);
+ JMutexAutoLock lock(m_textureinfo_cache_mutex);
- u32 id = m_atlaspointer_cache.size();
- AtlasPointer ap(id);
- ap.atlas = t;
- ap.pos = v2f(0,0);
- ap.size = v2f(1,1);
- ap.tiled = 0;
- core::dimension2d<u32> baseimg_dim(0,0);
- if(baseimg)
- baseimg_dim = baseimg->getDimension();
- SourceAtlasPointer nap(name, ap, baseimg, v2s32(0,0), baseimg_dim);
- m_atlaspointer_cache.push_back(nap);
+ u32 id = m_textureinfo_cache.size();
+ TextureInfo ti(name, t, baseimg);
+ m_textureinfo_cache.push_back(ti);
m_name_to_id[name] = id;
/*infostream<<"getTextureIdDirect(): "
std::string TextureSource::getTextureName(u32 id)
{
- JMutexAutoLock lock(m_atlaspointer_cache_mutex);
+ JMutexAutoLock lock(m_textureinfo_cache_mutex);
- if(id >= m_atlaspointer_cache.size())
+ if(id >= m_textureinfo_cache.size())
{
errorstream<<"TextureSource::getTextureName(): id="<<id
- <<" >= m_atlaspointer_cache.size()="
- <<m_atlaspointer_cache.size()<<std::endl;
+ <<" >= m_textureinfo_cache.size()="
+ <<m_textureinfo_cache.size()<<std::endl;
return "";
}
- return m_atlaspointer_cache[id].name;
+ return m_textureinfo_cache[id].name;
}
-
-AtlasPointer TextureSource::getTexture(u32 id)
+video::ITexture* TextureSource::getTexture(u32 id)
{
- JMutexAutoLock lock(m_atlaspointer_cache_mutex);
+ JMutexAutoLock lock(m_textureinfo_cache_mutex);
- if(id >= m_atlaspointer_cache.size())
- return AtlasPointer(0, NULL);
-
- return m_atlaspointer_cache[id].a;
+ if(id >= m_textureinfo_cache.size())
+ return NULL;
+
+ return m_textureinfo_cache[id].texture;
}
-void TextureSource::updateAP(AtlasPointer &ap)
+video::ITexture* TextureSource::getTexture(const std::string &name, u32 *id)
{
- AtlasPointer ap2 = getTexture(ap.id);
- ap = ap2;
+ u32 actual_id = getTextureId(name);
+ if(id){
+ *id = actual_id;
+ }
+ return getTexture(actual_id);
}
void TextureSource::processQueue()
void TextureSource::rebuildImagesAndTextures()
{
- JMutexAutoLock lock(m_atlaspointer_cache_mutex);
-
- /*// Oh well... just clear everything, they'll load sometime.
- m_atlaspointer_cache.clear();
- m_name_to_id.clear();*/
+ JMutexAutoLock lock(m_textureinfo_cache_mutex);
video::IVideoDriver* driver = m_device->getVideoDriver();
-
- // Remove source images from textures to disable inheriting textures
- // from existing textures
- /*for(u32 i=0; i<m_atlaspointer_cache.size(); i++){
- SourceAtlasPointer *sap = &m_atlaspointer_cache[i];
- sap->atlas_img->drop();
- sap->atlas_img = NULL;
- }*/
-
+
// Recreate textures
- for(u32 i=0; i<m_atlaspointer_cache.size(); i++){
- SourceAtlasPointer *sap = &m_atlaspointer_cache[i];
+ for(u32 i=0; i<m_textureinfo_cache.size(); i++){
+ TextureInfo *ti = &m_textureinfo_cache[i];
video::IImage *img =
- generate_image_from_scratch(sap->name, m_device, &m_sourcecache);
+ generate_image_from_scratch(ti->name, m_device, &m_sourcecache);
// Create texture from resulting image
video::ITexture *t = NULL;
if(img)
- t = driver->addTexture(sap->name.c_str(), img);
- video::ITexture *t_old = sap->a.atlas;
+ t = driver->addTexture(ti->name.c_str(), img);
+ video::ITexture *t_old = ti->texture;
// Replace texture
- sap->a.atlas = t;
- sap->a.pos = v2f(0,0);
- sap->a.size = v2f(1,1);
- sap->a.tiled = 0;
- sap->atlas_img = img;
- sap->intpos = v2s32(0,0);
- sap->intsize = img->getDimension();
+ ti->texture = t;
+ ti->img = img;
if (t_old != 0)
m_texture_trash.push_back(t_old);
}
}
-void TextureSource::buildMainAtlas(class IGameDef *gamedef)
-{
- assert(gamedef->tsrc() == this);
- INodeDefManager *ndef = gamedef->ndef();
-
- infostream<<"TextureSource::buildMainAtlas()"<<std::endl;
-
- //return; // Disable (for testing)
-
- video::IVideoDriver* driver = m_device->getVideoDriver();
- assert(driver);
-
- JMutexAutoLock lock(m_atlaspointer_cache_mutex);
-
- // Create an image of the right size
- 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 =
- driver->createImage(video::ECF_A8R8G8B8, atlas_dim);
- //assert(atlas_img);
- if(atlas_img == NULL)
- {
- errorstream<<"TextureSource::buildMainAtlas(): Failed to create atlas "
- "image; not building texture atlas."<<std::endl;
- return;
- }
-
- /*
- Grab list of stuff to include in the texture atlas from the
- main content features
- */
-
- std::set<std::string> sourcelist;
-
- for(u16 j=0; j<MAX_CONTENT+1; j++)
- {
- if(j == CONTENT_IGNORE || j == CONTENT_AIR)
- continue;
- const ContentFeatures &f = ndef->get(j);
- for(u32 i=0; i<6; i++)
- {
- std::string name = f.tiledef[i].name;
- sourcelist.insert(name);
- }
- }
-
- infostream<<"Creating texture atlas out of textures: ";
- for(std::set<std::string>::iterator
- i = sourcelist.begin();
- i != sourcelist.end(); ++i)
- {
- std::string name = *i;
- infostream<<"\""<<name<<"\" ";
- }
- infostream<<std::endl;
-
- // Padding to disallow texture bleeding
- // (16 needed if mipmapping is used; otherwise less will work too)
- s32 padding = 16;
- s32 column_padding = 16;
- s32 column_width = 256; // Space for 16 pieces of 16x16 textures
-
- /*
- First pass: generate almost everything
- */
- core::position2d<s32> pos_in_atlas(0,0);
-
- pos_in_atlas.X = column_padding;
- pos_in_atlas.Y = padding;
-
- for(std::set<std::string>::iterator
- i = sourcelist.begin();
- i != sourcelist.end(); ++i)
- {
- std::string name = *i;
-
- // Generate image by name
- video::IImage *img2 = generate_image_from_scratch(name, m_device,
- &m_sourcecache);
- if(img2 == NULL)
- {
- errorstream<<"TextureSource::buildMainAtlas(): "
- <<"Couldn't generate image \""<<name<<"\""<<std::endl;
- continue;
- }
-
- core::dimension2d<u32> dim = img2->getDimension();
-
- // Don't add to atlas if image is too large
- core::dimension2d<u32> max_size_in_atlas(64,64);
- if(dim.Width > max_size_in_atlas.Width
- || dim.Height > max_size_in_atlas.Height)
- {
- infostream<<"TextureSource::buildMainAtlas(): Not adding "
- <<"\""<<name<<"\" because image is large"<<std::endl;
- continue;
- }
-
- // 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;
- }
-
- /*
- Make texture
- */
- video::ITexture *t = driver->addTexture("__main_atlas__", atlas_img);
- assert(t);
-
- /*
- Second pass: set texture pointer in generated AtlasPointers
- */
- for(std::set<std::string>::iterator
- i = sourcelist.begin();
- i != sourcelist.end(); ++i)
- {
- std::string name = *i;
- if(m_name_to_id.find(name) == m_name_to_id.end())
- continue;
- u32 id = m_name_to_id[name];
- //infostream<<"id of name "<<name<<" is "<<id<<std::endl;
- m_atlaspointer_cache[id].a.atlas = t;
- }
-
- /*
- Write image to file so that it can be inspected
- */
- /*std::string atlaspath = porting::path_user
- + DIR_DELIM + "generated_texture_atlas.png";
- infostream<<"Removing and writing texture atlas for inspection to "
- <<atlaspath<<std::endl;
- fs::RecursiveDelete(atlaspath);
- driver->writeImageToFile(atlas_img, atlaspath.c_str());*/
-
- m_forcesingle_suffix = "^[forcesingle";
-}
-
video::IImage* generate_image_from_scratch(std::string name,
IrrlichtDevice *device, SourceImageCache *sourcecache)
{
<<"modification \""<<part_of_name<<"\""
<<std::endl;*/
- /*
- This is the simplest of all; it just adds stuff to the
- name so that a separate texture is created.
-
- It is used to make textures for stuff that doesn't want
- to implement getting the texture from a bigger texture
- atlas.
- */
- if(part_of_name == "[forcesingle")
- {
- // If base image is NULL, create a random color
- if(baseimg == NULL)
- {
- core::dimension2d<u32> dim(1,1);
- baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
- assert(baseimg);
- baseimg->setPixel(0,0, video::SColor(255,myrand()%256,
- myrand()%256,myrand()%256));
- }
- }
/*
[crackN
Adds a cracking texture
*/
- else if(part_of_name.substr(0,6) == "[crack")
+ if(part_of_name.substr(0,6) == "[crack")
{
if(baseimg == NULL)
{
*/
std::string getTexturePath(const std::string &filename);
-/*
- Specifies a texture in an atlas.
-
- This is used to specify single textures also.
-
- This has been designed to be small enough to be thrown around a lot.
-*/
-struct AtlasPointer
-{
- u32 id; // Texture id
- video::ITexture *atlas; // Atlas in where the texture is
- v2f pos; // Position in atlas
- v2f size; // Size in atlas
- u16 tiled; // X-wise tiling count. If 0, width of atlas is width of image.
-
- AtlasPointer():
- id(0),
- atlas(NULL),
- pos(0,0),
- size(1,1),
- tiled(1)
- {}
-
- AtlasPointer(
- u16 id_,
- video::ITexture *atlas_=NULL,
- v2f pos_=v2f(0,0),
- v2f size_=v2f(1,1),
- u16 tiled_=1
- ):
- id(id_),
- atlas(atlas_),
- pos(pos_),
- size(size_),
- tiled(tiled_)
- {
- }
-
- bool operator==(const AtlasPointer &other) const
- {
- return (
- id == other.id
- );
- /*return (
- id == other.id &&
- atlas == other.atlas &&
- pos == other.pos &&
- size == other.size &&
- tiled == other.tiled
- );*/
- }
-
- bool operator!=(const AtlasPointer &other) const
- {
- return !(*this == other);
- }
-
- float x0(){ return pos.X; }
- float x1(){ return pos.X + size.X; }
- float y0(){ return pos.Y; }
- float y1(){ return pos.Y + size.Y; }
-};
-
/*
TextureSource creates and caches textures.
*/
virtual u32 getTextureId(const std::string &name){return 0;}
virtual u32 getTextureIdDirect(const std::string &name){return 0;}
virtual std::string getTextureName(u32 id){return "";}
- virtual AtlasPointer getTexture(u32 id){return AtlasPointer(0);}
- virtual AtlasPointer getTexture(const std::string &name)
- {return AtlasPointer(0);}
- virtual video::ITexture* getTextureRaw(const std::string &name)
- {return NULL;}
- virtual AtlasPointer getTextureRawAP(const AtlasPointer &ap)
- {return AtlasPointer(0);}
+ virtual video::ITexture* getTexture(u32 id){return NULL;}
+ virtual video::ITexture* getTexture(
+ const std::string &name, u32 *id = NULL){
+ if(id) *id = 0;
+ return NULL;
+ }
virtual IrrlichtDevice* getDevice()
{return NULL;}
- virtual void updateAP(AtlasPointer &ap){};
virtual bool isKnownSourceImage(const std::string &name)=0;
};
virtual u32 getTextureId(const std::string &name){return 0;}
virtual u32 getTextureIdDirect(const std::string &name){return 0;}
virtual std::string getTextureName(u32 id){return "";}
- virtual AtlasPointer getTexture(u32 id){return AtlasPointer(0);}
- virtual AtlasPointer getTexture(const std::string &name)
- {return AtlasPointer(0);}
- virtual video::ITexture* getTextureRaw(const std::string &name)
- {return NULL;}
- virtual IrrlichtDevice* getDevice()
- {return NULL;}
- virtual void updateAP(AtlasPointer &ap){};
+ virtual video::ITexture* getTexture(u32 id){return NULL;}
+ virtual video::ITexture* getTexture(
+ const std::string &name, u32 *id = NULL){
+ if(id) *id = 0;
+ return NULL;
+ }
+ virtual IrrlichtDevice* getDevice(){return NULL;}
virtual bool isKnownSourceImage(const std::string &name)=0;
virtual void processQueue()=0;
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
virtual void rebuildImagesAndTextures()=0;
- virtual void buildMainAtlas(class IGameDef *gamedef)=0;
};
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
// Animation made up by splitting the texture to vertical frames, as
// defined by extra parameters
#define MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES 0x08
-// Whether liquid shader should be used
-#define MATERIAL_FLAG_
/*
This fully defines the looks of a tile.
struct TileSpec
{
TileSpec():
- texture(0),
+ texture_id(0),
+ texture(NULL),
alpha(255),
material_type(TILE_MATERIAL_BASIC),
material_flags(
MATERIAL_FLAG_BACKFACE_CULLING
),
animation_frame_count(1),
- animation_frame_length_ms(0)
+ animation_frame_length_ms(0),
+ rotation(0)
{
}
bool operator==(const TileSpec &other) const
{
return (
- texture == other.texture &&
+ texture_id == other.texture_id &&
+ /* texture == other.texture && */
alpha == other.alpha &&
material_type == other.material_type &&
material_flags == other.material_flags &&
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING) ? true : false;
}
- // NOTE: Deprecated, i guess?
- void setTexturePos(u8 tx_, u8 ty_, u8 tw_, u8 th_)
- {
- texture.pos = v2f((float)tx_/256.0, (float)ty_/256.0);
- texture.size = v2f(((float)tw_ + 1.0)/256.0, ((float)th_ + 1.0)/256.0);
- }
-
- AtlasPointer texture;
+ u32 texture_id;
+ video::ITexture *texture;
// Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
u8 alpha;
// Material parameters