aboutsummaryrefslogtreecommitdiff
path: root/src/mapblock.cpp
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-02-10 02:13:03 +0200
committerPerttu Ahola <celeron55@gmail.com>2011-02-10 02:13:03 +0200
commit1704badc306fc8c7c6609aff9f809aee3ac00d3a (patch)
tree76e1ba37bb0ec12bb744a6015f56613ba088e148 /src/mapblock.cpp
parent949383a2f7c0707667f76615fc748ff4879e2cc1 (diff)
downloadminetest-1704badc306fc8c7c6609aff9f809aee3ac00d3a.tar.gz
minetest-1704badc306fc8c7c6609aff9f809aee3ac00d3a.tar.bz2
minetest-1704badc306fc8c7c6609aff9f809aee3ac00d3a.zip
work-in-progress texture atlas optimization
Diffstat (limited to 'src/mapblock.cpp')
-rw-r--r--src/mapblock.cpp190
1 files changed, 147 insertions, 43 deletions
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index e3e90a9a1..2ec63dbde 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -273,13 +273,32 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
video::SColor c = video::SColor(alpha,li,li,li);
face.vertices[0] = video::S3DVertex(vertex_pos[0], zerovector, c,
- core::vector2d<f32>(0,1));
- face.vertices[1] = video::S3DVertex(vertex_pos[1], zerovector, c,
core::vector2d<f32>(abs_scale,1));
+ face.vertices[1] = video::S3DVertex(vertex_pos[1], zerovector, c,
+ core::vector2d<f32>(0,1));
face.vertices[2] = video::S3DVertex(vertex_pos[2], zerovector, c,
+ core::vector2d<f32>(0,0));
+ face.vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c,
core::vector2d<f32>(abs_scale,0));
+
+ /*float x0 = (float)tile.tx/256.0;
+ float y0 = (float)tile.ty/256.0;
+ float w = ((float)tile.tw + 1.0)/256.0;
+ float h = ((float)tile.th + 1.0)/256.0;*/
+
+ 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], zerovector, c,
+ core::vector2d<f32>(x0+w*abs_scale, y0+h));
+ face.vertices[1] = video::S3DVertex(vertex_pos[1], zerovector, c,
+ core::vector2d<f32>(x0, y0+h));
+ face.vertices[2] = video::S3DVertex(vertex_pos[2], zerovector, c,
+ core::vector2d<f32>(x0, y0));
face.vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c,
- core::vector2d<f32>(0,0));
+ core::vector2d<f32>(x0+w*abs_scale, y0));
face.tile = tile;
//DEBUG
@@ -318,11 +337,26 @@ TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
}
if(mod.type == NODEMOD_CRACK)
{
+ /*
+ Get texture id, translate it to name, append stuff to
+ name, get texture id
+ */
+ // Get original texture name
+ u32 orig_id = spec.texture.id;
+ std::string orig_name = g_texturesource->getTextureName(orig_id);
+ // Create new texture name
std::ostringstream os;
- os<<"[crack"<<mod.param;
-
- textureid_t tid = g_irrlicht->getTextureId(os.str());
- spec.spec.addTid(tid);
+ os<<orig_name<<"^[crack"<<mod.param;
+ //os<<orig_name<<"^[progressbar0.5";
+ //os<<"mese.png";
+ // Get new texture
+ u32 new_id = g_texturesource->getTextureId(os.str());
+
+ dstream<<"MapBlock::getNodeTile(): Switching from "
+ <<orig_name<<" to "<<os.str()<<" ("
+ <<orig_id<<" to "<<new_id<<")"<<std::endl;
+
+ spec.texture = g_texturesource->getTexture(new_id);
}
}
@@ -406,7 +440,9 @@ void MapBlock::updateFastFaceRow(
TileSpec tile0_next;
TileSpec tile1_next;
u8 light_next = 0;
-
+
+ // If at last position, there is nothing to compare to and
+ // the face must be drawn anyway
if(j != length - 1)
{
p_next = p + translate_dir;
@@ -426,7 +462,31 @@ void MapBlock::updateFastFaceRow(
continuous_tiles_count++;
- if(next_is_different)
+ // 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.
+
+ This check has to be made for both tiles, because this is
+ a bit hackish and we know which one we're using only when
+ the decision to make the faces is made.
+ */
+ if(tile0.texture.atlas != NULL && tile0.texture.tiled != 0)
+ {
+ if(tile0.texture.tiled <= continuous_tiles_count)
+ end_of_texture = true;
+ }
+ if(tile1.texture.atlas != NULL && tile1.texture.tiled != 0)
+ {
+ if(tile1.texture.tiled <= continuous_tiles_count)
+ end_of_texture = true;
+ }
+
+ //end_of_texture = true; //DEBUG
+
+ if(next_is_different || end_of_texture)
{
/*
Create a face if there should be one
@@ -684,10 +744,6 @@ void MapBlock::updateMesh(u32 daynight_ratio)
Convert FastFaces to SMesh
*/
- scene::SMesh *mesh_new = NULL;
-
- mesh_new = new scene::SMesh();
-
MeshCollector collector;
if(fastfaces_new.size() > 0)
@@ -708,8 +764,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
FastFace &f = fastfaces_new[i];
const u16 indices[] = {0,1,2,2,3,0};
-
- video::ITexture *texture = g_irrlicht->getTexture(f.tile.spec);
+
+ //video::ITexture *texture = g_irrlicht->getTexture(f.tile.spec);
+ video::ITexture *texture = f.tile.texture.atlas;
if(texture == NULL)
continue;
@@ -717,11 +774,6 @@ void MapBlock::updateMesh(u32 daynight_ratio)
f.tile.applyMaterialOptions(material);
- /*if(f.tile.alpha != 255)
- material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
- else
- material.MaterialType = video::EMT_SOLID;*/
-
collector.append(material, f.vertices, 4, indices, 6);
}
}
@@ -742,7 +794,11 @@ void MapBlock::updateMesh(u32 daynight_ratio)
material_water1.setFlag(video::EMF_BILINEAR_FILTER, false);
material_water1.setFlag(video::EMF_FOG_ENABLE, true);
material_water1.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
- material_water1.setTexture(0, g_irrlicht->getTexture("water.png"));
+ //TODO
+ //material_water1.setTexture(0, g_irrlicht->getTexture("water.png"));
+ AtlasPointer pa_water1 = g_texturesource->getTexture(
+ g_texturesource->getTextureId("water.png"));
+ material_water1.setTexture(0, pa_water1.atlas);
// New-style leaves material
video::SMaterial material_leaves1;
@@ -751,7 +807,11 @@ void MapBlock::updateMesh(u32 daynight_ratio)
material_leaves1.setFlag(video::EMF_BILINEAR_FILTER, false);
material_leaves1.setFlag(video::EMF_FOG_ENABLE, true);
material_leaves1.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
- material_leaves1.setTexture(0, g_irrlicht->getTexture("leaves.png"));
+ //TODO
+ //material_leaves1.setTexture(0, g_irrlicht->getTexture("leaves.png"));
+ AtlasPointer pa_leaves1 = g_texturesource->getTexture(
+ g_texturesource->getTextureId("leaves.png"));
+ material_leaves1.setTexture(0, pa_leaves1.atlas);
for(s16 z=0; z<MAP_BLOCKSIZE; z++)
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
@@ -804,7 +864,8 @@ void MapBlock::updateMesh(u32 daynight_ratio)
//material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
material.MaterialType
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
- if(dir == v3s16(0,-1,0))
+ //TODO
+ /*if(dir == v3s16(0,-1,0))
material.setTexture(0,
g_irrlicht->getTexture("torch_on_floor.png"));
else if(dir == v3s16(0,1,0))
@@ -816,7 +877,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
g_irrlicht->getTexture("torch_on_floor.png"));
else
material.setTexture(0,
- g_irrlicht->getTexture("torch.png"));
+ g_irrlicht->getTexture("torch.png"));*/
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
@@ -974,14 +1035,18 @@ void MapBlock::updateMesh(u32 daynight_ratio)
video::S3DVertex vertices[4] =
{
- /*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),*/
- video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,1),
+ /*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(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/
+ video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c,
+ pa_water1.x0(), pa_water1.y1()),
+ video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c,
+ pa_water1.x1(), pa_water1.y1()),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
+ pa_water1.x1(), pa_water1.y0()),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
+ pa_water1.x0(), pa_water1.y0()),
};
/*
@@ -1048,10 +1113,18 @@ void MapBlock::updateMesh(u32 daynight_ratio)
{
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,1),
+ /*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(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/
+ video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c,
+ pa_water1.x0(), pa_water1.y1()),
+ video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c,
+ pa_water1.x1(), pa_water1.y1()),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
+ pa_water1.x1(), pa_water1.y0()),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
+ pa_water1.x0(), pa_water1.y0()),
};
for(s32 i=0; i<4; i++)
@@ -1092,10 +1165,18 @@ void MapBlock::updateMesh(u32 daynight_ratio)
video::S3DVertex vertices[4] =
{
- video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,1),
+ /*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(-BS/2,0,BS/2, 0,0,0, c, 0,0),*/
+ video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c,
+ pa_water1.x0(), pa_water1.y1()),
+ video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c,
+ pa_water1.x1(), pa_water1.y1()),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c,
+ pa_water1.x1(), pa_water1.y0()),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c,
+ pa_water1.x0(), pa_water1.y0()),
};
for(s32 i=0; i<4; i++)
@@ -1120,10 +1201,18 @@ void MapBlock::updateMesh(u32 daynight_ratio)
{
video::S3DVertex vertices[4] =
{
- 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, 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),
+ video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c, 0,0),*/
+ video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c,
+ pa_leaves1.x0(), pa_leaves1.y1()),
+ video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c,
+ pa_leaves1.x1(), pa_leaves1.y1()),
+ video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c,
+ pa_leaves1.x1(), pa_leaves1.y0()),
+ video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c,
+ pa_leaves1.x0(), pa_leaves1.y0()),
};
if(j == 0)
@@ -1173,6 +1262,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
Add stuff from collector to mesh
*/
+ scene::SMesh *mesh_new = NULL;
+ mesh_new = new scene::SMesh();
+
collector.fillMesh(mesh_new);
/*
@@ -1191,13 +1283,25 @@ void MapBlock::updateMesh(u32 daynight_ratio)
mesh_new = NULL;
}
- // Use VBO for mesh (this just would set this for ever buffer)
- // This will lead to infinite memory usage because or irrlicht.
- //mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
-
- /*std::cout<<"MapBlock has "<<fastfaces_new.size()<<" faces "
- <<"and uses "<<mesh_new->getMeshBufferCount()
- <<" materials (meshbuffers)"<<std::endl;*/
+ if(mesh_new)
+ {
+#if 0
+ // Usually 1-700 faces and 1-7 materials
+ std::cout<<"Updated MapBlock has "<<fastfaces_new.size()<<" faces "
+ <<"and uses "<<mesh_new->getMeshBufferCount()
+ <<" materials (meshbuffers)"<<std::endl;
+#endif
+
+ // Use VBO for mesh (this just would set this for ever buffer)
+ // This will lead to infinite memory usage because or irrlicht.
+ //mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
+
+ /*
+ NOTE: If that is enabled, some kind of a queue to the main
+ thread should be made which would call irrlicht to delete
+ the hardware buffer and then delete the mesh
+ */
+ }
/*
Replace the mesh