diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index ebcedd5f052..90460287050 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -276,8 +276,7 @@ void RasterizerGLES3::end_frame(){
 
 	canvas->draw_generic_textured_rect(Rect2(0,0,15,15),Rect2(0,0,1,1));
 #endif
-	if (ContextGL::get_singleton())
-		ContextGL::get_singleton()->swap_buffers();
+	OS::get_singleton()->swap_buffers();
 }
 
 void RasterizerGLES3::finalize(){
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 60cbbc9023f..a618953b860 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -3675,57 +3675,157 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() {
 
 /* IMMEDIATE API */
 
-RID RasterizerStorageGLES3::immediate_create(){
 
-	return RID();
+RID RasterizerStorageGLES3::immediate_create() {
+
+	Immediate *im = memnew( Immediate );
+	return immediate_owner.make_rid(im);
+
 }
-void RasterizerStorageGLES3::immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture){
+
+void RasterizerStorageGLES3::immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture){
+
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(im->building);
+
+	Immediate::Chunk ic;
+	ic.texture=p_texture;
+	ic.primitive=p_rimitive;
+	im->chunks.push_back(ic);
+	im->mask=0;
+	im->building=true;
 
 
 }
 void RasterizerStorageGLES3::immediate_vertex(RID p_immediate,const Vector3& p_vertex){
 
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(!im->building);
+
+	Immediate::Chunk *c = &im->chunks.back()->get();
+
+
+	if (c->vertices.empty() && im->chunks.size()==1) {
+
+		im->aabb.pos=p_vertex;
+		im->aabb.size=Vector3();
+	} else {
+		im->aabb.expand_to(p_vertex);
+	}
+
+	if (im->mask&VS::ARRAY_FORMAT_NORMAL)
+		c->normals.push_back(chunk_normal);
+	if (im->mask&VS::ARRAY_FORMAT_TANGENT)
+		c->tangents.push_back(chunk_tangent);
+	if (im->mask&VS::ARRAY_FORMAT_COLOR)
+		c->colors.push_back(chunk_color);
+	if (im->mask&VS::ARRAY_FORMAT_TEX_UV)
+		c->uvs.push_back(chunk_uv);
+	if (im->mask&VS::ARRAY_FORMAT_TEX_UV2)
+		c->uvs2.push_back(chunk_uv2);
+	im->mask|=VS::ARRAY_FORMAT_VERTEX;
+	c->vertices.push_back(p_vertex);
 
 }
-void RasterizerStorageGLES3::immediate_vertex_2d(RID p_immediate,const Vector3& p_vertex){
 
 
-}
 void RasterizerStorageGLES3::immediate_normal(RID p_immediate,const Vector3& p_normal){
 
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(!im->building);
+
+	im->mask|=VS::ARRAY_FORMAT_NORMAL;
+	chunk_normal=p_normal;
 
 }
 void RasterizerStorageGLES3::immediate_tangent(RID p_immediate,const Plane& p_tangent){
 
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(!im->building);
+
+	im->mask|=VS::ARRAY_FORMAT_TANGENT;
+	chunk_tangent=p_tangent;
 
 }
 void RasterizerStorageGLES3::immediate_color(RID p_immediate,const Color& p_color){
 
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(!im->building);
+
+	im->mask|=VS::ARRAY_FORMAT_COLOR;
+	chunk_color=p_color;
 
 }
 void RasterizerStorageGLES3::immediate_uv(RID p_immediate,const Vector2& tex_uv){
 
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(!im->building);
+
+	im->mask|=VS::ARRAY_FORMAT_TEX_UV;
+	chunk_uv=tex_uv;
 
 }
 void RasterizerStorageGLES3::immediate_uv2(RID p_immediate,const Vector2& tex_uv){
 
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(!im->building);
+
+	im->mask|=VS::ARRAY_FORMAT_TEX_UV2;
+	chunk_uv2=tex_uv;
 
 }
+
 void RasterizerStorageGLES3::immediate_end(RID p_immediate){
 
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(!im->building);
+
+	im->building=false;
+
+	im->instance_change_notify();
 
 }
-void RasterizerStorageGLES3::immediate_clear(RID p_immediate){
+void RasterizerStorageGLES3::immediate_clear(RID p_immediate) {
 
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	ERR_FAIL_COND(im->building);
+
+	im->chunks.clear();
+	im->instance_change_notify();
 
 }
-void RasterizerStorageGLES3::immediate_set_material(RID p_immediate,RID p_material){
 
+AABB RasterizerStorageGLES3::immediate_get_aabb(RID p_immediate) const {
+
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND_V(!im,AABB());
+	return im->aabb;
+}
+
+void RasterizerStorageGLES3::immediate_set_material(RID p_immediate,RID p_material) {
+
+	Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND(!im);
+	im->material=p_material;
+	im->instance_material_change_notify();
 
 }
-RID RasterizerStorageGLES3::immediate_get_material(RID p_immediate) const{
 
-	return RID();
+RID RasterizerStorageGLES3::immediate_get_material(RID p_immediate) const {
+
+	const Immediate *im = immediate_owner.get(p_immediate);
+	ERR_FAIL_COND_V(!im,RID());
+	return im->material;
+
 }
 
 /* SKELETON API */
@@ -4417,6 +4517,10 @@ void RasterizerStorageGLES3::instance_add_dependency(RID p_base,RasterizerScene:
 			inst = multimesh_owner.getornull(p_base);
 			ERR_FAIL_COND(!inst);
 		} break;
+		case VS::INSTANCE_IMMEDIATE: {
+			inst = immediate_owner.getornull(p_base);
+			ERR_FAIL_COND(!inst);
+		} break;
 		case VS::INSTANCE_REFLECTION_PROBE: {
 			inst = reflection_probe_owner.getornull(p_base);
 			ERR_FAIL_COND(!inst);
@@ -4452,6 +4556,10 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base,RasterizerSce
 			inst = multimesh_owner.getornull(p_base);
 			ERR_FAIL_COND(!inst);
 		} break;
+		case VS::INSTANCE_IMMEDIATE: {
+			inst = immediate_owner.getornull(p_base);
+			ERR_FAIL_COND(!inst);
+		} break;
 		case VS::INSTANCE_REFLECTION_PROBE: {
 			inst = reflection_probe_owner.getornull(p_base);
 			ERR_FAIL_COND(!inst);
@@ -4949,6 +5057,9 @@ VS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
 	if (multimesh_owner.owns(p_rid)) {
 		return VS::INSTANCE_MULTIMESH;
 	}
+	if (immediate_owner.owns(p_rid)) {
+		return VS::INSTANCE_IMMEDIATE;
+	}
 	if (light_owner.owns(p_rid)) {
 		return VS::INSTANCE_LIGHT;
 	}
@@ -5057,7 +5168,12 @@ bool RasterizerStorageGLES3::free(RID p_rid){
 
 		multimesh_owner.free(p_rid);
 		memdelete(multimesh);
+	} else if (immediate_owner.owns(p_rid)) {
 
+		Immediate *immediate = immediate_owner.get(p_rid);
+
+		immediate_owner.free(p_rid);
+		memdelete(immediate);
 	} else if (light_owner.owns(p_rid)) {
 
 		// delete the texture
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index c6712bd8eac..623962bf611 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -651,10 +651,41 @@ public:
 
 	/* IMMEDIATE API */
 
+	struct Immediate : public Geometry {
+
+		struct Chunk {
+
+			RID texture;
+			VS::PrimitiveType primitive;
+			Vector<Vector3> vertices;
+			Vector<Vector3> normals;
+			Vector<Plane> tangents;
+			Vector<Color> colors;
+			Vector<Vector2> uvs;
+			Vector<Vector2> uvs2;
+		};
+
+		List<Chunk> chunks;
+		bool building;
+		int mask;
+		AABB aabb;
+
+		Immediate() { type=GEOMETRY_IMMEDIATE; building=false;}
+
+	};
+
+	Vector3 chunk_vertex;
+	Vector3 chunk_normal;
+	Plane chunk_tangent;
+	Color chunk_color;
+	Vector2 chunk_uv;
+	Vector2 chunk_uv2;
+
+	mutable RID_Owner<Immediate> immediate_owner;
+
 	virtual RID immediate_create();
 	virtual void immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture=RID());
-	virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex);
-	virtual void immediate_vertex_2d(RID p_immediate,const Vector3& p_vertex);
+	virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex);	
 	virtual void immediate_normal(RID p_immediate,const Vector3& p_normal);
 	virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent);
 	virtual void immediate_color(RID p_immediate,const Color& p_color);
@@ -664,6 +695,7 @@ public:
 	virtual void immediate_clear(RID p_immediate);
 	virtual void immediate_set_material(RID p_immediate,RID p_material);
 	virtual RID immediate_get_material(RID p_immediate) const;
+	virtual AABB immediate_get_aabb(RID p_immediate) const;
 
 	/* SKELETON API */
 
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index e906f9a7909..78f35c493ab 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -222,9 +222,8 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
 	Vector<const char*> strings;
 #ifdef GLES_OVER_GL
 	strings.push_back("#version 330\n");
-	//strings.push_back("#version 300 es\n");
 #else
-	strings.push_back("#version 300 es\n"); //ATI requieres this before anything
+	strings.push_back("#version 300 es\n");
 #endif
 
 
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 08d19957252..5f536b8fd40 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -285,7 +285,6 @@ public:
 	virtual RID immediate_create()=0;
 	virtual void immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture=RID())=0;
 	virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex)=0;
-	virtual void immediate_vertex_2d(RID p_immediate,const Vector3& p_vertex)=0;
 	virtual void immediate_normal(RID p_immediate,const Vector3& p_normal)=0;
 	virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent)=0;
 	virtual void immediate_color(RID p_immediate,const Color& p_color)=0;
@@ -295,6 +294,8 @@ public:
 	virtual void immediate_clear(RID p_immediate)=0;
 	virtual void immediate_set_material(RID p_immediate,RID p_material)=0;
 	virtual RID immediate_get_material(RID p_immediate) const=0;
+	virtual AABB immediate_get_aabb(RID p_immediate) const=0;
+
 
 	/* SKELETON API */
 
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 675e2d4aef3..c3afadb3937 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -731,7 +731,6 @@ public:
 	BIND0R(RID,immediate_create)
 	BIND3(immediate_begin,RID,PrimitiveType,RID)
 	BIND2(immediate_vertex,RID,const Vector3&)
-	BIND2(immediate_vertex_2d,RID,const Vector3&)
 	BIND2(immediate_normal,RID,const Vector3&)
 	BIND2(immediate_tangent,RID,const Plane&)
 	BIND2(immediate_color,RID,const Color&)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index f25e5bc943b..2439eacd756 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -557,12 +557,9 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base){
 
 				instance->base_data=light;
 			} break;
-			case VS::INSTANCE_MESH: {
-
-				InstanceGeometryData *geom = memnew( InstanceGeometryData );
-				instance->base_data=geom;
-			} break;
-			case VS::INSTANCE_MULTIMESH: {
+			case VS::INSTANCE_MESH:
+			case VS::INSTANCE_MULTIMESH:
+			case VS::INSTANCE_IMMEDIATE: {
 
 				InstanceGeometryData *geom = memnew( InstanceGeometryData );
 				instance->base_data=geom;
@@ -1147,13 +1144,14 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) {
 			new_aabb = VSG::storage->multimesh_get_aabb(p_instance->base);
 
 		} break;
-#if 0
 		case VisualServer::INSTANCE_IMMEDIATE: {
 
-			new_aabb = rasterizer->immediate_get_aabb(p_instance->base);
+			new_aabb = VSG::storage->immediate_get_aabb(p_instance->base);
 
 
 		} break;
+#if 0
+
 		case VisualServer::INSTANCE_PARTICLES: {
 
 			new_aabb = rasterizer->particles_get_aabb(p_instance->base);
@@ -2309,6 +2307,17 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
 							can_cast_shadows=false;
 						}
 					}
+				} else if (p_instance->base_type==VS::INSTANCE_IMMEDIATE) {
+
+					RID mat = VSG::storage->immediate_get_material(p_instance->base);
+
+					if (!mat.is_valid() || VSG::storage->material_casts_shadows(mat)) {
+						can_cast_shadows=true;
+					} else {
+						can_cast_shadows=false;
+					}
+
+
 				}
 
 
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 30d6b76b8e5..27b08c4c500 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1648,6 +1648,10 @@ void VisualServer::mesh_add_surface_from_planes( RID p_mesh, const DVector<Plane
 
 }
 
+void VisualServer::immediate_vertex_2d(RID p_immediate,const Vector2& p_vertex) {
+	immediate_vertex(p_immediate,Vector3(p_vertex.x,p_vertex.y,0));
+}
+
 RID VisualServer::instance_create2(RID p_base, RID p_scenario) {
 
 	RID instance = instance_create();
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 7d561bee38e..0fd0733727d 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -319,7 +319,7 @@ public:
 	virtual RID immediate_create()=0;
 	virtual void immediate_begin(RID p_immediate,PrimitiveType p_rimitive,RID p_texture=RID())=0;
 	virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex)=0;
-	virtual void immediate_vertex_2d(RID p_immediate,const Vector3& p_vertex)=0;
+	virtual void immediate_vertex_2d(RID p_immediate,const Vector2& p_vertex);
 	virtual void immediate_normal(RID p_immediate,const Vector3& p_normal)=0;
 	virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent)=0;
 	virtual void immediate_color(RID p_immediate,const Color& p_color)=0;