diff --git a/minetest.conf.example b/minetest.conf.example index 3f1977268..75e546c2f 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -112,9 +112,6 @@ # 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. diff --git a/src/client.cpp b/src/client.cpp index c82d9b050..5e682aaa3 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -320,12 +320,6 @@ Client::Client( 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."<rebuildImagesAndTextures(); - // Update texture atlas - infostream<<"- Updating texture atlas"<getBool("enable_texture_atlas")) - m_tsrc->buildMainAtlas(this); - // Rebuild shaders m_shsrc->rebuildShaders(); diff --git a/src/content_cao.cpp b/src/content_cao.cpp index f79d0d6f6..ece284343 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -223,7 +223,7 @@ void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, // 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; @@ -393,7 +393,7 @@ void ItemCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, 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; @@ -864,7 +864,7 @@ public: 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); @@ -1273,7 +1273,7 @@ public: 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 @@ -1300,7 +1300,7 @@ public: 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 "< 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 @@ -1378,7 +1373,7 @@ public: 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 @@ -1403,7 +1398,7 @@ public: 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 diff --git a/src/content_cso.cpp b/src/content_cso.cpp index 73d5f2b48..4f652a8a3 100644 --- a/src/content_cso.cpp +++ b/src/content_cso.cpp @@ -50,7 +50,7 @@ public: 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); diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 84408e776..bc17e19aa 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -99,7 +99,6 @@ void makeCuboid(MeshCollector *collector, const aabb3f &box, 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) @@ -119,49 +118,43 @@ void makeCuboid(MeshCollector *collector, const aabb3f &box, 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) @@ -218,7 +211,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data, */ 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)); @@ -280,14 +272,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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), }; /* @@ -359,14 +347,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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); @@ -386,7 +370,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data, */ 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)); @@ -566,14 +549,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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), }; /* @@ -647,14 +626,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, { 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 @@ -725,7 +700,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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)); @@ -741,14 +715,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, // 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 @@ -910,7 +880,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data, { 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)); @@ -945,22 +914,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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++) @@ -990,7 +953,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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)); @@ -999,14 +961,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, // 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); @@ -1037,7 +995,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data, { 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)); @@ -1046,16 +1003,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data, { 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) @@ -1088,10 +1041,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data, // 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)); @@ -1341,8 +1297,6 @@ void mapblock_mesh_generate_special(MeshMakeData *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)); @@ -1354,14 +1308,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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++) diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 501a04f51..44f5d1e86 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -94,7 +94,6 @@ void set_default_settings(Settings *settings) 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"); diff --git a/src/farmesh.cpp b/src/farmesh.cpp index ecf01ee07..93c50e5d0 100644 --- a/src/farmesh.cpp +++ b/src/farmesh.cpp @@ -65,7 +65,7 @@ FarMesh::FarMesh( 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); diff --git a/src/game.cpp b/src/game.cpp index 65b52777a..bcd155a79 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1345,7 +1345,7 @@ void the_game( */ 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; } @@ -2312,7 +2312,7 @@ void the_game( 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(), @@ -2321,12 +2321,15 @@ void the_game( *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, @@ -2343,7 +2346,7 @@ void the_game( 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) diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index c1b256f08..ee39df8b7 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -519,7 +519,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) 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); @@ -805,7 +805,7 @@ void GUIFormSpecMenu::drawMenu() { 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 imgrect(0, 0, spec.geom.X, spec.geom.Y); // Image rectangle on screen @@ -825,7 +825,7 @@ void GUIFormSpecMenu::drawMenu() { 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 imgrect(0, 0, spec.geom.X, spec.geom.Y); // Image rectangle on screen diff --git a/src/hud.cpp b/src/hud.cpp index 9404ed997..f1a4ab523 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -178,7 +178,7 @@ void Hud::drawLuaElements() { 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; @@ -228,7 +228,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s 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; @@ -306,7 +306,7 @@ void Hud::drawCrosshair() { 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)); diff --git a/src/itemdef.cpp b/src/itemdef.cpp index d660db77f..b582aef78 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -341,7 +341,7 @@ public: 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) { @@ -365,7 +365,7 @@ public: 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) @@ -446,7 +446,7 @@ public: if(cc->inventory_texture == NULL) { cc->inventory_texture = - tsrc->getTextureRaw(f.tiledef[0].name); + tsrc->getTexture(f.tiledef[0].name); } } else diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index be88b1973..a9ed75325 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -452,6 +452,11 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, // 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); @@ -488,8 +493,8 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, 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]; @@ -497,8 +502,8 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, 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]; @@ -506,8 +511,8 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, 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]; @@ -515,16 +520,16 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, 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; @@ -555,11 +560,6 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, 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(x0+w*abs_scale, y0+h)); @@ -645,12 +645,6 @@ TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data) 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; } @@ -717,7 +711,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data) 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; } @@ -889,23 +883,7 @@ static void updateFastFaceRow( 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 @@ -1060,7 +1038,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data): 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; @@ -1112,7 +1090,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data): 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 @@ -1137,9 +1115,11 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data): } // Replace tile texture with the first animation frame std::ostringstream os(std::ios::binary); - os<getTextureName(p.tile.texture.id); + os<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) @@ -1173,7 +1153,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data): //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 @@ -1259,8 +1239,8 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat ITextureSource *tsrc = m_gamedef->getTextureSource(); std::ostringstream os; os<getTexture(os.str()); - buf->getMaterial().setTexture(0, ap.atlas); + buf->getMaterial().setTexture(0, + tsrc->getTexture(os.str())); } m_last_crack = crack; @@ -1287,11 +1267,10 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat // Create new texture name from original std::ostringstream os(std::ios::binary); - os<getTextureName(tile.texture.id); + os<getTextureName(tile.texture_id); os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<getTexture(os.str()); - buf->getMaterial().setTexture(0, ap.atlas); + buf->getMaterial().setTexture(0, tsrc->getTexture(os.str())); } // Day-night transition diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 7d8ce70d3..13e7e9958 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -674,7 +674,9 @@ public: // 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 @@ -689,10 +691,9 @@ public: 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; @@ -715,8 +716,9 @@ public: // Special tiles (fill in f->special_tiles[]) for(u16 j=0; jspecial_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 @@ -731,10 +733,9 @@ public: 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; diff --git a/src/nodedef.h b/src/nodedef.h index e397d20e0..665a5ddc2 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -312,7 +312,6 @@ public: /* Update tile textures to latest return values of TextueSource. - Call after updating the texture atlas of a TextureSource. */ virtual void updateTextures(ITextureSource *tsrc)=0; diff --git a/src/particles.cpp b/src/particles.cpp index 1d814f619..88905d40d 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -57,7 +57,9 @@ Particle::Particle( float expirationtime, float size, bool collisiondetection, - AtlasPointer ap + video::ITexture *texture, + v2f texpos, + v2f texsize ): scene::ISceneNode(smgr->getRootSceneNode(), smgr) { @@ -70,8 +72,9 @@ Particle::Particle( 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 @@ -180,14 +183,19 @@ void Particle::updateLight(ClientEnvironment &env) 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++) { @@ -248,19 +256,19 @@ void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, { // Texture u8 texid = myrand_range(0,5); - AtlasPointer ap = tiles[texid].texture; + video::ITexture *texture = tiles[texid].texture; + + // 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; + float size = rand()%64/512.; float visual_size = BS*size; - float texsize = size*2; - - float x1 = ap.x1(); - float y1 = ap.y1(); - - 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); + 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, @@ -285,7 +293,9 @@ void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, rand()%100/100., // expiration time visual_size, true, - ap); + texture, + texpos, + texsize); } /* @@ -296,7 +306,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, 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; @@ -314,7 +324,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *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++) @@ -362,7 +372,9 @@ void ParticleSpawner::step(float dtime, ClientEnvironment &env) exptime, size, m_collisiondetection, - m_ap); + m_texture, + v2f(0.0, 0.0), + v2f(1.0, 1.0)); m_spawntimes.erase(i); } else @@ -398,7 +410,9 @@ void ParticleSpawner::step(float dtime, ClientEnvironment &env) exptime, size, m_collisiondetection, - m_ap); + m_texture, + v2f(0.0, 0.0), + v2f(1.0, 1.0)); } } } diff --git a/src/particles.h b/src/particles.h index 308da551f..327dcbc9e 100644 --- a/src/particles.h +++ b/src/particles.h @@ -42,7 +42,9 @@ class Particle : public scene::ISceneNode float expirationtime, float size, bool collisiondetection, - AtlasPointer texture + video::ITexture *texture, + v2f texpos, + v2f texsize ); ~Particle(); @@ -81,16 +83,13 @@ private: core::aabbox3d m_box; core::aabbox3d 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; }; @@ -109,7 +108,7 @@ class ParticleSpawner float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, - AtlasPointer ap, + video::ITexture *texture, u32 id); ~ParticleSpawner(); @@ -136,7 +135,7 @@ class ParticleSpawner float m_maxexptime; float m_minsize; float m_maxsize; - AtlasPointer m_ap; + video::ITexture *m_texture; std::vector m_spawntimes; bool m_collisiondetection; }; diff --git a/src/tile.cpp b/src/tile.cpp index f176d1549..da286fda9 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -25,8 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mesh.h" #include #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" @@ -165,31 +163,23 @@ std::string getTexturePath(const std::string &filename) } /* - 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_) { } }; @@ -307,7 +297,7 @@ public: 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 @@ -315,7 +305,7 @@ public: 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"). */ @@ -354,25 +344,9 @@ public: 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() @@ -380,10 +354,6 @@ public: 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; @@ -407,10 +377,6 @@ public: // 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: @@ -428,17 +394,12 @@ private: // A texture id is index in this array. // The first position contains a NULL texture. - std::vector m_atlaspointer_cache; + std::vector m_textureinfo_cache; // Maps a texture name to an index in the former. std::map 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 m_get_texture_queue; @@ -453,18 +414,16 @@ IWritableTextureSource* createTextureSource(IrrlichtDevice *device) } 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; } @@ -474,21 +433,19 @@ TextureSource::~TextureSource() unsigned int textures_before = driver->getTextureCount(); - for (std::vector::iterator iter = - m_atlaspointer_cache.begin(); iter != m_atlaspointer_cache.end(); - iter++) + for (std::vector::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::iterator iter = m_texture_trash.begin(); iter != m_texture_trash.end(); @@ -512,7 +469,7 @@ u32 TextureSource::getTextureId(const std::string &name) /* See if texture already exists */ - JMutexAutoLock lock(m_atlaspointer_cache_mutex); + JMutexAutoLock lock(m_textureinfo_cache_mutex); std::map::iterator n; n = m_name_to_id.find(name); if(n != m_name_to_id.end()) @@ -591,8 +548,6 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, /* 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); @@ -625,7 +580,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) See if texture already exists */ { - JMutexAutoLock lock(m_atlaspointer_cache_mutex); + JMutexAutoLock lock(m_textureinfo_cache_mutex); std::map::iterator n; n = m_name_to_id.find(name); @@ -693,13 +648,11 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) // If a base image was found, copy it to baseimg if(base_image_id != 0) { - JMutexAutoLock lock(m_atlaspointer_cache_mutex); + JMutexAutoLock lock(m_textureinfo_cache_mutex); - SourceAtlasPointer ap = m_atlaspointer_cache[base_image_id]; - - 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: \""< dim = ap.intsize; + core::dimension2d dim = ti->img->getDimension(); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); - core::position2d pos_to(0,0); - core::position2d pos_from = ap.intpos; - - image->copyTo( + ti->img->copyTo( baseimg, // target v2s32(0,0), // position in target - core::rect(pos_from, dim) // from + core::rect(v2s32(0,0), dim) // from ); /*infostream<<"getTextureIdDirect(): Loaded \"" @@ -759,19 +709,11 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) 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 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(): " @@ -782,34 +724,36 @@ u32 TextureSource::getTextureIdDirect(const std::string &name) 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="<= m_atlaspointer_cache.size()=" - <= m_textureinfo_cache.size()=" + <= 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() @@ -849,299 +793,29 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im 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; iatlas_img->drop(); - sap->atlas_img = NULL; - }*/ - + // Recreate textures - for(u32 i=0; iname, 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()"<getVideoDriver(); - assert(driver); - - JMutexAutoLock lock(m_atlaspointer_cache_mutex); - - // Create an image of the right size - core::dimension2d max_dim = driver->getMaxTextureSize(); - core::dimension2d 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."< sourcelist; - - for(u16 j=0; jget(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::iterator - i = sourcelist.begin(); - i != sourcelist.end(); ++i) - { - std::string name = *i; - infostream<<"\""< pos_in_atlas(0,0); - - pos_in_atlas.X = column_padding; - pos_in_atlas.Y = padding; - - for(std::set::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 \""< dim = img2->getDimension(); - - // Don't add to atlas if image is too large - core::dimension2d 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 " - <<"\""< 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." - < 16) // Limit to 16 (more gives no benefit) - xwise_tiling = 16; - for(u32 j=0; jcopyToWithAlpha(atlas_img, - pos_in_atlas + v2s32(j*dim.Width,0), - core::rect(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(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; y0getPixel(x, src_y); - atlas_img->setPixel(x,dst_y,c); - } - - for(u32 side=0; side<2; side++) // left and right - for(s32 x0=0; x0getPixel(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::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"<addTexture("__main_atlas__", atlas_img); - assert(t); - - /* - Second pass: set texture pointer in generated AtlasPointers - */ - for(std::set::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 "<writeImageToFile(atlas_img, atlaspath.c_str());*/ - - m_forcesingle_suffix = "^[forcesingle"; -} - video::IImage* generate_image_from_scratch(std::string name, IrrlichtDevice *device, SourceImageCache *sourcecache) { @@ -1285,31 +959,11 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg, <<"modification \""< 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) { diff --git a/src/tile.h b/src/tile.h index 531a93172..144cb6475 100644 --- a/src/tile.h +++ b/src/tile.h @@ -57,69 +57,6 @@ std::string getImagePath(std::string path); */ 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. */ @@ -132,16 +69,14 @@ public: 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; }; @@ -153,20 +88,18 @@ public: 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); @@ -189,8 +122,6 @@ enum MaterialType{ // 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. @@ -199,7 +130,8 @@ enum MaterialType{ struct TileSpec { TileSpec(): - texture(0), + texture_id(0), + texture(NULL), alpha(255), material_type(TILE_MATERIAL_BASIC), material_flags( @@ -207,14 +139,16 @@ struct TileSpec 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 && @@ -268,14 +202,8 @@ struct TileSpec 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