diff --git a/src/inventory.cpp b/src/inventory.cpp
index f91e2e0b6cd6e433e784d7b1b5ad0a18d757e135..47a8d4de90503ed9580bc2724094d08c792d171a 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -118,6 +118,10 @@ bool MaterialItem::isCookable()
 	{
 		return true;
 	}
+	else if(m_content == CONTENT_SAND)
+	{
+		return true;
+	}
 	return false;
 }
 
@@ -131,6 +135,10 @@ InventoryItem *MaterialItem::createCookResult()
 	{
 		return new MaterialItem(CONTENT_STONE, 1);
 	}
+	else if(m_content == CONTENT_SAND)
+	{
+		return new MaterialItem(CONTENT_GLASS, 1);
+	}
 	return NULL;
 }
 
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 67e7e25740bbaf5c01cd5a9f821b4aa6b5ea77b1..58b23bd146e6001d50055a18357c1e1ae308bde7 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -901,6 +901,17 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
 			g_texturesource->getTextureId("leaves.png"));
 	material_leaves1.setTexture(0, pa_leaves1.atlas);
 
+	// Glass material
+	video::SMaterial material_glass;
+	material_glass.setFlag(video::EMF_LIGHTING, false);
+	material_glass.setFlag(video::EMF_BILINEAR_FILTER, false);
+	material_glass.setFlag(video::EMF_FOG_ENABLE, true);
+	material_glass.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+	AtlasPointer pa_glass = g_texturesource->getTexture(
+			g_texturesource->getTextureId("glass.png"));
+	material_glass.setTexture(0, pa_glass.atlas);
+
+
 	for(s16 z=0; z<MAP_BLOCKSIZE; z++)
 	for(s16 y=0; y<MAP_BLOCKSIZE; y++)
 	for(s16 x=0; x<MAP_BLOCKSIZE; x++)
@@ -1406,6 +1417,72 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
 				collector.append(material_leaves1, vertices, 4, indices, 6);
 			}
 		}
+		/*
+			Add glass
+		*/
+		else if(n.d == CONTENT_GLASS)
+		{
+			u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+			video::SColor c(255,l,l,l);
+
+			for(u32 j=0; j<6; j++)
+			{
+				video::S3DVertex vertices[4] =
+				{
+					video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c,
+						pa_glass.x0(), pa_glass.y1()),
+					video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c,
+						pa_glass.x1(), pa_glass.y1()),
+					video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c,
+						pa_glass.x1(), pa_glass.y0()),
+					video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c,
+						pa_glass.x0(), pa_glass.y0()),
+				};
+
+				if(j == 0)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateXZBy(0);
+				}
+				else if(j == 1)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateXZBy(180);
+				}
+				else if(j == 2)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateXZBy(-90);
+				}
+				else if(j == 3)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateXZBy(90);
+				}
+				else if(j == 4)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateYZBy(-90);
+				}
+				else if(j == 5)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateYZBy(90);
+				}
+
+				for(u16 i=0; i<4; i++)
+				{
+					vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
+				}
+
+				u16 indices[] = {0,1,2,2,3,0};
+				// Add to mesh collector
+				collector.append(material_glass, vertices, 4, indices, 6);
+			}
+		}
+
+
+
 	}
 
 	/*
diff --git a/src/mapnode.cpp b/src/mapnode.cpp
index 6deebd56d28417dc82ef0ac4c5dd22f27a2907e7..c27f4848b4358ef41ace137e4000d1c1eebb8fa9 100644
--- a/src/mapnode.cpp
+++ b/src/mapnode.cpp
@@ -204,7 +204,17 @@ void init_mapnode()
 		f->setAllTextures("[noalpha:leaves.png");
 	}
 	f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
-	
+
+	i = CONTENT_GLASS;
+	f = &g_content_features[i];
+	f->light_propagates = true;
+	f->param_type = CPT_LIGHT;
+	f->is_ground_content = true;
+	f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+	f->solidness = 0; // drawn separately, makes no faces
+	f->setInventoryTextureCube("glass.png", "glass.png", "glass.png");
+
+
 	// Deprecated
 	i = CONTENT_COALSTONE;
 	f = &g_content_features[i];
diff --git a/src/mapnode.h b/src/mapnode.h
index d456cf88391cf169ecb0341bc33f7b97fcd75bb7..9ab885386dabae8901c642672b017bfddaec998c 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -99,6 +99,7 @@ void init_content_inventory_texture_paths();
 //#define CONTENT_WORKBENCH 17
 #define CONTENT_COBBLE 18
 #define CONTENT_STEEL 19
+#define CONTENT_GLASS 20
 
 /*
 	Content feature list
diff --git a/src/materials.cpp b/src/materials.cpp
index 2e33abebaf4432485ab6d57f6ce5fdefbabc1cdf..e5f0c3b9e8a6f1cdb0f3778dbfea2d8d9e7fa684 100644
--- a/src/materials.cpp
+++ b/src/materials.cpp
@@ -72,6 +72,7 @@ void initializeMaterialProperties()
 	
 	setWoodLikeDiggingProperties(CONTENT_TREE, 1.0);
 	setWoodLikeDiggingProperties(CONTENT_LEAVES, 0.15);
+	setWoodLikeDiggingProperties(CONTENT_GLASS, 0.15);
 	setWoodLikeDiggingProperties(CONTENT_WOOD, 0.75);
 	setWoodLikeDiggingProperties(CONTENT_CHEST, 1.0);
 
diff --git a/src/server.cpp b/src/server.cpp
index d47dcb9ce1ad9cd46e17cbfda3b187c40bedd2f1..b5a38aa06b6ec34f946337bd920bc9f1a09eecb8 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -3984,6 +3984,7 @@ void setCreativeInventory(Player *player)
 		CONTENT_SAND,
 		CONTENT_TREE,
 		CONTENT_LEAVES,
+		CONTENT_GLASS,
 		CONTENT_MESE,
 		CONTENT_WATERSOURCE,
 		CONTENT_CLOUD,
diff --git a/src/tile.cpp b/src/tile.cpp
index e65e92b7e43601409f5ae89e00ed2572605b859c..5b89c6932e05e40adde0de2db9c02e5f3ebd8546 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -476,6 +476,7 @@ void TextureSource::buildMainAtlas()
 	sourcelist.push_back("tree_top.png");
 	sourcelist.push_back("water.png");
 	sourcelist.push_back("leaves.png");
+	sourcelist.push_back("glass.png");
 	sourcelist.push_back("mud.png^grass_side.png");
 	sourcelist.push_back("cobble.png");