diff --git a/ground/openpilotgcs/src/libs/glc_lib/.gitignore b/ground/openpilotgcs/src/libs/glc_lib/.gitignore
new file mode 100644
index 000000000..e2f6ef3be
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/.gitignore
@@ -0,0 +1 @@
+/qrc_glc_lib.cpp
diff --git a/ground/openpilotgcs/src/libs/glc_lib/3rdparty/lib3ds/light.c b/ground/openpilotgcs/src/libs/glc_lib/3rdparty/lib3ds/light.c
index 2eee44859..311f1d623 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/3rdparty/lib3ds/light.c
+++ b/ground/openpilotgcs/src/libs/glc_lib/3rdparty/lib3ds/light.c
@@ -30,6 +30,8 @@
 /*!
  * \defgroup light Lights
  */
+/*!
+
 
 /*!
  * \ingroup light
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_3drep.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_3drep.cpp
index 98908afe4..387abe5bb 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_3drep.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_3drep.cpp
@@ -28,7 +28,6 @@
 // Class chunk id
 quint32 GLC_3DRep::m_ChunkId= 0xA702;
 
-// Default constructor
 GLC_3DRep::GLC_3DRep()
 : GLC_Rep()
 , m_pGeomList(new QList<GLC_Geometry*>)
@@ -37,7 +36,6 @@ GLC_3DRep::GLC_3DRep()
 
 }
 
-// Construct a 3DRep with a geometry
 GLC_3DRep::GLC_3DRep(GLC_Geometry* pGeom)
 : GLC_Rep()
 , m_pGeomList(new QList<GLC_Geometry*>)
@@ -48,7 +46,6 @@ GLC_3DRep::GLC_3DRep(GLC_Geometry* pGeom)
 	setName(pGeom->name());
 }
 
-// Copy Constructor
 GLC_3DRep::GLC_3DRep(const GLC_3DRep& rep)
 : GLC_Rep(rep)
 , m_pGeomList(rep.m_pGeomList)
@@ -57,7 +54,6 @@ GLC_3DRep::GLC_3DRep(const GLC_3DRep& rep)
 
 }
 
-// Assignement operator
 GLC_3DRep& GLC_3DRep::operator=(const GLC_Rep& rep)
 {
 	const GLC_3DRep* p3DRep= dynamic_cast<const GLC_3DRep*>(&rep);
@@ -73,13 +69,11 @@ GLC_3DRep& GLC_3DRep::operator=(const GLC_Rep& rep)
 	return *this;
 }
 
-// Clone the representation
 GLC_Rep* GLC_3DRep::clone() const
 {
 	return new GLC_3DRep(*this);
 }
 
-// Make a deep copy of the 3DRep
 GLC_Rep* GLC_3DRep::deepCopy() const
 {
 	GLC_3DRep* pCloneRep= new GLC_3DRep;
@@ -95,7 +89,6 @@ GLC_Rep* GLC_3DRep::deepCopy() const
 	return pCloneRep;
 }
 
-// Destructor
 GLC_3DRep::~GLC_3DRep()
 {
 	clear();
@@ -104,13 +97,11 @@ GLC_3DRep::~GLC_3DRep()
 //////////////////////////////////////////////////////////////////////
 // Get functions
 //////////////////////////////////////////////////////////////////////
-// Return the class Chunk ID
 quint32 GLC_3DRep::chunckID()
 {
 	return m_ChunkId;
 }
 
-// Return the type of representation
 int GLC_3DRep::type() const
 {
 	return (*m_pType);
@@ -120,7 +111,6 @@ int GLC_3DRep::type() const
 // Get functions
 //////////////////////////////////////////////////////////////////////
 
-// Return true if the rep bounding box is valid
 bool GLC_3DRep::boundingBoxIsValid() const
 {
 	bool result= !m_pGeomList->isEmpty();
@@ -134,7 +124,6 @@ bool GLC_3DRep::boundingBoxIsValid() const
 	return result;
 }
 
-// Return the 3DRep bounding Box
 GLC_BoundingBox GLC_3DRep::boundingBox() const
 {
 	GLC_BoundingBox resultBox;
@@ -146,7 +135,6 @@ GLC_BoundingBox GLC_3DRep::boundingBox() const
 	return resultBox;
 }
 
-// Get number of faces
 unsigned int GLC_3DRep::faceCount() const
 {
 	unsigned int result= 0;
@@ -162,7 +150,6 @@ unsigned int GLC_3DRep::faceCount() const
 	return result;
 }
 
-// Get number of vertex
 unsigned int GLC_3DRep::vertexCount() const
 {
 	unsigned int result= 0;
@@ -178,7 +165,6 @@ unsigned int GLC_3DRep::vertexCount() const
 	return result;
 }
 
-// Get number of materials
 unsigned int GLC_3DRep::materialCount() const
 {
 	unsigned int result= 0;
@@ -194,7 +180,6 @@ unsigned int GLC_3DRep::materialCount() const
 	return result;
 }
 
-// Get materials List
 QSet<GLC_Material*> GLC_3DRep::materialSet() const
 {
 	QSet<GLC_Material*> result;
@@ -210,7 +195,18 @@ QSet<GLC_Material*> GLC_3DRep::materialSet() const
 	return result;
 }
 
-// Remove empty geometries
+double GLC_3DRep::volume() const
+{
+	double resultVolume= 0.0;
+	const int geomCount= m_pGeomList->count();
+	for (int i= 0; i < geomCount; ++i)
+	{
+		resultVolume+= m_pGeomList->at(i)->volume();
+	}
+
+	return resultVolume;
+}
+
 void GLC_3DRep::clean()
 {
 	QList<GLC_Geometry*>::iterator iGeomList= m_pGeomList->begin();
@@ -229,7 +225,6 @@ void GLC_3DRep::clean()
 	}
 }
 
-// Reverse geometries normals
 void GLC_3DRep::reverseNormals()
 {
 	const int size= m_pGeomList->size();
@@ -239,7 +234,6 @@ void GLC_3DRep::reverseNormals()
 	}
 }
 
-// Load the representation
 bool GLC_3DRep::load()
 {
 	bool loadSucces= false;
@@ -274,7 +268,7 @@ bool GLC_3DRep::load()
 	return loadSucces;
 
 }
-// Replace the representation
+
 void GLC_3DRep::replace(GLC_Rep* pRep)
 {
 	GLC_3DRep* p3DRep= dynamic_cast<GLC_3DRep*>(pRep);
@@ -295,7 +289,6 @@ void GLC_3DRep::replace(GLC_Rep* pRep)
 	}
 }
 
-// Replace the specified material by a new one
 void GLC_3DRep::replaceMaterial(GLC_uint oldId, GLC_Material* pNewMaterial)
 {
 	//qDebug() << "GLC_3DRep::replaceMaterial";
@@ -315,7 +308,6 @@ void GLC_3DRep::replaceMaterial(GLC_uint oldId, GLC_Material* pNewMaterial)
 	}
 }
 
-// Merge this 3Drep with another 3DRep
 void GLC_3DRep::merge(const GLC_3DRep* pRep)
 {
 	// Get the number of geometry of pRep
@@ -361,7 +353,6 @@ void GLC_3DRep::transformSubGeometries(const GLC_Matrix4x4& matrix)
 {
 	// Get the number of geometry of pRep
 	const int repCount= m_pGeomList->size();
-	qDebug() << "repCount " << repCount;
 	for (int i= 0; i < repCount; ++i)
 	{
 		GLC_Mesh* pCurrentMesh= dynamic_cast<GLC_Mesh*>(geomAt(i));
@@ -372,7 +363,16 @@ void GLC_3DRep::transformSubGeometries(const GLC_Matrix4x4& matrix)
 	}
 }
 
-// UnLoad the representation
+void GLC_3DRep::setVboUsage(bool usage)
+{
+	// Get the number of geometry of pRep
+	const int repCount= m_pGeomList->size();
+	for (int i= 0; i < repCount; ++i)
+	{
+		m_pGeomList->at(i)->setVboUsage(usage);
+	}
+}
+
 bool GLC_3DRep::unload()
 {
 	bool unloadSucess= false;
@@ -404,7 +404,6 @@ bool GLC_3DRep::unload()
 // private services functions
 //////////////////////////////////////////////////////////////////////
 
-// Clear the 3D representation
 void GLC_3DRep::clear()
 {
 	if (isTheLast())
@@ -422,7 +421,6 @@ void GLC_3DRep::clear()
 	}
 }
 // Non Member methods
-// Non-member stream operator
 QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep)
 {
 	quint32 chunckId= GLC_3DRep::m_ChunkId;
@@ -457,6 +455,7 @@ QDataStream &operator<<(QDataStream & stream, const GLC_3DRep & rep)
 
 	return stream;
 }
+
 QDataStream &operator>>(QDataStream & stream, GLC_3DRep & rep)
 {
 	Q_ASSERT(rep.isEmpty());
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_3drep.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_3drep.h
index 5da9a1ccc..27c6f4038 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_3drep.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_3drep.h
@@ -121,6 +121,9 @@ public:
 	//! Return materials Set of this 3DRep
 	QSet<GLC_Material*> materialSet() const;
 
+	//! Return the volume of this 3DRep
+	double volume() const;
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -168,6 +171,8 @@ public:
 	//! Transform 3DRep sub mesh vertice with the given matrix
 	void transformSubGeometries(const GLC_Matrix4x4& matrix);
 
+	//! Set VBO usage
+	void setVboUsage(bool usage);
 
 //@}
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_box.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_box.cpp
index 540509f0a..2b6e510a2 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_box.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_box.cpp
@@ -36,7 +36,7 @@ GLC_Box::GLC_Box(double dLx, double dLy, double dlz)
 , m_dLgY(dLy)
 , m_dLgZ(dlz)
 {
-
+	createMeshAndWire();
 }
 // Copy constructor
 GLC_Box::GLC_Box(const GLC_Box& box)
@@ -45,7 +45,7 @@ GLC_Box::GLC_Box(const GLC_Box& box)
 , m_dLgY(box.m_dLgY)
 , m_dLgZ(box.m_dLgZ)
 {
-
+	createMeshAndWire();
 }
 GLC_Box::~GLC_Box()
 {
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_bsrep.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_bsrep.cpp
index 82c208774..edfc9ffb9 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_bsrep.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_bsrep.cpp
@@ -32,7 +32,7 @@ const QString GLC_BSRep::m_Suffix("BSRep");
 const QUuid GLC_BSRep::m_Uuid("{d6f97789-36a9-4c2e-b667-0e66c27f839f}");
 
 // The binary rep version
-const quint32 GLC_BSRep::m_Version= 102;
+const quint32 GLC_BSRep::m_Version= 103;
 
 // Mutex used by compression
 QMutex GLC_BSRep::m_CompressionMutex;
@@ -181,6 +181,11 @@ QString GLC_BSRep::suffix()
 	return m_Suffix;
 }
 
+quint32 GLC_BSRep::version()
+{
+	return m_Version;
+}
+
 //////////////////////////////////////////////////////////////////////
 //name Set Functions
 //////////////////////////////////////////////////////////////////////
@@ -322,7 +327,7 @@ bool GLC_BSRep::headerIsOk()
 	// Set the version of the data stream
 	m_DataStream.setVersion(QDataStream::Qt_4_6);
 
-	bool headerOk= (uuid == m_Uuid) && (version == m_Version) && writeFinished;
+	bool headerOk= (uuid == m_Uuid) && (version <= m_Version) && (version > 101) && writeFinished;
 
 	return headerOk;
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_bsrep.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_bsrep.h
index 3c6923588..f1dbe4955 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_bsrep.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_bsrep.h
@@ -75,6 +75,9 @@ public:
 
 	//! Return bsrep suffix
 	static QString suffix();
+
+	//! Return bsrep version
+	static quint32 version();
 //@}
 
 //////////////////////////////////////////////////////////////////////
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_cone.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_cone.cpp
index a0cb882fa..78b540341 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_cone.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_cone.cpp
@@ -33,6 +33,7 @@ GLC_Cone::GLC_Cone(double dRadius, double dLength)
 , m_Discret(glc::GLC_POLYDISCRET)	// Default discretion
 {
 	Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0));
+	createMeshAndWire();
 }
 
 GLC_Cone::GLC_Cone(const GLC_Cone& sourceCone)
@@ -41,7 +42,7 @@ GLC_Cone::GLC_Cone(const GLC_Cone& sourceCone)
 , m_Length(sourceCone.m_Length)
 , m_Discret(sourceCone.m_Discret)
 {
-
+	createMeshAndWire();
 }
 
 GLC_Cone::~GLC_Cone()
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_cylinder.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_cylinder.cpp
index 16c90cd88..be33e93fb 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_cylinder.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_cylinder.cpp
@@ -44,6 +44,7 @@ GLC_Cylinder::GLC_Cylinder(double dRadius, double dLength)
 , m_EndedIsCaped(true)			// Cylinder ended are closed
 {
 	Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0));
+	createMeshAndWire();
 }
 
 GLC_Cylinder::GLC_Cylinder(const GLC_Cylinder& sourceCylinder)
@@ -54,6 +55,7 @@ GLC_Cylinder::GLC_Cylinder(const GLC_Cylinder& sourceCylinder)
 , m_EndedIsCaped(sourceCylinder.m_EndedIsCaped)
 {
 	Q_ASSERT((m_Radius > 0.0) && (m_Length > 0.0) && (m_Discret > 0));
+	createMeshAndWire();
 
 }
 GLC_Cylinder::~GLC_Cylinder()
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_disc.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_disc.cpp
index 69420d439..66983437b 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_disc.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_disc.cpp
@@ -30,7 +30,7 @@ GLC_Disc::GLC_Disc(double radius, double angle)
 , m_Angle(angle)
 , m_Step(0)
 {
-
+	createMeshAndWire();
 }
 
 GLC_Disc::GLC_Disc(const GLC_Disc& disc)
@@ -40,7 +40,7 @@ GLC_Disc::GLC_Disc(const GLC_Disc& disc)
 , m_Angle(disc.m_Angle)
 , m_Step(disc.m_Step)
 {
-
+	createMeshAndWire();
 }
 
 GLC_Disc::~GLC_Disc()
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_geometry.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_geometry.cpp
index 24ab7030f..77880818c 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_geometry.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_geometry.cpp
@@ -25,6 +25,7 @@
 #include "../shading/glc_selectionmaterial.h"
 #include "../glc_openglexception.h"
 #include "../glc_state.h"
+#include "../glc_context.h"
 #include "glc_geometry.h"
 
 //////////////////////////////////////////////////////////////////////
@@ -44,6 +45,7 @@ GLC_Geometry::GLC_Geometry(const QString& name, const bool typeIsWire)
 , m_TransparentMaterialNumber(0)
 , m_Id(glc::GLC_GenGeomID())
 , m_Name(name)
+, m_UseVbo(false)
 {
 
 }
@@ -61,6 +63,7 @@ GLC_Geometry::GLC_Geometry(const GLC_Geometry& sourceGeom)
 , m_TransparentMaterialNumber(sourceGeom.m_TransparentMaterialNumber)
 , m_Id(glc::GLC_GenGeomID())
 , m_Name(sourceGeom.m_Name)
+, m_UseVbo(sourceGeom.m_UseVbo)
 {
 	// Add this mesh to inner material
 	MaterialHash::const_iterator i= sourceGeom.m_MaterialHash.constBegin();
@@ -95,6 +98,7 @@ GLC_Geometry& GLC_Geometry::operator=(const GLC_Geometry& sourceGeom)
 		m_TransparentMaterialNumber= sourceGeom.m_TransparentMaterialNumber;
 		m_Id= glc::GLC_GenGeomID();
 		m_Name= sourceGeom.m_Name;
+		m_UseVbo= sourceGeom.m_UseVbo;
 	}
 	return *this;
 }
@@ -134,6 +138,11 @@ unsigned int GLC_Geometry::VertexCount() const
 	return 0;
 }
 
+double GLC_Geometry::volume()
+{
+	return 0.0;
+}
+
 /////////////////////////////////////////////////////////////////////
 // Set Functions
 //////////////////////////////////////////////////////////////////////
@@ -179,7 +188,6 @@ void GLC_Geometry::updateTransparentMaterialNumber()
 	}
 	if (m_WireColor.alpha() != 255)
 	{
-		qDebug() << "GLC_Geometry::updateTransparentMaterialNumber()";
 		++m_TransparentMaterialNumber;
 	}
 }
@@ -187,8 +195,6 @@ void GLC_Geometry::updateTransparentMaterialNumber()
 // Add material to mesh
 void GLC_Geometry::addMaterial(GLC_Material* pMaterial)
 {
-	Q_ASSERT(!m_IsWire);
-
 	if (pMaterial != NULL)
 	{
 		const GLC_uint materialID= pMaterial->id();
@@ -234,6 +240,15 @@ void GLC_Geometry::releaseVboClientSide(bool update)
 	m_WireData.releaseVboClientSide(update);
 }
 
+void GLC_Geometry::setVboUsage(bool usage)
+{
+	m_UseVbo= usage;
+	if (!usage || (usage && GLC_State::vboSupported()))
+	{
+		m_WireData.setVboUsage(m_UseVbo);
+	}
+}
+
 //////////////////////////////////////////////////////////////////////
 // OpenGL Functions
 //////////////////////////////////////////////////////////////////////
@@ -283,7 +298,7 @@ void GLC_Geometry::render(const GLC_RenderProperties& renderProperties)
 		GLenum error= glGetError();
 		if (error != GL_NO_ERROR)
 		{
-			GLC_OpenGlException OpenGlException("GLC_Geometry::glExecute " + name(), error);
+			GLC_OpenGlException OpenGlException("GLC_Geometry::render " + name(), error);
 			throw(OpenGlException);
 		}
 	}
@@ -297,7 +312,7 @@ void GLC_Geometry::glPropGeom(const GLC_RenderProperties& renderProperties)
 	if(m_IsWire)
 	{
 		glLineWidth(m_LineWidth);
-		glDisable(GL_LIGHTING);
+		GLC_Context::current()->glcEnableLighting(false);;
 		if (!renderProperties.isSelected())
 		{
 			// Set polyline colors
@@ -318,13 +333,13 @@ void GLC_Geometry::glPropGeom(const GLC_RenderProperties& renderProperties)
 		GLC_Material* pCurrentMaterial= m_MaterialHash.begin().value();
 		if (pCurrentMaterial->hasTexture())
 		{
-			glEnable(GL_LIGHTING);
+			GLC_Context::current()->glcEnableLighting(true);
 			pCurrentMaterial->glExecute();
 			if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
 		}
 		else
 		{
-			glEnable(GL_LIGHTING);
+			GLC_Context::current()->glcEnableLighting(true);
 			if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
 			else pCurrentMaterial->glExecute();
 		}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_geometry.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_geometry.h
index 2d40a5b3f..ee35cba5b 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_geometry.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_geometry.h
@@ -29,7 +29,7 @@
 #include "glc_wiredata.h"
 #include "../glc_boundingbox.h"
 
-#include "glc_config.h"
+#include "../glc_config.h"
 
 typedef QHash<GLC_uint, GLC_Material*> MaterialHash;
 typedef QHash<GLC_uint, GLC_uint> MaterialHashMap;
@@ -68,19 +68,13 @@ class GLC_LIB_EXPORT GLC_Geometry
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Default constructor
-	/*!
-	 * QString Name
-	 * const bool typeIsWire
-	 */
-	GLC_Geometry(const QString &, const bool);
+	GLC_Geometry(const QString &name, const bool type);
+
 	//! Copy constructor
-	/*!
-	 * const GLC_VboGeom geometry to copy
-	 */
-	GLC_Geometry(const GLC_Geometry&);
+	GLC_Geometry(const GLC_Geometry& sourceGeom);
 
 	//! Overload "=" operator
-	GLC_Geometry& operator=(const GLC_Geometry&);
+	GLC_Geometry& operator=(const GLC_Geometry& sourceGeom);
 
 	//! Destructor
 	virtual ~GLC_Geometry();
@@ -197,6 +191,13 @@ public:
 	inline GLsizei wirePolylineSize(int index) const
 	{return m_WireData.verticeGroupSize(index);}
 
+	//! Return the volume of this geometry
+	virtual double volume();
+
+	//! Return true if this geometry will try to use VBO
+	inline bool vboIsUsed() const
+	{return m_UseVbo;}
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -259,6 +260,9 @@ public:
 	//! Release client VBO
 	virtual void releaseVboClientSide(bool update= false);
 
+	//! Set VBO usage
+	virtual void setVboUsage(bool usage);
+
 //@}
 //////////////////////////////////////////////////////////////////////
 /*! \name OpenGL Functions*/
@@ -357,6 +361,9 @@ private:
 
 	//! Name of geometry
 	QString m_Name;
+
+	//! VBO usage flag
+	bool m_UseVbo;
 };
 
 #endif /*GLC_GEOMETRY_H_*/
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_line.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_line.cpp
index 1fc0e234d..78c0d32b8 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_line.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_line.cpp
@@ -28,19 +28,19 @@
 //////////////////////////////////////////////////////////////////////
 
 GLC_Line::GLC_Line(const GLC_Point3d & point1, const GLC_Point3d & point2)
-: GLC_Geometry("Line", true)
+: GLC_Polylines()
 , m_Point1(point1)
 , m_Point2(point2)
 {
-
+	createWire();
 }
 
 GLC_Line::GLC_Line(const GLC_Line& line)
-: GLC_Geometry(line)
+: GLC_Polylines(line)
 , m_Point1(line.m_Point1)
 , m_Point2(line.m_Point2)
 {
-
+	createWire();
 }
 
 GLC_Line::~GLC_Line()
@@ -54,15 +54,7 @@ GLC_Line::~GLC_Line()
 
 const GLC_BoundingBox& GLC_Line::boundingBox(void)
 {
-
-	if (NULL == m_pBoundingBox)
-	{
-		m_pBoundingBox= new GLC_BoundingBox();
-
-		m_pBoundingBox->combine(m_Point1);
-		m_pBoundingBox->combine(m_Point2);
-	}
-	return *m_pBoundingBox;
+	return GLC_Polylines::boundingBox();
 }
 
 GLC_Geometry* GLC_Line::clone() const
@@ -74,32 +66,44 @@ GLC_Geometry* GLC_Line::clone() const
 //////////////////////////////////////////////////////////////////////
 // Set Functions
 //////////////////////////////////////////////////////////////////////
-void GLC_Line::setColor(const QColor& color)
+void GLC_Line::setCoordinate(const GLC_Point3d &point1, const GLC_Point3d &point2)
 {
-	m_WireColor= color;
-	if (GLC_Geometry::hasMaterial())
-	{
-		GLC_Geometry::firstMaterial()->setDiffuseColor(color);
-	}
+	m_Point1= point1;
+	m_Point2= point2;
+	clear();
+	createWire();
 }
+
+GLC_Line& GLC_Line::operator=(const GLC_Line& line)
+{
+	if (this != &line)
+	{
+		m_Point1= line.m_Point1;
+		m_Point2= line.m_Point2;
+		GLC_Polylines::operator=(line);
+	}
+	return *this;
+}
+
 //////////////////////////////////////////////////////////////////////
 // OpenGL Functions
 //////////////////////////////////////////////////////////////////////
 
-void GLC_Line::glDraw(const GLC_RenderProperties&)
+void GLC_Line::glDraw(const GLC_RenderProperties& renderProperties)
 {
-	// Point Display
-	glBegin(GL_LINES);
-		glVertex3dv(m_Point1.data());
-		glVertex3dv(m_Point2.data());
-	glEnd();
-
-	// OpenGL error handler
-	GLenum error= glGetError();
-	if (error != GL_NO_ERROR)
-	{
-		GLC_OpenGlException OpenGlException("GLC_Line::GlDraw ", error);
-		throw(OpenGlException);
-	}
+	GLC_Polylines::glDraw(renderProperties);
 }
 
+
+//////////////////////////////////////////////////////////////////////
+// Private services Functions
+//////////////////////////////////////////////////////////////////////
+void  GLC_Line::createWire()
+{
+	QList<GLC_Point3d> points;
+	points.append(m_Point1);
+	points.append(m_Point2);
+	GLC_Polylines::addPolyline(points);
+}
+
+
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_line.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_line.h
index b2d527903..7091d6e0a 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_line.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_line.h
@@ -23,7 +23,7 @@
 #ifndef GLC_LINE_H_
 #define GLC_LINE_H_
 
-#include "glc_geometry.h"
+#include "glc_polylines.h"
 
 #include "../glc_config.h"
 
@@ -34,7 +34,7 @@
 /*! An GLC_Line is just a simple renderable 3D Line*/
 //////////////////////////////////////////////////////////////////////
 
-class GLC_LIB_EXPORT GLC_Line : public GLC_Geometry
+class GLC_LIB_EXPORT GLC_Line : public GLC_Polylines
 {
 //////////////////////////////////////////////////////////////////////
 /*! @name Constructor / Destructor */
@@ -79,12 +79,15 @@ public:
 //@{
 //////////////////////////////////////////////////////////////////////
 public:
-	//! Set Line coordinate by 4D point
-	void setCoordinate(const GLC_Point3d &, const GLC_Point3d &);
+	//! Set Line coordinate by 3D point
+	void setCoordinate(const GLC_Point3d &point1, const GLC_Point3d &point2);
 
-	//! Set this line color
-	inline void setColor(const QColor& color);
+	//! Clear the content of this line Data and makes it empty
+	inline void clear()
+	{GLC_Polylines::clear();}
 
+	//! Set this line from the given line and return a reference of this line
+	GLC_Line& operator=(const GLC_Line& line);
 
 //@}
 
@@ -100,6 +103,16 @@ private:
 
 //@}
 
+//////////////////////////////////////////////////////////////////////
+/*! \name Private services Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+private:
+	//! Create the wire
+	void createWire();
+
+//@}
+
 //////////////////////////////////////////////////////////////////////
 // Private Member
 //////////////////////////////////////////////////////////////////////
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_lod.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_lod.cpp
index ec6f4deeb..050ff1a09 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_lod.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_lod.cpp
@@ -22,7 +22,7 @@
 
 //! \file glc_lod.cpp implementation of the GLC_Lod class.
 
-
+#include "../glc_exception.h"
 #include "glc_lod.h"
 
 // Class chunk id
@@ -31,7 +31,7 @@ quint32 GLC_Lod::m_ChunkId= 0xA708;
 
 GLC_Lod::GLC_Lod()
 : m_Accuracy(0.0)
-, m_IboId(0)
+, m_IndexBuffer(QGLBuffer::IndexBuffer)
 , m_IndexVector()
 , m_IndexSize(0)
 , m_TrianglesCount(0)
@@ -42,7 +42,7 @@ GLC_Lod::GLC_Lod()
 
 GLC_Lod::GLC_Lod(double accuracy)
 : m_Accuracy(accuracy)
-, m_IboId(0)
+, m_IndexBuffer(QGLBuffer::IndexBuffer)
 , m_IndexVector()
 , m_IndexSize(0)
 , m_TrianglesCount(0)
@@ -53,7 +53,7 @@ GLC_Lod::GLC_Lod(double accuracy)
 
 GLC_Lod::GLC_Lod(const GLC_Lod& lod)
 : m_Accuracy(lod.m_Accuracy)
-, m_IboId(0)
+, m_IndexBuffer(QGLBuffer::IndexBuffer)
 , m_IndexVector(lod.indexVector())
 , m_IndexSize(lod.m_IndexSize)
 , m_TrianglesCount(lod.m_TrianglesCount)
@@ -68,7 +68,7 @@ GLC_Lod& GLC_Lod::operator=(const GLC_Lod& lod)
 	if (this != &lod)
 	{
 		m_Accuracy= lod.m_Accuracy;
-		m_IboId= 0;
+		m_IndexBuffer.destroy();
 		m_IndexVector= lod.indexVector();
 		m_IndexSize= lod.m_IndexSize;
 		m_TrianglesCount= lod.m_TrianglesCount;
@@ -79,11 +79,7 @@ GLC_Lod& GLC_Lod::operator=(const GLC_Lod& lod)
 
 GLC_Lod::~GLC_Lod()
 {
-	// Delete IBO
-	if (0 != m_IboId)
-	{
-		glDeleteBuffers(1, &m_IboId);
-	}
+
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -98,18 +94,18 @@ quint32 GLC_Lod::chunckID()
 
 QVector<GLuint> GLC_Lod::indexVector() const
 {
-	if (0 != m_IboId)
+	if (m_IndexBuffer.isCreated())
 	{
 		// VBO created get data from VBO
 		const int sizeOfIbo= m_IndexSize;
 		const GLsizeiptr dataSize= sizeOfIbo * sizeof(GLuint);
 		QVector<GLuint> indexVector(sizeOfIbo);
 
-		useIBO();
-		GLvoid* pIbo = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY);
+		const_cast<QGLBuffer&>(m_IndexBuffer).bind();
+		GLvoid* pIbo = const_cast<QGLBuffer&>(m_IndexBuffer).map(QGLBuffer::ReadOnly);
 		memcpy(indexVector.data(), pIbo, dataSize);
-		glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
-		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+		const_cast<QGLBuffer&>(m_IndexBuffer).unmap();
+		const_cast<QGLBuffer&>(m_IndexBuffer).release();
 		return indexVector;
 	}
 	else
@@ -121,7 +117,7 @@ QVector<GLuint> GLC_Lod::indexVector() const
 
 void GLC_Lod::copyIboToClientSide()
 {
-	if ((0 != m_IboId) && (m_IndexVector.isEmpty()))
+	if (m_IndexBuffer.isCreated() && (m_IndexVector.isEmpty()))
 	{
 		m_IndexVector= indexVector();
 	}
@@ -130,22 +126,57 @@ void GLC_Lod::copyIboToClientSide()
 
 void GLC_Lod::releaseIboClientSide(bool update)
 {
-	if((0 != m_IboId) && !m_IndexVector.isEmpty())
+	if(m_IndexBuffer.isCreated() && !m_IndexVector.isEmpty())
 	{
 		if (update)
 		{
 			// Copy index from client side to serveur
-			useIBO();
+			m_IndexBuffer.bind();
 
 			const GLsizei indexNbr= static_cast<GLsizei>(m_IndexVector.size());
 			const GLsizeiptr indexSize = indexNbr * sizeof(GLuint);
-			glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, m_IndexVector.data(), GL_STATIC_DRAW);
-			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+			m_IndexBuffer.allocate(m_IndexVector.data(), indexSize);
+			m_IndexBuffer.release();
 		}
+		m_IndexSize= m_IndexVector.size();
 		m_IndexVector.clear();
 	}
 }
 
+void GLC_Lod::setIboUsage(bool usage)
+{
+	if (usage && !m_IndexVector.isEmpty())
+	{
+		createIBO();
+		// Copy index from client side to serveur
+		m_IndexBuffer.bind();
+
+		const GLsizei indexNbr= static_cast<GLsizei>(m_IndexVector.size());
+		const GLsizeiptr indexSize = indexNbr * sizeof(GLuint);
+		m_IndexBuffer.allocate(m_IndexVector.data(), indexSize);
+		m_IndexBuffer.release();
+
+		m_IndexSize= m_IndexVector.size();
+		m_IndexVector.clear();
+
+	}
+	else if (!usage && m_IndexBuffer.isCreated())
+	{
+		m_IndexVector= indexVector();
+		m_IndexBuffer.destroy();
+	}
+}
+
+void GLC_Lod::useIBO() const
+{
+	Q_ASSERT(m_IndexBuffer.isCreated());
+	if (!const_cast<QGLBuffer&>(m_IndexBuffer).bind())
+	{
+		GLC_Exception exception("GLC_Lod::useIBO  Failed to bind index buffer");
+		throw(exception);
+	}
+}
+
 
 QDataStream &operator<<(QDataStream &stream, const GLC_Lod &lod)
 {
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_lod.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_lod.h
index 3ff4c18a0..02856a737 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_lod.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_lod.h
@@ -26,6 +26,8 @@
 #define GLC_LOD_H_
 
 #include <QVector>
+#include <QGLBuffer>
+
 #include "../glc_ext.h"
 
 #include "../glc_config.h"
@@ -88,7 +90,7 @@ public:
 	 * - Triangles Fans index
 	 */
 	inline QVector<GLuint>* indexVectorHandle()
-	{ return &m_IndexVector;}
+	{return &m_IndexVector;}
 
 	//! Return the size of the index Vector
 	inline int indexVectorSize() const
@@ -111,12 +113,6 @@ public:
 	//! Release client IBO
 	void releaseIboClientSide(bool update= false);
 
-	//! The mesh wich use this lod is finished
-	inline void finishVbo()
-	{
-		m_IndexSize= m_IndexVector.size();
-		m_IndexVector.clear();
-	}
 	//! Set accuracy of the LOD
 	inline void setAccuracy(const double& accuracy)
 	{m_Accuracy= accuracy;}
@@ -127,6 +123,9 @@ public:
 		m_TrianglesCount+= count;
 	}
 
+	//! Set IBO usage
+	void setIboUsage(bool usage);
+
 
 //@}
 
@@ -138,15 +137,18 @@ public:
 	//! IBO creation
 	inline void createIBO()
 	{
-		if (0 == m_IboId && !m_IndexVector.isEmpty())
+		if (!m_IndexBuffer.isCreated() && !m_IndexVector.isEmpty())
 		{
-			glGenBuffers(1, &m_IboId);
+			m_IndexBuffer.create();
 		}
 	}
 
 	//! Ibo Usage
-	inline void useIBO() const
-	{glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IboId);}
+	void useIBO() const;
+
+	//! Fill IBO
+	inline void fillIbo()
+	{releaseIboClientSide(true);}
 
 //@}
 
@@ -158,8 +160,8 @@ private:
 	//! The accuracy of the LOD
 	double m_Accuracy;
 
-	//! The IBO ID
-	GLuint m_IboId;
+	//! The Index Buffer
+	QGLBuffer m_IndexBuffer;
 
 	//! The Index Vector
 	QVector<GLuint> m_IndexVector;
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_mesh.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_mesh.cpp
index 25fd6e755..caa5d550c 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_mesh.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_mesh.cpp
@@ -24,6 +24,7 @@
 
 #include "glc_mesh.h"
 #include "../glc_renderstatistics.h"
+#include "../glc_context.h"
 
 // Class chunk id
 quint32 GLC_Mesh::m_ChunkId= 0xA701;
@@ -167,7 +168,7 @@ const GLC_BoundingBox& GLC_Mesh::boundingBox()
 
 		if (m_MeshData.positionVectorHandle()->isEmpty())
 		{
-			qDebug() << "GLC_ExtendedMesh::getBoundingBox empty m_Positions";
+			qDebug() << "GLC_Mesh::boundingBox empty m_Positions";
 		}
 		else
 		{
@@ -210,7 +211,7 @@ QVector<GLuint> GLC_Mesh::getTrianglesIndex(int lod, GLC_uint materialId) const
 	GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId);
 
 	int offset= 0;
-	if (GLC_State::vboUsed())
+	if (vboIsUsed())
 	{
 		offset= static_cast<int>(reinterpret_cast<GLsizeiptr>(pPrimitiveGroup->trianglesIndexOffset()) / sizeof(GLuint));
 	}
@@ -258,7 +259,7 @@ QList<QVector<GLuint> > GLC_Mesh::getStripsIndex(int lod, GLC_uint materialId) c
 	QList<int> sizes;
 	int stripsCount;
 
-	if (GLC_State::vboUsed())
+	if (vboIsUsed())
 	{
 		stripsCount= pPrimitiveGroup->stripsOffset().size();
 		for (int i= 0; i < stripsCount; ++i)
@@ -331,7 +332,7 @@ QList<QVector<GLuint> > GLC_Mesh::getFansIndex(int lod, GLC_uint materialId) con
 	QList<int> sizes;
 	int fansCount;
 
-	if (GLC_State::vboUsed())
+	if (vboIsUsed())
 	{
 		fansCount= pPrimitiveGroup->fansOffset().size();
 		for (int i= 0; i < fansCount; ++i)
@@ -455,6 +456,59 @@ GLC_Mesh& GLC_Mesh::transformVertice(const GLC_Matrix4x4& matrix)
 	return *this;
 }
 
+double GLC_Mesh::volume()
+{
+	double resultVolume= 0.0;
+
+	if (!m_MeshData.isEmpty())
+	{
+		IndexList triangleIndex;
+		QList<GLC_Material*> materials= materialSet().toList();
+		const int materialsCount= materials.count();
+		for (int i= 0; i < materialsCount; ++i)
+		{
+			GLC_uint materialId= materials.at(i)->id();
+			if (containsTriangles(0, materialId))
+			{
+				triangleIndex.append(getTrianglesIndex(0, materialId).toList());
+			}
+			if (containsStrips(0, materialId))
+			{
+				triangleIndex.append(equivalentTrianglesIndexOfstripsIndex(0, materialId));
+			}
+			if (containsFans(0, materialId))
+			{
+				triangleIndex.append(equivalentTrianglesIndexOfFansIndex(0, materialId));
+			}
+		}
+
+		GLfloatVector vertices= m_MeshData.positionVector();
+		Q_ASSERT((triangleIndex.count() % 3) == 0);
+		const int triangleCount= triangleIndex.count() / 3;
+		for (int i= 0; i < triangleCount; ++i)
+		{
+			const int index= i * 3;
+			const double v1x= vertices.at(triangleIndex.at(index) * 3);
+			const double v1y= vertices.at(triangleIndex.at(index) * 3 + 1);
+			const double v1z= vertices.at(triangleIndex.at(index) * 3 + 2);
+
+			const double v2x= vertices.at(triangleIndex.at(index + 1) * 3);
+			const double v2y= vertices.at(triangleIndex.at(index + 1) * 3 + 1);
+			const double v2z= vertices.at(triangleIndex.at(index + 1) * 3 + 2);
+
+			const double v3x= vertices.at(triangleIndex.at(index + 2) * 3);
+			const double v3y= vertices.at(triangleIndex.at(index + 2) * 3 + 1);
+			const double v3z= vertices.at(triangleIndex.at(index + 2) * 3 + 2);
+
+			resultVolume+= ((v2y - v1y) * (v3z - v1z) - (v2z - v1z) * (v3y - v1y)) * (v1x + v2x + v3x);
+		}
+
+		resultVolume= resultVolume / 6.0;
+	}
+
+	return resultVolume;
+}
+
 //////////////////////////////////////////////////////////////////////
 // Set Functions
 //////////////////////////////////////////////////////////////////////
@@ -581,8 +635,11 @@ void GLC_Mesh::reverseNormals()
 	{
 		(*pNormalVector)[i]= - pNormalVector->at(i);
 	}
-	// Invalid the geometry
-	m_GeometryIsValid = false;
+	if (vboIsUsed())
+	{
+		m_MeshData.fillVbo(GLC_MeshData::GLC_Normal);
+		m_MeshData.useVBO(false, GLC_MeshData::GLC_Normal);
+	}
 }
 
 // Copy index list in a vector for Vertex Array Use
@@ -592,14 +649,7 @@ void GLC_Mesh::finish()
 
 	m_MeshData.finishLod();
 
-	if (GLC_State::vboUsed())
-	{
-		finishVbo();
-	}
-	else
-	{
-		finishNonVbo();
-	}
+	moveIndexToMeshDataLod();
 
 	//qDebug() << "Mesh mem size= " << memmorySize();
 }
@@ -692,6 +742,15 @@ void GLC_Mesh::releaseVboClientSide(bool update)
 	GLC_Geometry::releaseVboClientSide(update);
 }
 
+void GLC_Mesh::setVboUsage(bool usage)
+{
+	if (!isEmpty())
+	{
+		GLC_Geometry::setVboUsage(usage);
+		m_MeshData.setVboUsage(usage);
+	}
+}
+
 // Load the mesh from binary data stream
 void GLC_Mesh::loadFromDataStream(QDataStream& stream, const MaterialHash& materialHash, const QHash<GLC_uint, GLC_uint>& materialIdMap)
 {
@@ -749,7 +808,6 @@ void GLC_Mesh::loadFromDataStream(QDataStream& stream, const MaterialHash& mater
 	stream >> m_NumberOfNormals;
 
 	finishSerialized();
-	//qDebug() << "Mesh mem size= " << memmorySize();
 }
 
 // Save the mesh to binary data stream
@@ -802,9 +860,10 @@ void GLC_Mesh::saveToDataStream(QDataStream& stream) const
 // Virtual interface for OpenGL Geometry set up.
 void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties)
 {
-	Q_ASSERT(m_GeometryIsValid || !m_MeshData.normalVectorHandle()->isEmpty());
 
-	const bool vboIsUsed= GLC_State::vboUsed();
+	Q_ASSERT(m_GeometryIsValid || !m_MeshData.positionSizeIsSet());
+
+	const bool vboIsUsed= GLC_Geometry::vboIsUsed()  && GLC_State::vboSupported();
 
 	if (m_IsSelected && (renderProperties.renderingMode() == glc::PrimitiveSelected) && !GLC_State::isInSelectionMode()
 	&& !renderProperties.setOfSelectedPrimitiveIdIsEmpty())
@@ -817,27 +876,20 @@ void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties)
 		m_MeshData.createVBOs();
 
 		// Create VBO and IBO
-		if (!m_GeometryIsValid && !m_MeshData.positionVectorHandle()->isEmpty())
+		if (!m_GeometryIsValid && !m_MeshData.positionSizeIsSet())
 		{
 			fillVbosAndIbos();
 		}
-		else if (!m_GeometryIsValid && !m_MeshData.normalVectorHandle()->isEmpty())
-		{
-			// Normals has been inversed update normal vbo
-			m_MeshData.useVBO(true, GLC_MeshData::GLC_Normal);
-
-			GLfloatVector* pNormalVector= m_MeshData.normalVectorHandle();
-			const GLsizei dataNbr= static_cast<GLsizei>(pNormalVector->size());
-			const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
-			glBufferData(GL_ARRAY_BUFFER, dataSize, pNormalVector->data(), GL_STATIC_DRAW);
-			m_MeshData.normalVectorHandle()->clear();
-		}
 
 		// Activate mesh VBOs and IBO of the current LOD
 		activateVboAndIbo();
 	}
 	else
 	{
+		if (!m_GeometryIsValid)
+		{
+			m_MeshData.initPositionSize();
+		}
 		activateVertexArray();
 	}
 
@@ -893,6 +945,9 @@ void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties)
 		case glc::OverwriteTransparency:
 			OverwriteTransparencyRenderLoop(renderProperties, vboIsUsed);
 			break;
+		case glc::OverwriteTransparencyAndMaterial:
+			OverwriteTransparencyAndMaterialRenderLoop(renderProperties, vboIsUsed);
+			break;
 		case glc::OverwritePrimitiveMaterial:
 			if ((m_CurrentLod == 0) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty())
 				primitiveRenderLoop(renderProperties, vboIsUsed);
@@ -907,11 +962,6 @@ void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties)
 
 
 	// Restore client state
-	if (vboIsUsed)
-	{
-		m_MeshData.useIBO(false);
-		m_MeshData.useVBO(false, GLC_MeshData::GLC_Normal);
-	}
 
 	if (m_ColorPearVertex && !m_IsSelected && !GLC_State::isInSelectionMode())
 	{
@@ -923,12 +973,18 @@ void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties)
 	glDisableClientState(GL_NORMAL_ARRAY);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
+	if (vboIsUsed)
+	{
+		QGLBuffer::release(QGLBuffer::IndexBuffer);
+		QGLBuffer::release(QGLBuffer::VertexBuffer);
+	}
+
 	// Draw mesh's wire if necessary
 	if ((renderProperties.renderingFlag() == glc::WireRenderFlag) && !m_WireData.isEmpty() && !GLC_Geometry::typeIsWire())
 	{
 		if (!GLC_State::isInSelectionMode())
 		{
-			glDisable(GL_LIGHTING);
+			GLC_Context::current()->glcEnableLighting(false);
 			// Set polyline colors
 			GLfloat color[4]= {static_cast<float>(m_WireColor.redF()),
 									static_cast<float>(m_WireColor.greenF()),
@@ -937,7 +993,7 @@ void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties)
 
 			glColor4fv(color);
 			m_WireData.glDraw(renderProperties, GL_LINE_STRIP);
-			glEnable(GL_LIGHTING);
+			GLC_Context::current()->glcEnableLighting(true);
 		}
 		else
 		{
@@ -1011,54 +1067,38 @@ GLC_uint GLC_Mesh::setCurrentMaterial(GLC_Material* pMaterial, int lod, double a
 // Fill VBOs and IBOs
 void GLC_Mesh::fillVbosAndIbos()
 {
-	// Create VBO of vertices
+	// Fill VBO of vertices
 	m_MeshData.fillVbo(GLC_MeshData::GLC_Vertex);
 
-	// Create VBO of normals
+	// Fill VBO of normals
 	m_MeshData.fillVbo(GLC_MeshData::GLC_Normal);
 
-	// Create VBO of texel if needed
+	// Fill VBO of texel if needed
 	m_MeshData.fillVbo(GLC_MeshData::GLC_Texel);
 
-	// Create VBO of color if needed
+	// Fill VBO of color if needed
 	m_MeshData.fillVbo(GLC_MeshData::GLC_Color);
 
-	const int lodNumber= m_MeshData.lodCount();
-	for (int i= 0; i < lodNumber; ++i)
-	{
-		//Create LOD IBO
-		if (!m_MeshData.indexVectorHandle(i)->isEmpty())
-		{
-			QVector<GLuint>* pIndexVector= m_MeshData.indexVectorHandle(i);
-			m_MeshData.useIBO(true, i);
-			const GLsizei indexNbr= static_cast<GLsizei>(pIndexVector->size());
-			const GLsizeiptr indexSize = indexNbr * sizeof(GLuint);
-			glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, pIndexVector->data(), GL_STATIC_DRAW);
-		}
-	}
-	// Remove client side data
-	m_MeshData.finishVbo();
+	// Fill a lod IBO
+	m_MeshData.fillLodIbo();
 
 }
 // set primitive group offset
 void GLC_Mesh::finishSerialized()
 {
-	if (GLC_State::vboUsed())
+	PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
+	while (iGroups != m_PrimitiveGroups.constEnd())
 	{
-		PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
-		while (iGroups != m_PrimitiveGroups.constEnd())
+		LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
+		while (iGroup != iGroups.value()->constEnd())
 		{
-			LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
-			while (iGroup != iGroups.value()->constEnd())
-			{
-				iGroup.value()->changeToVboMode();
-				++iGroup;
-			}
-			++iGroups;
+			iGroup.value()->computeVboOffset();
+			++iGroup;
 		}
+		++iGroups;
 	}
 }
-
+/*
 // Move Indexs from the primitive groups to the mesh Data LOD and Set IBOs offsets
 void GLC_Mesh::finishVbo()
 {
@@ -1097,11 +1137,12 @@ void GLC_Mesh::finishVbo()
 
 	}
 }
+*/
 
 // Move Indexs from the primitive groups to the mesh Data LOD and Set Index offsets
-void GLC_Mesh::finishNonVbo()
+void GLC_Mesh::moveIndexToMeshDataLod()
 {
-	//qDebug() << "GLC_Mesh::finishNonVbo()";
+	//qDebug() << "GLC_Mesh::moveIndexToMeshDataLod()";
 	PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
 	while (iGroups != m_PrimitiveGroups.constEnd())
 	{
@@ -1130,6 +1171,7 @@ void GLC_Mesh::finishNonVbo()
 				(*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->fansIndex().toVector();
 			}
 
+			iGroup.value()->computeVboOffset();
 			iGroup.value()->finish();
 			++iGroup;
 		}
@@ -1166,9 +1208,13 @@ void GLC_Mesh::normalRenderLoop(const GLC_RenderProperties& renderProperties, bo
 			{
 
 				if (vboIsUsed)
+				{
 					vboDrawPrimitivesOf(pCurrentGroup);
+				}
 				else
+				{
 					vertexArrayDrawPrimitivesOf(pCurrentGroup);
+				}
 			}
 
 			++iGroup;
@@ -1243,6 +1289,40 @@ void GLC_Mesh::OverwriteTransparencyRenderLoop(const GLC_RenderProperties& rende
 	}
 }
 
+void GLC_Mesh::OverwriteTransparencyAndMaterialRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
+{
+	// Get transparency value
+	const float alpha= renderProperties.overwriteTransparency();
+	Q_ASSERT(-1.0f != alpha);
+
+	// Get the overwrite material
+	GLC_Material* pOverwriteMaterial= renderProperties.overwriteMaterial();
+	Q_ASSERT(NULL != pOverwriteMaterial);
+	pOverwriteMaterial->glExecute(alpha);
+	if (m_IsSelected) GLC_SelectionMaterial::glExecute();
+
+	LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
+	while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
+	{
+		GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
+
+		// Test if the current material is renderable
+		bool materialIsrenderable = (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
+
+   		// Choose the primitives to render
+		if (m_IsSelected || materialIsrenderable)
+		{
+
+			if (vboIsUsed)
+				vboDrawPrimitivesOf(pCurrentGroup);
+			else
+				vertexArrayDrawPrimitivesOf(pCurrentGroup);
+		}
+
+		++iGroup;
+	}
+}
+
 // The body selection render loop
 void GLC_Mesh::bodySelectionRenderLoop(bool vboIsUsed)
 {
@@ -1475,3 +1555,61 @@ void GLC_Mesh::copyBulkData(GLC_Mesh* pLodMesh, const QHash<GLuint, GLuint>& tag
 		tempFloatVector.clear();
 	}
 }
+
+IndexList GLC_Mesh::equivalentTrianglesIndexOfstripsIndex(int lodIndex, GLC_uint materialId)
+{
+	IndexList trianglesIndex;
+	if (containsStrips(lodIndex, materialId))
+	{
+		const QList<QVector<GLuint> > stripsIndex= getStripsIndex(lodIndex, materialId);
+		const int stripCount= stripsIndex.count();
+		for (int i= 0; i < stripCount; ++i)
+		{
+			const QVector<GLuint> currentStripIndex= stripsIndex.at(i);
+
+			trianglesIndex.append(currentStripIndex.at(0));
+			trianglesIndex.append(currentStripIndex.at(1));
+			trianglesIndex.append(currentStripIndex.at(2));
+			const int stripSize= currentStripIndex.size();
+			for (int j= 3; j < stripSize; ++j)
+			{
+				if ((j % 2) != 0)
+				{
+					trianglesIndex.append(currentStripIndex.at(j));
+					trianglesIndex.append(currentStripIndex.at(j - 1));
+					trianglesIndex.append(currentStripIndex.at(j - 2));
+				}
+				else
+				{
+					trianglesIndex.append(currentStripIndex.at(j));
+					trianglesIndex.append(currentStripIndex.at(j - 2));
+					trianglesIndex.append(currentStripIndex.at(j - 1));
+				}
+			}
+		}
+	}
+	return trianglesIndex;
+}
+
+IndexList GLC_Mesh::equivalentTrianglesIndexOfFansIndex(int lodIndex, GLC_uint materialId)
+{
+	IndexList trianglesIndex;
+	if (containsFans(lodIndex, materialId))
+	{
+		const QList<QVector<GLuint> > fanIndex= getFansIndex(lodIndex, materialId);
+		const int fanCount= fanIndex.count();
+		for (int i= 0; i < fanCount; ++i)
+		{
+			const QVector<GLuint> currentFanIndex= fanIndex.at(i);
+			const int size= currentFanIndex.size();
+			for (int j= 1; j < size - 1; ++j)
+			{
+				trianglesIndex.append(currentFanIndex.first());
+				trianglesIndex.append(currentFanIndex.at(j));
+				trianglesIndex.append(currentFanIndex.at(j + 1));
+			}
+		}
+	}
+	return trianglesIndex;
+}
+
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_mesh.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_mesh.h
index 389a1dd3e..98061167f 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_mesh.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_mesh.h
@@ -183,10 +183,12 @@ public:
 	//! Create a mesh from the given LOD index
 	GLC_Mesh* createMeshFromGivenLod(int lodIndex);
 
-
 	//! Transform mesh vertice by the given matrix
 	GLC_Mesh& transformVertice(const GLC_Matrix4x4& matrix);
 
+	//! Return the volume of this mesh
+	virtual double volume();
+
 //@}
 //////////////////////////////////////////////////////////////////////
 /*! \name Set Functions*/
@@ -264,6 +266,9 @@ public:
 	//! Release client VBO
 	virtual void releaseVboClientSide(bool update);
 
+	//! Set VBO usage
+	virtual void setVboUsage(bool usage);
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -309,10 +314,10 @@ private:
 	void finishSerialized();
 
 	//! Move Indexs from the primitive groups to the mesh Data LOD and Set IBOs offsets
-	void finishVbo();
+	//void finishVbo();
 
 	//! Move Indexs from the primitive groups to the mesh Data LOD and Set Index offsets
-	void finishNonVbo();
+	void moveIndexToMeshDataLod();
 
 	//! Use VBO to Draw primitives from the specified GLC_PrimitiveGroup
 	inline void vboDrawPrimitivesOf(GLC_PrimitiveGroup*);
@@ -353,6 +358,9 @@ private:
 	//! The overwrite transparency render loop
 	void OverwriteTransparencyRenderLoop(const GLC_RenderProperties&, bool);
 
+	//! The overwrite transparency and material render loop
+	void OverwriteTransparencyAndMaterialRenderLoop(const GLC_RenderProperties&, bool);
+
 	//! The body selection render loop
 	void bodySelectionRenderLoop(bool);
 
@@ -371,6 +379,13 @@ private:
 	//! Copy Bulk data
 	void copyBulkData(GLC_Mesh* pLodMesh, const QHash<GLuint, GLuint>& tagetToSourceIndexMap, int maxIndex);
 
+	//! Return the equivalent triangles index of the strips index of given LOD and material ID
+	IndexList equivalentTrianglesIndexOfstripsIndex(int lodIndex, GLC_uint materialId);
+
+	//! Return the equivalent triangles index of the fan index of given LOD and material ID
+	IndexList equivalentTrianglesIndexOfFansIndex(int lodIndex, GLC_uint materialId);
+
+
 //@}
 
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_meshdata.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_meshdata.cpp
index 1cfb5c7ca..2c96c1a74 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_meshdata.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_meshdata.cpp
@@ -22,6 +22,7 @@
 
 //! \file glc_meshdata.cpp Implementation for the GLC_MeshData class.
 
+#include "../glc_exception.h"
 #include "glc_meshdata.h"
 #include "../glc_state.h"
 
@@ -30,36 +31,38 @@ quint32 GLC_MeshData::m_ChunkId= 0xA704;
 
 // Default constructor
 GLC_MeshData::GLC_MeshData()
-: m_VboId(0)
+: m_VertexBuffer()
 , m_Positions()
 , m_Normals()
 , m_Texels()
 , m_Colors()
-, m_NormalVboId(0)
-, m_TexelVboId(0)
-, m_ColorVboId(0)
+, m_NormalBuffer()
+, m_TexelBuffer()
+, m_ColorBuffer()
 , m_LodList()
-, m_PositionSize(0)
-, m_TexelsSize(0)
-, m_ColorSize(0)
+, m_PositionSize(-1)
+, m_TexelsSize(-1)
+, m_ColorSize(-1)
+, m_UseVbo(false)
 {
 
 }
 
 // Copy constructor
 GLC_MeshData::GLC_MeshData(const GLC_MeshData& meshData)
-: m_VboId(0)
+: m_VertexBuffer()
 , m_Positions(meshData.positionVector())
 , m_Normals(meshData.normalVector())
 , m_Texels(meshData.texelVector())
 , m_Colors(meshData.colorVector())
-, m_NormalVboId(0)
-, m_TexelVboId(0)
-, m_ColorVboId(0)
+, m_NormalBuffer()
+, m_TexelBuffer()
+, m_ColorBuffer()
 , m_LodList()
 , m_PositionSize(meshData.m_PositionSize)
 , m_TexelsSize(meshData.m_TexelsSize)
 , m_ColorSize(meshData.m_ColorSize)
+, m_UseVbo(meshData.m_UseVbo)
 {
 	// Copy meshData LOD list
 	const int size= meshData.m_LodList.size();
@@ -85,6 +88,7 @@ GLC_MeshData& GLC_MeshData::operator=(const GLC_MeshData& meshData)
 		m_PositionSize= meshData.m_PositionSize;
 		m_TexelsSize= meshData.m_TexelsSize;
 		m_ColorSize= meshData.m_ColorSize;
+		m_UseVbo= meshData.m_UseVbo;
 
 		// Copy meshData LOD list
 		const int size= meshData.m_LodList.size();
@@ -112,18 +116,22 @@ quint32 GLC_MeshData::chunckID()
 // Return the Position Vector
 GLfloatVector GLC_MeshData::positionVector() const
 {
-	if (0 != m_VboId)
+	if (m_VertexBuffer.isCreated())
 	{
 		// VBO created get data from VBO
 		const int sizeOfVbo= m_PositionSize;
 		const GLsizeiptr dataSize= sizeOfVbo * sizeof(float);
 		GLfloatVector positionVector(sizeOfVbo);
 
-		glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
-		GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
+		if (!const_cast<QGLBuffer&>(m_VertexBuffer).bind())
+		{
+			GLC_Exception exception("GLC_MeshData::positionVector()  Failed to bind vertex buffer");
+			throw(exception);
+		}
+		GLvoid* pVbo = const_cast<QGLBuffer&>(m_VertexBuffer).map(QGLBuffer::ReadOnly);
 		memcpy(positionVector.data(), pVbo, dataSize);
-		glUnmapBuffer(GL_ARRAY_BUFFER);
-		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		const_cast<QGLBuffer&>(m_VertexBuffer).unmap();
+		const_cast<QGLBuffer&>(m_VertexBuffer).release();
 		return positionVector;
 	}
 	else
@@ -135,18 +143,18 @@ GLfloatVector GLC_MeshData::positionVector() const
 // Return the normal Vector
 GLfloatVector GLC_MeshData::normalVector() const
 {
-	if (0 != m_NormalVboId)
+	if (m_NormalBuffer.isCreated())
 	{
 		// VBO created get data from VBO
 		const int sizeOfVbo= m_PositionSize;
 		const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
 		GLfloatVector normalVector(sizeOfVbo);
 
-		glBindBuffer(GL_ARRAY_BUFFER, m_NormalVboId);
-		GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
+		const_cast<QGLBuffer&>(m_NormalBuffer).bind();
+		GLvoid* pVbo = const_cast<QGLBuffer&>(m_NormalBuffer).map(QGLBuffer::ReadOnly);
 		memcpy(normalVector.data(), pVbo, dataSize);
-		glUnmapBuffer(GL_ARRAY_BUFFER);
-		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		const_cast<QGLBuffer&>(m_NormalBuffer).unmap();
+		const_cast<QGLBuffer&>(m_NormalBuffer).release();
 		return normalVector;
 	}
 	else
@@ -158,18 +166,18 @@ GLfloatVector GLC_MeshData::normalVector() const
 // Return the texel Vector
 GLfloatVector GLC_MeshData::texelVector() const
 {
-	if (0 != m_TexelVboId)
+	if (m_TexelBuffer.isCreated())
 	{
 		// VBO created get data from VBO
 		const int sizeOfVbo= m_TexelsSize;
 		const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
 		GLfloatVector texelVector(sizeOfVbo);
 
-		glBindBuffer(GL_ARRAY_BUFFER, m_TexelVboId);
-		GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
+		const_cast<QGLBuffer&>(m_TexelBuffer).bind();
+		GLvoid* pVbo = const_cast<QGLBuffer&>(m_TexelBuffer).map(QGLBuffer::ReadOnly);
 		memcpy(texelVector.data(), pVbo, dataSize);
-		glUnmapBuffer(GL_ARRAY_BUFFER);
-		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		const_cast<QGLBuffer&>(m_TexelBuffer).unmap();
+		const_cast<QGLBuffer&>(m_TexelBuffer).release();
 		return texelVector;
 	}
 	else
@@ -181,18 +189,18 @@ GLfloatVector GLC_MeshData::texelVector() const
 // Return the color Vector
 GLfloatVector GLC_MeshData::colorVector() const
 {
-	if (0 != m_ColorVboId)
+	if (m_ColorBuffer.isCreated())
 	{
 		// VBO created get data from VBO
 		const int sizeOfVbo= m_ColorSize;
 		const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
 		GLfloatVector normalVector(sizeOfVbo);
 
-		glBindBuffer(GL_ARRAY_BUFFER, m_ColorVboId);
-		GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
+		const_cast<QGLBuffer&>(m_ColorBuffer).bind();
+		GLvoid* pVbo = const_cast<QGLBuffer&>(m_ColorBuffer).map(QGLBuffer::ReadOnly);
 		memcpy(normalVector.data(), pVbo, dataSize);
-		glUnmapBuffer(GL_ARRAY_BUFFER);
-		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		const_cast<QGLBuffer&>(m_ColorBuffer).unmap();
+		const_cast<QGLBuffer&>(m_ColorBuffer).release();
 		return normalVector;
 	}
 	else
@@ -205,25 +213,6 @@ GLfloatVector GLC_MeshData::colorVector() const
 // Set Functions
 //////////////////////////////////////////////////////////////////////
 
-// The mesh wich use the data is finished
-void GLC_MeshData::finishVbo()
-{
-	m_PositionSize= m_Positions.size();
-	m_Positions.clear();
-	m_Normals.clear();
-	m_TexelsSize= m_Texels.size();
-	m_Texels.clear();
-	m_ColorSize= m_Colors.size();
-	m_Colors.clear();
-
-	// Finish the LOD
-	const int size= m_LodList.size();
-	for (int i= 0; i < size; ++i)
-	{
-		m_LodList[i]->finishVbo();
-	}
-}
-
 // If the there is more than 2 LOD Swap the first and last
 void GLC_MeshData::finishLod()
 {
@@ -244,35 +233,31 @@ void GLC_MeshData::clear()
 	m_Normals.clear();
 	m_Texels.clear();
 	m_Colors.clear();
-	m_PositionSize= 0;
-	m_TexelsSize= 0;
-	m_ColorSize= 0;
+	m_PositionSize= -1;
+	m_TexelsSize= -1;
+	m_ColorSize= -1;
 
 	// Delete Main Vbo ID
-	if (0 != m_VboId)
+	if (m_VertexBuffer.isCreated())
 	{
-		glDeleteBuffers(1, &m_VboId);
-		m_VboId= 0;
+		m_VertexBuffer.destroy();
 	}
 
 	// Delete Normal VBO
-	if (0 != m_NormalVboId)
+	if (m_NormalBuffer.isCreated())
 	{
-		glDeleteBuffers(1, &m_NormalVboId);
-		m_NormalVboId= 0;
+		m_NormalBuffer.destroy();
 	}
 
 	// Delete Texel VBO
-	if (0 != m_TexelVboId)
+	if (m_TexelBuffer.isCreated())
 	{
-		glDeleteBuffers(1, &m_TexelVboId);
-		m_TexelVboId= 0;
+		m_TexelBuffer.destroy();
 	}
 	// Delete color index
-	if (0 != m_ColorVboId)
+	if (m_ColorBuffer.isCreated())
 	{
-		glDeleteBuffers(1, &m_ColorVboId);
-		m_ColorVboId= 0;
+		m_ColorBuffer.destroy();
 	}
 
 	const int size= m_LodList.size();
@@ -286,16 +271,16 @@ void GLC_MeshData::clear()
 void GLC_MeshData::copyVboToClientSide()
 {
 
-	if ((0 != m_VboId) && m_Positions.isEmpty())
+	if (m_VertexBuffer.isCreated() && m_Positions.isEmpty())
 	{
-		Q_ASSERT(0 != m_NormalVboId);
+		Q_ASSERT(m_NormalBuffer.isCreated());
 		m_Positions= positionVector();
 		m_Normals= normalVector();
-		if (0 != m_TexelVboId)
+		if (m_TexelBuffer.isCreated())
 		{
 			m_Texels= texelVector();
 		}
-		if (0 != m_ColorVboId)
+		if (m_ColorBuffer.isCreated())
 		{
 			m_Colors= colorVector();
 		}
@@ -304,7 +289,7 @@ void GLC_MeshData::copyVboToClientSide()
 
 void GLC_MeshData::releaseVboClientSide(bool update)
 {
-	if ((0 != m_VboId) && !m_Positions.isEmpty())
+	if (m_VertexBuffer.isCreated() && !m_Positions.isEmpty())
 	{
 		if (update)
 		{
@@ -324,28 +309,82 @@ void GLC_MeshData::releaseVboClientSide(bool update)
 	}
 }
 
+void GLC_MeshData::setVboUsage(bool usage)
+{
+	if (usage && (m_PositionSize != -1) && (!m_Positions.isEmpty()) && (!m_VertexBuffer.isCreated()))
+	{
+		createVBOs();
+
+		fillVbo(GLC_MeshData::GLC_Vertex);
+		fillVbo(GLC_MeshData::GLC_Normal);
+		fillVbo(GLC_MeshData::GLC_Texel);
+		fillVbo(GLC_MeshData::GLC_Color);
+		useVBO(false, GLC_MeshData::GLC_Color);
+
+		const int lodCount= m_LodList.count();
+		for (int i= 0; i < lodCount; ++i)
+		{
+			m_LodList.at(i)->setIboUsage(usage);
+		}
+
+	}
+	else if (!usage && m_VertexBuffer.isCreated())
+	{
+		m_Positions= positionVector();
+		m_PositionSize= m_Positions.size();
+		m_VertexBuffer.destroy();
+
+		m_Normals= normalVector();
+		m_NormalBuffer.destroy();
+
+		if (m_TexelBuffer.isCreated())
+		{
+			m_Texels= texelVector();
+			m_TexelsSize= m_Texels.size();
+			m_TexelBuffer.destroy();
+		}
+		if (m_ColorBuffer.isCreated())
+		{
+			m_Colors= colorVector();
+			m_ColorSize= m_Colors.size();
+			m_ColorBuffer.destroy();
+		}
+
+		const int lodCount= m_LodList.count();
+		for (int i= 0; i < lodCount; ++i)
+		{
+			m_LodList.at(i)->setIboUsage(usage);
+		}
+	}
+	m_UseVbo= usage;
+
+}
+
 //////////////////////////////////////////////////////////////////////
 // OpenGL Functions
 //////////////////////////////////////////////////////////////////////
 // Vbo creation
 void GLC_MeshData::createVBOs()
 {
+
 	// Create position VBO
-	if (0 == m_VboId)
+	if (!m_VertexBuffer.isCreated())
 	{
-		glGenBuffers(1, &m_VboId);
-		glGenBuffers(1, &m_NormalVboId);
+		Q_ASSERT((NULL != QGLContext::currentContext()) &&  QGLContext::currentContext()->isValid());
+
+		m_VertexBuffer.create();
+		m_NormalBuffer.create();
 
 		// Create Texel VBO
-		if (0 == m_TexelVboId && !m_Texels.isEmpty())
+		if (!m_TexelBuffer.isCreated() && !m_Texels.isEmpty())
 		{
-			glGenBuffers(1, &m_TexelVboId);
+			m_TexelBuffer.create();
 		}
 
 		// Create Color VBO
-		if (0 == m_ColorVboId && !m_Colors.isEmpty())
+		if (!m_ColorBuffer.isCreated() && !m_Colors.isEmpty())
 		{
-			glGenBuffers(1, &m_ColorVboId);
+			m_ColorBuffer.create();
 		}
 
 		const int size= m_LodList.size();
@@ -357,7 +396,7 @@ void GLC_MeshData::createVBOs()
 }
 
 // Ibo Usage
-bool GLC_MeshData::useVBO(bool use, GLC_MeshData::VboType type) const
+bool GLC_MeshData::useVBO(bool use, GLC_MeshData::VboType type)
 {
 	bool result= true;
 	if (use)
@@ -365,19 +404,35 @@ bool GLC_MeshData::useVBO(bool use, GLC_MeshData::VboType type) const
 		// Chose the right VBO
 		if (type == GLC_MeshData::GLC_Vertex)
 		{
-			glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
+			if (!m_VertexBuffer.bind())
+			{
+				GLC_Exception exception("GLC_MeshData::useVBO  Failed to bind vertex buffer");
+				throw(exception);
+			}
 		}
 		else if (type == GLC_MeshData::GLC_Normal)
 		{
-			glBindBuffer(GL_ARRAY_BUFFER, m_NormalVboId);
+			if (!m_NormalBuffer.bind())
+			{
+				GLC_Exception exception("GLC_MeshData::useVBO  Failed to bind normal buffer");
+				throw(exception);
+			}
 		}
-		else if ((type == GLC_MeshData::GLC_Texel) && (0 != m_TexelVboId))
+		else if ((type == GLC_MeshData::GLC_Texel) && m_TexelBuffer.isCreated())
 		{
-			glBindBuffer(GL_ARRAY_BUFFER, m_TexelVboId);
+			if (!m_TexelBuffer.bind())
+			{
+				GLC_Exception exception("GLC_MeshData::useVBO  Failed to bind texel buffer");
+				throw(exception);
+			}
 		}
-		else if ((type == GLC_MeshData::GLC_Color) && (0 != m_ColorVboId))
+		else if ((type == GLC_MeshData::GLC_Color) && m_ColorBuffer.isCreated())
 		{
-			glBindBuffer(GL_ARRAY_BUFFER, m_ColorVboId);
+			if (!m_ColorBuffer.bind())
+			{
+				GLC_Exception exception("GLC_MeshData::useVBO  Failed to bind color buffer");
+				throw(exception);
+			}
 		}
 
 		else result= false;
@@ -385,7 +440,7 @@ bool GLC_MeshData::useVBO(bool use, GLC_MeshData::VboType type) const
 	else
 	{
 		// Unbind VBO
-		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		QGLBuffer::release(QGLBuffer::VertexBuffer);
 	}
 	return result;
 }
@@ -398,28 +453,48 @@ void GLC_MeshData::fillVbo(GLC_MeshData::VboType type)
 		useVBO(true, type);
 		const GLsizei dataNbr= static_cast<GLsizei>(m_Positions.size());
 		const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
-		glBufferData(GL_ARRAY_BUFFER, dataSize, m_Positions.data(), GL_STATIC_DRAW);
+		m_VertexBuffer.allocate(m_Positions.data(), dataSize);
+
+		m_PositionSize= m_Positions.size();
+		m_Positions.clear();
 	}
 	else if (type == GLC_MeshData::GLC_Normal)
 	{
 		useVBO(true, type);
 		const GLsizei dataNbr= static_cast<GLsizei>(m_Normals.size());
 		const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
-		glBufferData(GL_ARRAY_BUFFER, dataSize, m_Normals.data(), GL_STATIC_DRAW);
+		m_NormalBuffer.allocate(m_Normals.data(), dataSize);
+
+		m_Normals.clear();
 	}
-	else if ((type == GLC_MeshData::GLC_Texel) && (0 != m_TexelVboId))
+	else if ((type == GLC_MeshData::GLC_Texel) && m_TexelBuffer.isCreated())
 	{
 		useVBO(true, type);
 		const GLsizei dataNbr= static_cast<GLsizei>(m_Texels.size());
 		const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
-		glBufferData(GL_ARRAY_BUFFER, dataSize, m_Texels.data(), GL_STATIC_DRAW);
+		m_TexelBuffer.allocate(m_Texels.data(), dataSize);
+
+		m_TexelsSize= m_Texels.size();
+		m_Texels.clear();
 	}
-	else if ((type == GLC_MeshData::GLC_Color) && (0 != m_ColorVboId))
+	else if ((type == GLC_MeshData::GLC_Color) && m_ColorBuffer.isCreated())
 	{
 		useVBO(true, type);
 		const GLsizei dataNbr= static_cast<GLsizei>(m_Colors.size());
 		const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
-		glBufferData(GL_ARRAY_BUFFER, dataSize, m_Colors.data(), GL_STATIC_DRAW);
+		m_ColorBuffer.allocate(m_Colors.data(), dataSize);
+
+		m_ColorSize= m_Colors.size();
+		m_Colors.clear();
+	}
+}
+
+void GLC_MeshData::fillLodIbo()
+{
+	const int lodCount= m_LodList.count();
+	for (int i= 0; i < lodCount; ++i)
+	{
+		m_LodList.at(i)->fillIbo();
 	}
 }
 // Non Member methods
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_meshdata.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_meshdata.h
index 04c33e526..f9c5160ba 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_meshdata.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_meshdata.h
@@ -26,6 +26,7 @@
 #define GLC_MESHDATA_H_
 
 #include <QVector>
+#include <QGLBuffer>
 
 #include "glc_lod.h"
 #include "../glc_global.h"
@@ -140,7 +141,7 @@ public:
 
 	//! Return true if the mesh data doesn't contains vertice
 	inline bool isEmpty() const
-	{return (0 == m_PositionSize) && (0 == m_Positions.size());}
+	{return (1 > m_PositionSize) && (0 == m_Positions.size());}
 
 	//! Return the number of triangle from the given lod index
 	inline unsigned int trianglesCount(int lod) const
@@ -149,6 +150,10 @@ public:
 		return m_LodList.at(lod)->trianglesCount();
 	}
 
+	//! Return true if the position size is set
+	inline bool positionSizeIsSet() const
+	{return m_PositionSize != -1;}
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -160,9 +165,6 @@ public:
 	inline void appendLod(double accuracy= 0.0)
 	{m_LodList.append(new GLC_Lod(accuracy));}
 
-	//! The mesh wich use the data is finished and VBO is used
-	void finishVbo();
-
 	//! If the there is more than 2 LOD Swap the first and last
 	void finishLod();
 
@@ -183,6 +185,13 @@ public:
 		m_LodList.at(lod)->trianglesAdded(number);
 	}
 
+	//! Set VBO usage
+	void setVboUsage(bool usage);
+
+	//! Init the position size
+	inline void initPositionSize()
+	{m_PositionSize= m_Positions.size();}
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -194,15 +203,18 @@ public:
 	void createVBOs();
 
 	//! Ibo Usage
-	bool useVBO(bool, GLC_MeshData::VboType) const;
+	bool useVBO(bool, GLC_MeshData::VboType);
 
 	//! Ibo Usage
 	inline void useIBO(bool use, const int currentLod= 0)
 	{
 		if (use) m_LodList.at(currentLod)->useIBO();
-		else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+		else QGLBuffer::release(QGLBuffer::IndexBuffer);
 	}
 
+	//! Fill all LOD IBO
+	void fillLodIbo();
+
 	//! Fill the VBO of the given type
 	void fillVbo(GLC_MeshData::VboType vboType);
 
@@ -213,8 +225,8 @@ public:
 //////////////////////////////////////////////////////////////////////
 private:
 
-	//! Main VBO ID
-	GLuint m_VboId;
+	//! The vertex Buffer
+	QGLBuffer m_VertexBuffer;
 
 	//! Vertex Position Vector
 	GLfloatVector m_Positions;
@@ -228,14 +240,14 @@ private:
 	//! Color index
 	GLfloatVector m_Colors;
 
-	//! Normals VBO ID
-	GLuint m_NormalVboId;
+	//! Normals Buffer
+	QGLBuffer m_NormalBuffer;
 
-	//! Texture VBO ID
-	GLuint m_TexelVboId;
+	//! Texture Buffer
+	QGLBuffer m_TexelBuffer;
 
-	//! Color VBO ID
-	GLuint m_ColorVboId;
+	//! Color Buffer
+	QGLBuffer m_ColorBuffer;
 
 	//! The list of LOD
 	QList<GLC_Lod*> m_LodList;
@@ -249,6 +261,9 @@ private:
 	//! The size of Color VBO
 	int m_ColorSize;
 
+	//! Use VBO
+	bool m_UseVbo;
+
 	//! Class chunk id
 	static quint32 m_ChunkId;
 };
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_point.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_point.cpp
index 4cd7f8543..a89dd6e25 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_point.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_point.cpp
@@ -32,18 +32,27 @@ using namespace glc;
 
 
 GLC_Point::GLC_Point(const GLC_Point3d &setCoord)
-:GLC_Geometry("Point", true)
+:GLC_PointCloud()
 , m_Coordinate(setCoord)
 , m_Size(1.0f)
 {
-
+	setCoordinate(m_Coordinate);
 }
-//! Construct an GLC_Point
+
 GLC_Point::GLC_Point(double x, double y, double z)
-:GLC_Geometry("Point", true)
+:GLC_PointCloud()
 , m_Coordinate(x, y, z)
 , m_Size(1.0f)
 {
+	setCoordinate(m_Coordinate);
+}
+
+GLC_Point::GLC_Point(const GLC_Point& point)
+:GLC_PointCloud(point)
+, m_Coordinate(point.m_Coordinate)
+, m_Size(point.m_Size)
+{
+
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -56,26 +65,6 @@ GLC_Point3d GLC_Point::coordinate(void) const
 	return m_Coordinate;
 }
 
-// return the point bounding box
-const GLC_BoundingBox& GLC_Point::boundingBox(void)
-{
-
-	if (NULL == m_pBoundingBox)
-	{
-		m_pBoundingBox= new GLC_BoundingBox();
-		const double delta= 1e-2;
-		GLC_Point3d lower(m_Coordinate.x() - delta,
-				m_Coordinate.y() - delta,
-				m_Coordinate.z() - delta);
-		GLC_Point3d upper(m_Coordinate.x() + delta,
-				m_Coordinate.y() + delta,
-				m_Coordinate.z() + delta);
-		m_pBoundingBox->combine(lower);
-		m_pBoundingBox->combine(upper);
-	}
-	return *m_pBoundingBox;
-}
-
 // Return a copy of the current geometry
 GLC_Geometry* GLC_Point::clone() const
 {
@@ -90,32 +79,26 @@ GLC_Geometry* GLC_Point::clone() const
 void GLC_Point::setCoordinate(const GLC_Point3d &point)
 {
 	m_Coordinate= point;
+	GLC_PointCloud::clear();
+	QList<GLC_Point3d> points;
+	points.append(m_Coordinate);
+	GLC_PointCloud::addPoint(points);
+
 }
 // Set Point coordinate by 3 double
 void GLC_Point::setCoordinate(double x, double y, double z)
 {
-	m_Coordinate.setVect(x, y, z);
+	setCoordinate(GLC_Point3d(x, y, z));
 }
 
 //////////////////////////////////////////////////////////////////////
 // OpenGL Functions
 //////////////////////////////////////////////////////////////////////
 
-void GLC_Point::glDraw(const GLC_RenderProperties&)
+void GLC_Point::glDraw(const GLC_RenderProperties& renderProperties)
 {
 	glPointSize(m_Size);
 	// Point Display
-	glBegin(GL_POINTS);
-		glVertex3dv(m_Coordinate.data());
-	glEnd();
-	glPointSize(1.0f);
-
-	// OpenGL error handler
-	GLenum error= glGetError();
-	if (error != GL_NO_ERROR)
-	{
-		GLC_OpenGlException OpenGlException("GLC_Point::GlDraw ", error);
-		throw(OpenGlException);
-	}
+	GLC_PointCloud::glDraw(renderProperties);
 }
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_point.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_point.h
index d50b40dc0..ba9bf6cfb 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_point.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_point.h
@@ -25,7 +25,7 @@
 #ifndef GLC_POINT_H_
 #define GLC_POINT_H_
 
-#include "glc_geometry.h"
+#include "glc_pointcloud.h"
 
 #include "../glc_config.h"
 
@@ -36,7 +36,7 @@
 /*! An GLC_Point is just a simple 3D Point*/
 //////////////////////////////////////////////////////////////////////
 
-class GLC_LIB_EXPORT GLC_Point : public GLC_Geometry
+class GLC_LIB_EXPORT GLC_Point : public GLC_PointCloud
 {
 //////////////////////////////////////////////////////////////////////
 /*! @name Constructor / Destructor */
@@ -49,6 +49,9 @@ public:
 	//! Construct an GLC_Point
 	GLC_Point(double, double, double);
 
+	//! Copy constructor
+	GLC_Point(const GLC_Point& point);
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -60,9 +63,6 @@ public:
 	//! Return a GLC_Point3d of coordinate
 	GLC_Point3d coordinate(void) const;
 
-	//! Return the point bounding box
-	virtual const GLC_BoundingBox& boundingBox(void);
-
 	//! Return a copy of the geometry
 	virtual GLC_Geometry* clone() const;
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointcloud.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointcloud.cpp
index 48bdabbcf..2e8535102 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointcloud.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointcloud.cpp
@@ -96,6 +96,23 @@ GLC_uint GLC_PointCloud::addPoint(const QList<GLC_Point3df>& pointsList)
 	return GLC_Geometry::m_WireData.addVerticeGroup(data);
 }
 
+void GLC_PointCloud::addColors(const QList<QColor>& colors)
+{
+	const int colorCount= colors.count();
+	const int size= colorCount * 4;
+	GLfloatVector data(size);
+	for (int i= 0; i < colorCount; ++i)
+	{
+		QColor color= colors.at(i);
+		data[i * 4]= static_cast<GLfloat>(color.redF());
+		data[i * 4 + 1]= static_cast<GLfloat>(color.greenF());
+		data[i * 4 + 2]= static_cast<GLfloat>(color.blueF());
+		data[i * 4 + 3]= static_cast<GLfloat>(color.alphaF());
+	}
+
+	GLC_Geometry::m_WireData.addColors(data);
+}
+
 GLC_PointCloud& GLC_PointCloud::operator=(const GLC_PointCloud& pointCloud)
 {
 	if (this != &pointCloud)
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointcloud.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointcloud.h
index b9e49c7d3..41462957f 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointcloud.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointcloud.h
@@ -86,6 +86,13 @@ public:
 	//! Add the given list of points to this cloud and returns its id if id are managed
 	GLC_uint addPoint(const QList<GLC_Point3df>& pointsList);
 
+	//! Add Colors
+	inline void addColors(const GLfloatVector& colors)
+	{GLC_Geometry::m_WireData.addColors(colors);}
+
+	//! Add Colors
+	void addColors(const QList<QColor>& colors);
+
 	//! Set this point cloud from the given point cloud and return a reference of this point cloud
 	GLC_PointCloud& operator=(const GLC_PointCloud& pointcloud);
 
@@ -99,7 +106,7 @@ public:
 /*! \name OpenGL Functions*/
 //@{
 //////////////////////////////////////////////////////////////////////
-private:
+protected:
 
 	//! Virtual interface for OpenGL Geometry set up.
 	/*! This Virtual function is implemented here.\n
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointsprite.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointsprite.cpp
index a90b1e8ef..560bb6048 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointsprite.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointsprite.cpp
@@ -27,13 +27,14 @@
 #include "../glc_state.h"
 #include "../glc_ext.h"
 #include "../shading/glc_selectionmaterial.h"
+#include "../glc_context.h"
 
 // The maximum point size
 float GLC_PointSprite::m_MaxSize= -1.0f;
 
 // Default constructor
 GLC_PointSprite::GLC_PointSprite(float size, GLC_Material* pMaterial)
-:GLC_Geometry("PointSprite", false)
+:GLC_PointCloud()
 , m_Size(size)
 , m_DistanceAttenuation(3)
 , m_FadeThresoldSize(60.0f)
@@ -46,6 +47,19 @@ GLC_PointSprite::GLC_PointSprite(float size, GLC_Material* pMaterial)
 	m_DistanceAttenuation[0]= 1.0f;
 	m_DistanceAttenuation[1]= 0.0f;
 	m_DistanceAttenuation[2]= 0.0f;
+
+	QList<GLC_Point3d> points;
+	points.append(GLC_Point3d(0.0, 0.0, 0.0));
+	GLC_PointCloud::addPoint(points);
+}
+
+GLC_PointSprite::GLC_PointSprite(const GLC_PointSprite& point)
+: GLC_PointCloud(point)
+, m_Size(point.m_Size)
+, m_DistanceAttenuation(point.m_DistanceAttenuation)
+, m_FadeThresoldSize(point.m_FadeThresoldSize)
+{
+
 }
 
 GLC_PointSprite::~GLC_PointSprite()
@@ -53,26 +67,6 @@ GLC_PointSprite::~GLC_PointSprite()
 
 }
 
-// return the point bounding box
-const GLC_BoundingBox& GLC_PointSprite::boundingBox(void)
-{
-
-	if (NULL == m_pBoundingBox)
-	{
-		m_pBoundingBox= new GLC_BoundingBox();
-		const double epsilon= 1e-2;
-		GLC_Point3d lower( 	- epsilon,
-							- epsilon,
-							- epsilon);
-		GLC_Point3d upper(  epsilon,
-							epsilon,
-							epsilon);
-		m_pBoundingBox->combine(lower);
-		m_pBoundingBox->combine(upper);
-	}
-	return *m_pBoundingBox;
-}
-
 // Return a copy of the current geometry
 GLC_Geometry* GLC_PointSprite::clone() const
 {
@@ -116,6 +110,7 @@ void GLC_PointSprite::render(const GLC_RenderProperties& renderProperties)
 		glEnable(GL_TEXTURE_2D);
 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 		glDisable(GL_LIGHTING);
+		//GLC_Context::current()->glcEnableLighting(false);
 
 	    if(m_MaterialHash.size() == 1)
 	    {
@@ -143,6 +138,7 @@ void GLC_PointSprite::render(const GLC_RenderProperties& renderProperties)
 		glDisable(GL_BLEND);
 		glDisable(GL_TEXTURE_2D);
 		glDisable(GL_LIGHTING);
+		//GLC_Context::current()->glcEnableLighting(false);
 	}
 
 
@@ -182,19 +178,8 @@ void GLC_PointSprite::render(const GLC_RenderProperties& renderProperties)
 
 }
 // Point sprite set up
-void GLC_PointSprite::glDraw(const GLC_RenderProperties&)
+void GLC_PointSprite::glDraw(const GLC_RenderProperties& renderProperties)
 {
-	// Point Display
-	glBegin(GL_POINTS);
-		glVertex3f(0.0f,0.0f,0.0f);
-	glEnd();
-
-	// OpenGL error handler
-	GLenum error= glGetError();
-	if (error != GL_NO_ERROR)
-	{
-		GLC_OpenGlException OpenGlException("GLC_PointSprite::GlDraw ", error);
-		throw(OpenGlException);
-	}
+	GLC_PointCloud::glDraw(renderProperties);
 }
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointsprite.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointsprite.h
index 62cf2f623..fc74f05b9 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointsprite.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_pointsprite.h
@@ -22,7 +22,7 @@
  *****************************************************************************/
 //! \file glc_pointsprite.h interface for the GLC_PointSprite class.
 
-#include "glc_geometry.h"
+#include "glc_pointcloud.h"
 #include <QVector>
 
 #include "../glc_config.h"
@@ -37,7 +37,7 @@
 /*! An GLC_PointSprite is just a simple 3D Sprite Point*/
 //////////////////////////////////////////////////////////////////////
 
-class GLC_LIB_EXPORT GLC_PointSprite : public GLC_Geometry
+class GLC_LIB_EXPORT GLC_PointSprite : public GLC_PointCloud
 {
 public:
 //////////////////////////////////////////////////////////////////////
@@ -48,6 +48,9 @@ public:
 	/*! The material must exist and had texture*/
 	GLC_PointSprite(float, GLC_Material*);
 
+	//! Copy constructor
+	GLC_PointSprite(const GLC_PointSprite& point);
+
 	//! Default destructor
 	virtual ~GLC_PointSprite();
 //@}
@@ -61,9 +64,6 @@ public:
 	inline float size() const
 	{return m_Size;}
 
-	//! Return the point bounding box
-	virtual const GLC_BoundingBox& boundingBox(void);
-
 	//! Return a copy of the geometry
 	virtual GLC_Geometry* clone() const;
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_polylines.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_polylines.cpp
index 2c1336d7b..89e73e9ae 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_polylines.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_polylines.cpp
@@ -64,6 +64,38 @@ GLC_Geometry* GLC_Polylines::clone() const
 //////////////////////////////////////////////////////////////////////
 // Set Functions
 //////////////////////////////////////////////////////////////////////
+
+
+GLC_uint GLC_Polylines::addPolyline(const QList<GLC_Point3d>& pointsList)
+{
+	const int pointCount= pointsList.size();
+	const int size= pointCount * 3;
+	GLfloatVector data(size);
+	for (int i= 0; i < pointCount; ++i)
+	{
+		const GLC_Point3d currentPoint(pointsList.at(i));
+		data[i * 3]= static_cast<float>(currentPoint.x());
+		data[i * 3 + 1]= static_cast<float>(currentPoint.y());
+		data[i * 3 + 2]= static_cast<float>(currentPoint.z());
+	}
+	return GLC_Geometry::m_WireData.addVerticeGroup(data);
+}
+
+GLC_uint GLC_Polylines::addPolyline(const QList<GLC_Point3df>& pointsList)
+{
+	const int pointCount= pointsList.size();
+	const int size= pointCount * 3;
+	GLfloatVector data(size);
+	for (int i= 0; i < pointCount; ++i)
+	{
+		const GLC_Point3df currentPoint(pointsList.at(i));
+		data[i * 3]= currentPoint.x();
+		data[i * 3 + 1]= currentPoint.y();
+		data[i * 3 + 2]= currentPoint.z();
+	}
+	return GLC_Geometry::m_WireData.addVerticeGroup(data);
+}
+
 GLC_Polylines& GLC_Polylines::operator=(const GLC_Polylines& polyline)
 {
 	if (this != &polyline)
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_polylines.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_polylines.h
index 9655c5cb2..545d5382a 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_polylines.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_polylines.h
@@ -74,10 +74,16 @@ public:
 //@{
 //////////////////////////////////////////////////////////////////////
 public:
-	//! Add a Polyline to this wire and returns its id if id are managed
+	//! Add a Polyline to this polylines and returns its id if id are managed
 	inline GLC_uint addPolyline(const GLfloatVector& data)
 	{return GLC_Geometry::m_WireData.addVerticeGroup(data);}
 
+	//! Add polyline with the given list of points to this polylines and returns its id if id are managed
+	GLC_uint addPolyline(const QList<GLC_Point3d>& pointsList);
+
+	//! Add polyline with the given list of points to this polylines and returns its id if id are managed
+	GLC_uint addPolyline(const QList<GLC_Point3df>& pointsList);
+
 	//! Set this polylines from the given polylines and return a reference of this polylines
 	GLC_Polylines& operator=(const GLC_Polylines& polyline);
 
@@ -91,7 +97,7 @@ public:
 /*! \name OpenGL Functions*/
 //@{
 //////////////////////////////////////////////////////////////////////
-private:
+protected:
 
 	//! Virtual interface for OpenGL Geometry set up.
 	/*! This Virtual function is implemented here.\n
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_primitivegroup.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_primitivegroup.cpp
index db13e07e3..bae3546f6 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_primitivegroup.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_primitivegroup.cpp
@@ -189,13 +189,12 @@ void GLC_PrimitiveGroup::addTrianglesStrip(const IndexList& input, GLC_uint id)
 // Set the triangle index offset
 void GLC_PrimitiveGroup::setTrianglesOffset(GLvoid* pOffset)
 {
-	m_TrianglesGroupOffseti.pop_back();
+	//m_TrianglesGroupOffseti.pop_back();
 	const int size= m_TrianglesGroupOffseti.size();
 	for (int i= 0; i < size; ++i)
 	{
 		m_TrianglesGroupOffset.append(BUFFER_OFFSET(static_cast<GLsizei>(m_TrianglesGroupOffseti[i]) * sizeof(GLuint) + reinterpret_cast<GLsizeiptr>(pOffset)));
 	}
-	m_TrianglesGroupOffseti.clear();
 }
 
 // Set the triangle index offset
@@ -212,13 +211,12 @@ void GLC_PrimitiveGroup::setTrianglesOffseti(int offset)
 // Set base triangle strip offset
 void GLC_PrimitiveGroup::setBaseTrianglesStripOffset(GLvoid* pOffset)
 {
-	m_StripIndexOffseti.pop_back();
+	//m_StripIndexOffseti.pop_back();
 	const int size= m_StripIndexOffseti.size();
 	for (int i= 0; i < size; ++i)
 	{
 		m_StripIndexOffset.append(BUFFER_OFFSET(static_cast<GLsizei>(m_StripIndexOffseti[i]) * sizeof(GLuint) + reinterpret_cast<GLsizeiptr>(pOffset)));
 	}
-	m_StripIndexOffseti.clear();
 }
 
 // Set base triangle strip offset
@@ -257,13 +255,12 @@ void GLC_PrimitiveGroup::addTrianglesFan(const IndexList& input, GLC_uint id)
 // Set base triangle fan offset
 void GLC_PrimitiveGroup::setBaseTrianglesFanOffset(GLvoid* pOffset)
 {
-	m_FanIndexOffseti.pop_back();
+	//m_FanIndexOffseti.pop_back();
 	const int size= m_FanIndexOffseti.size();
 	for (int i= 0; i < size; ++i)
 	{
 		m_FanIndexOffset.append(BUFFER_OFFSET(static_cast<GLsizei>(m_FanIndexOffseti[i]) * sizeof(GLuint) + reinterpret_cast<GLsizeiptr>(pOffset)));
 	}
-	m_FanIndexOffseti.clear();
 }
 
 // Set base triangle fan offset
@@ -278,16 +275,14 @@ void GLC_PrimitiveGroup::setBaseTrianglesFanOffseti(int offset)
 }
 
 // Change index to VBO mode
-void GLC_PrimitiveGroup::changeToVboMode()
+void GLC_PrimitiveGroup::computeVboOffset()
 {
-
 	m_TrianglesGroupOffset.clear();
 	const int triangleOffsetSize= m_TrianglesGroupOffseti.size();
 	for (int i= 0; i < triangleOffsetSize; ++i)
 	{
 		m_TrianglesGroupOffset.append(BUFFER_OFFSET(static_cast<GLsizei>(m_TrianglesGroupOffseti.at(i)) * sizeof(GLuint)));
 	}
-	m_TrianglesGroupOffseti.clear();
 
 	m_StripIndexOffset.clear();
 	const int stripOffsetSize= m_StripIndexOffseti.size();
@@ -295,7 +290,6 @@ void GLC_PrimitiveGroup::changeToVboMode()
 	{
 		m_StripIndexOffset.append(BUFFER_OFFSET(static_cast<GLsizei>(m_StripIndexOffseti.at(i)) * sizeof(GLuint)));
 	}
-	m_StripIndexOffseti.clear();
 
 	m_FanIndexOffset.clear();
 	const int fanOffsetSize= m_FanIndexOffseti.size();
@@ -303,7 +297,6 @@ void GLC_PrimitiveGroup::changeToVboMode()
 	{
 		m_FanIndexOffset.append(BUFFER_OFFSET(static_cast<GLsizei>(m_FanIndexOffseti.at(i)) * sizeof(GLuint)));
 	}
-	m_FanIndexOffseti.clear();
 }
 
 // Clear the group
@@ -345,35 +338,10 @@ QDataStream &operator<<(QDataStream &stream, const GLC_PrimitiveGroup &primitive
 	OffsetVectori fanIndexOffseti;
 
 	// Get triangles, strips and fans offset
-	if (GLC_State::vboUsed())
-	{
-		// Convert offset to index
-		// Triangles offset
-		const int triangleIndexOffsetSize= primitiveGroup.m_TrianglesGroupOffset.size();
-		for (int i= 0; i < triangleIndexOffsetSize; ++i)
-		{
-			trianglesGroupOffseti.append(static_cast<GLuint>(reinterpret_cast<GLsizeiptr>(primitiveGroup.m_TrianglesGroupOffset.at(i)) / sizeof(GLuint)));
-		}
+	trianglesGroupOffseti= primitiveGroup.m_TrianglesGroupOffseti;
+	stripIndexOffseti= primitiveGroup.m_StripIndexOffseti;
+	fanIndexOffseti= primitiveGroup.m_FanIndexOffseti;
 
-		// Trips offsets
-		const int stripIndexOffsetSize= primitiveGroup.m_StripIndexOffset.size();
-		for (int i= 0; i < stripIndexOffsetSize; ++i)
-		{
-			stripIndexOffseti.append(static_cast<GLuint>(reinterpret_cast<GLsizeiptr>(primitiveGroup.m_StripIndexOffset.at(i)) / sizeof(GLuint)));
-		}
-		// Fans offsets
-		const int fanIndexOffsetSize= primitiveGroup.m_FanIndexOffset.size();
-		for (int i= 0; i < fanIndexOffsetSize; ++i)
-		{
-			fanIndexOffseti.append(static_cast<GLuint>(reinterpret_cast<GLsizeiptr>(primitiveGroup.m_FanIndexOffset.at(i)) / sizeof(GLuint)));
-		}
-	}
-	else
-	{
-		trianglesGroupOffseti= primitiveGroup.m_TrianglesGroupOffseti;
-		stripIndexOffseti= primitiveGroup.m_StripIndexOffseti;
-		fanIndexOffseti= primitiveGroup.m_FanIndexOffseti;
-	}
 	// Triangles index
 	stream << primitiveGroup.m_TrianglesIndexSize;
 	stream << trianglesGroupOffseti;
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_primitivegroup.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_primitivegroup.h
index f367ca17d..93ec228a6 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_primitivegroup.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_primitivegroup.h
@@ -28,7 +28,7 @@
 #include "../glc_ext.h"
 #include "../glc_global.h"
 
-#include "glc_config.h"
+#include "../glc_config.h"
 
 //////////////////////////////////////////////////////////////////////
 //! \class GLC_PrimitiveGroup
@@ -231,8 +231,8 @@ public:
 	//! Set base triangle fan offset
 	void setBaseTrianglesFanOffseti(int);
 
-	//! Change index to VBO mode
-	void changeToVboMode();
+	//! Compute VBO offset
+	void computeVboOffset();
 
 	//! The mesh wich use this group is finished
 	inline void finish()
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_sphere.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_sphere.cpp
index fdd7f70e2..5c2a70400 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_sphere.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_sphere.cpp
@@ -36,7 +36,7 @@ GLC_Sphere::GLC_Sphere(double radius)
 , m_PhiMin(-glc::PI / 2.0)
 , m_PhiMax(glc::PI / 2.0)
 {
-
+	createMesh();
 }
 
 
@@ -49,7 +49,7 @@ GLC_Sphere::GLC_Sphere(const GLC_Sphere & sphere)
 , m_PhiMin(sphere.m_PhiMin)
 , m_PhiMax(sphere.m_PhiMax)
 {
-
+	createMesh();
 }
 
 GLC_Sphere::~GLC_Sphere()
@@ -92,8 +92,19 @@ void GLC_Sphere::setDiscretion(int TargetDiscret)
 	}
 }
 
+void GLC_Sphere::glDraw(const GLC_RenderProperties& renderProperties)
+{
+	if (GLC_Mesh::isEmpty())
+	{
+		createMesh();
+	}
+
+	GLC_Mesh::glDraw(renderProperties);
+}
+
 void GLC_Sphere::createMesh()
 {
+
 	Q_ASSERT(GLC_Mesh::isEmpty());
 
 	GLfloatVector verticeFloat;
@@ -153,8 +164,8 @@ void GLC_Sphere::createMesh()
 			xf= m_Radius * cost * cospp;
 			yf= m_Radius * sint * cospp;
 
-			verticeFloat << xi << yi << zi << xf << yf << zf;
- 			normalsFloat << cost * cosp << sint * cosp << sinp << cost * cospp << sint * cospp << sinpp ;
+			verticeFloat << xf << yf << zf << xi << yi << zi;
+			normalsFloat << cost * cospp << sint * cospp << sinpp << cost * cosp << sint * cosp << sinp;
  			texelVector << static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps)
 						<< static_cast<double>(p) * 1.0 / static_cast<double>(nbPhiSteps)
 						<< static_cast<double>(t) * 1.0 / static_cast<double>(nbThetaSteps)
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_sphere.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_sphere.h
index 2b1cafc04..4523f88e5 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_sphere.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_sphere.h
@@ -90,6 +90,17 @@ public:
 
 //@}
 
+//////////////////////////////////////////////////////////////////////
+/*! \name OpenGL Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+private:
+	//! Virtual interface for OpenGL Geometry set up.
+	/*! This Virtual function is implemented here.\n
+	 *  Throw GLC_OpenGlException*/
+	virtual void glDraw(const GLC_RenderProperties&);
+//@}
+
 //////////////////////////////////////////////////////////////////////
 /*! \name Private services Functions*/
 //@{
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_wiredata.cpp b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_wiredata.cpp
index c2c8bcfbe..69b61121e 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_wiredata.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_wiredata.cpp
@@ -23,38 +23,55 @@
 //! \file glc_wiredata.cpp Implementation for the GLC_WireData class.
 
 #include "glc_wiredata.h"
+#include "glc_bsrep.h"
 #include "../glc_ext.h"
 #include "../glc_state.h"
+#include "../glc_exception.h"
 
 // Class chunk id
-quint32 GLC_WireData::m_ChunkId= 0xA706;
+// Old chunkId = 0xA706
+quint32 GLC_WireData::m_ChunkId= 0xA711;
 
 
 GLC_WireData::GLC_WireData()
-: m_VboId(0)
+: m_VerticeBuffer()
 , m_NextPrimitiveLocalId(1)
 , m_Positions()
+, m_ColorBuffer()
+, m_Colors()
+, m_IndexBuffer(QGLBuffer::IndexBuffer)
+, m_IndexVector()
 , m_PositionSize(0)
+, m_ColorSize(0)
 , m_pBoundingBox(NULL)
 , m_VerticeGrouprSizes()
+, m_VerticeGroupOffseti()
 , m_VerticeGroupOffset()
 , m_VerticeGroupId()
 , m_VerticeGroupCount(0)
+, m_UseVbo(false)
 {
 
 }
 
 
 GLC_WireData::GLC_WireData(const GLC_WireData& data)
-: m_VboId(0)
+: m_VerticeBuffer()
 , m_NextPrimitiveLocalId(data.m_NextPrimitiveLocalId)
 , m_Positions(data.positionVector())
+, m_ColorBuffer()
+, m_Colors(data.colorVector())
+, m_IndexBuffer(QGLBuffer::IndexBuffer)
+, m_IndexVector(data.indexVector())
 , m_PositionSize(data.m_PositionSize)
+, m_ColorSize(data.m_ColorSize)
 , m_pBoundingBox(NULL)
 , m_VerticeGrouprSizes(data.m_VerticeGrouprSizes)
+, m_VerticeGroupOffseti(data.m_VerticeGroupOffseti)
 , m_VerticeGroupOffset(data.m_VerticeGroupOffset)
 , m_VerticeGroupId(data.m_VerticeGroupId)
 , m_VerticeGroupCount(data.m_VerticeGroupCount)
+, m_UseVbo(data.m_UseVbo)
 {
 	if (NULL != data.m_pBoundingBox)
 	{
@@ -70,15 +87,20 @@ GLC_WireData& GLC_WireData::operator=(const GLC_WireData& data)
 		clear();
 		m_NextPrimitiveLocalId= data.m_NextPrimitiveLocalId;
 		m_Positions= data.positionVector();
+		m_Colors= data.colorVector();
+		m_IndexVector= data.indexVector();
 		m_PositionSize= data.m_PositionSize;
+		m_ColorSize= data.m_ColorSize;
 		if (NULL != data.m_pBoundingBox)
 		{
 			m_pBoundingBox= new GLC_BoundingBox(*(data.m_pBoundingBox));
 		}
 		m_VerticeGrouprSizes= data.m_VerticeGrouprSizes;
+		m_VerticeGroupOffseti= data.m_VerticeGroupOffseti;
 		m_VerticeGroupOffset= data.m_VerticeGroupOffset;
 		m_VerticeGroupId= data.m_VerticeGroupId;
 		m_VerticeGroupCount= data.m_VerticeGroupCount;
+		m_UseVbo= data.m_UseVbo;
 	}
 	return *this;
 }
@@ -86,13 +108,6 @@ GLC_WireData& GLC_WireData::operator=(const GLC_WireData& data)
 GLC_WireData::~GLC_WireData()
 {
 	clear();
-
-	// Delete Main Vbo ID
-	if (0 != m_VboId)
-	{
-		glDeleteBuffers(1, &m_VboId);
-		m_VboId= 0;
-	}
 }
 //////////////////////////////////////////////////////////////////////
 // Get Functions
@@ -107,18 +122,19 @@ quint32 GLC_WireData::chunckID()
 
 GLfloatVector GLC_WireData::positionVector() const
 {
-	if (0 != m_VboId)
+	if (m_VerticeBuffer.isCreated())
 	{
+		Q_ASSERT((NULL != QGLContext::currentContext()) &&  QGLContext::currentContext()->isValid());
 		// VBO created get data from VBO
 		const int sizeOfVbo= m_PositionSize;
 		const GLsizeiptr dataSize= sizeOfVbo * sizeof(float);
 		GLfloatVector positionVector(sizeOfVbo);
 
-		glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
-		GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
+		const_cast<QGLBuffer&>(m_VerticeBuffer).bind();
+		GLvoid* pVbo = const_cast<QGLBuffer&>(m_VerticeBuffer).map(QGLBuffer::ReadOnly);
 		memcpy(positionVector.data(), pVbo, dataSize);
-		glUnmapBuffer(GL_ARRAY_BUFFER);
-		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		const_cast<QGLBuffer&>(m_VerticeBuffer).unmap();
+		const_cast<QGLBuffer&>(m_VerticeBuffer).release();
 		return positionVector;
 	}
 	else
@@ -127,6 +143,51 @@ GLfloatVector GLC_WireData::positionVector() const
 	}
 }
 
+// Return the color Vector
+GLfloatVector GLC_WireData::colorVector() const
+{
+	if (m_ColorBuffer.isCreated())
+	{
+		// VBO created get data from VBO
+		const int sizeOfVbo= m_ColorSize;
+		const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
+		GLfloatVector normalVector(sizeOfVbo);
+
+		const_cast<QGLBuffer&>(m_ColorBuffer).bind();
+		GLvoid* pVbo = const_cast<QGLBuffer&>(m_ColorBuffer).map(QGLBuffer::ReadOnly);
+		memcpy(normalVector.data(), pVbo, dataSize);
+		const_cast<QGLBuffer&>(m_ColorBuffer).unmap();
+		const_cast<QGLBuffer&>(m_ColorBuffer).release();
+		return normalVector;
+	}
+	else
+	{
+		return m_Colors;
+	}
+}
+
+QVector<GLuint> GLC_WireData::indexVector() const
+{
+	if (m_IndexBuffer.isCreated())
+	{
+		// VBO created get data from VBO
+		const int sizeOfIbo= m_PositionSize / 3;
+		const GLsizeiptr dataSize= sizeOfIbo * sizeof(GLuint);
+		QVector<GLuint> indexVector(sizeOfIbo);
+
+		const_cast<QGLBuffer&>(m_IndexBuffer).bind();
+		GLvoid* pIbo = const_cast<QGLBuffer&>(m_IndexBuffer).map(QGLBuffer::ReadOnly);
+		memcpy(indexVector.data(), pIbo, dataSize);
+		const_cast<QGLBuffer&>(m_IndexBuffer).unmap();
+		const_cast<QGLBuffer&>(m_IndexBuffer).release();
+		return indexVector;
+	}
+	else
+	{
+		return m_IndexVector;
+	}
+}
+
 
 GLC_BoundingBox& GLC_WireData::boundingBox()
 {
@@ -141,10 +202,26 @@ GLC_BoundingBox& GLC_WireData::boundingBox()
 		else
 		{
 			const int max= m_Positions.size();
-			for (int i= 0; i < max; i= i + 3)
+			if (max == 3) // Only One point
 			{
-				GLC_Point3d point(m_Positions[i], m_Positions[i + 1], m_Positions[i + 2]);
-				m_pBoundingBox->combine(point);
+				const double delta= 1e-2;
+				GLC_Point3d lower(m_Positions[0] - delta,
+						m_Positions[1] - delta,
+						m_Positions[2] - delta);
+				GLC_Point3d upper(m_Positions[0] + delta,
+						m_Positions[1] + delta,
+						m_Positions[2] + delta);
+				m_pBoundingBox->combine(lower);
+				m_pBoundingBox->combine(upper);
+
+			}
+			else
+			{
+				for (int i= 0; i < max; i= i + 3)
+				{
+					GLC_Point3d point(m_Positions[i], m_Positions[i + 1], m_Positions[i + 2]);
+					m_pBoundingBox->combine(point);
+				}
 			}
 		}
 
@@ -166,12 +243,12 @@ GLC_uint GLC_WireData::addVerticeGroup(const GLfloatVector& floatVector)
 
 	m_VerticeGrouprSizes.append(static_cast<GLsizei>(floatVector.size() / 3));
 
-	if (m_VerticeGroupOffset.isEmpty())
+	if (m_VerticeGroupOffseti.isEmpty())
 	{
-		m_VerticeGroupOffset.append(0);
+		m_VerticeGroupOffseti.append(0);
 	}
-	int offset= m_VerticeGroupOffset.last() + m_VerticeGrouprSizes.last();
-	m_VerticeGroupOffset.append(offset);
+	int offset= m_VerticeGroupOffseti.last() + m_VerticeGrouprSizes.last();
+	m_VerticeGroupOffseti.append(offset);
 
 	// The Polyline id
 	m_VerticeGroupId.append(m_NextPrimitiveLocalId);
@@ -180,6 +257,7 @@ GLC_uint GLC_WireData::addVerticeGroup(const GLfloatVector& floatVector)
 
 void GLC_WireData::clear()
 {
+	m_VerticeBuffer.destroy();
 	m_NextPrimitiveLocalId= 1;
 	m_Positions.clear();
 	m_PositionSize= 0;
@@ -187,27 +265,54 @@ void GLC_WireData::clear()
 	m_pBoundingBox= NULL;
 
 	m_VerticeGrouprSizes.clear();
-	m_VerticeGroupOffset.clear();
+	m_VerticeGroupOffseti.clear();
 	m_VerticeGroupId.clear();
 	m_VerticeGroupCount= 0;
 }
 
 void GLC_WireData::copyVboToClientSide()
 {
-	if ((0 != m_VboId) && m_Positions.isEmpty())
+	if (m_VerticeBuffer.isCreated() && m_Positions.isEmpty())
 	{
 		m_Positions= positionVector();
+
+		if (m_ColorBuffer.isCreated() && m_Colors.isEmpty())
+		{
+			m_Colors= colorVector();
+		}
+		m_IndexVector= indexVector();
 	}
+
 }
 
 void GLC_WireData::releaseVboClientSide(bool update)
 {
-	if ((0 != m_VboId) && !m_Positions.isEmpty())
+	if (m_VerticeBuffer.isCreated() && !m_Positions.isEmpty())
 	{
 		if (update) finishVbo();
 	}
 }
 
+void GLC_WireData::setVboUsage(bool usage)
+{
+	m_UseVbo= usage;
+	if (!isEmpty())
+	{
+		if (m_UseVbo && (m_PositionSize != 0) && (!m_Positions.isEmpty())&& (!m_VerticeBuffer.isCreated()))
+		{
+			finishVbo();
+		}
+		else if (!m_UseVbo && m_VerticeBuffer.isCreated())
+		{
+			m_Positions= positionVector();
+			m_VerticeBuffer.destroy();
+			m_Colors= colorVector();
+			m_ColorBuffer.destroy();
+			m_IndexVector= indexVector();
+			m_IndexBuffer.destroy();
+		}
+	}
+}
 
 //////////////////////////////////////////////////////////////////////
 // OpenGL Functions
@@ -215,82 +320,212 @@ void GLC_WireData::releaseVboClientSide(bool update)
 
 void GLC_WireData::finishVbo()
 {
-	createVBOs();
-	useVBO(true);
+	Q_ASSERT((NULL != QGLContext::currentContext()) &&  QGLContext::currentContext()->isValid());
+	if (!m_VerticeBuffer.isCreated())
+	{
+		m_VerticeBuffer.create();
+	}
+	if ((m_Colors.size() > 0) && !m_ColorBuffer.isCreated())
+	{
+		m_ColorBuffer.create();
+	}
+	if (!m_IndexBuffer.isCreated())
+	{
+		m_IndexBuffer.create();
+	}
 	fillVBOs();
-	useVBO(false);
 
 	m_PositionSize= m_Positions.size();
 	m_Positions.clear();
+
+	m_IndexVector.clear();
+
+	if (m_ColorBuffer.isCreated())
+	{
+		m_ColorSize= m_Colors.size();
+		m_Colors.clear();
+	}
 }
 
-void GLC_WireData::useVBO(bool use)
+void GLC_WireData::useVBO(GLC_WireData::VboType type, bool use)
 {
 	if (use)
 	{
-		glBindBuffer(GL_ARRAY_BUFFER, m_VboId);	}
+
+		// Chose the right VBO
+		if (type == GLC_WireData::GLC_Vertex)
+		{
+			if (!m_VerticeBuffer.bind())
+			{
+				GLC_Exception exception("GLC_WireData::useVBO  Failed to bind vertex buffer");
+				throw(exception);
+			}
+		}
+		else if (type == GLC_WireData::GLC_Color)
+		{
+			Q_ASSERT(m_ColorSize > 0);
+			if (!m_ColorBuffer.bind())
+			{
+				GLC_Exception exception("GLC_WireData::useVBO  Failed to bind color buffer");
+				throw(exception);
+			}
+		}
+		else if ((type == GLC_WireData::GLC_Index) && m_IndexBuffer.isCreated())
+		{
+			if (!m_IndexBuffer.bind())
+			{
+				GLC_Exception exception("GLC_WireData::useVBO  Failed to bind index buffer");
+				throw(exception);
+			}
+		}
+	}
 	else
 	{
-		// Unbind VBO
-		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		QGLBuffer::release(QGLBuffer::VertexBuffer);
+		QGLBuffer::release(QGLBuffer::IndexBuffer);
 	}
 }
 
 void GLC_WireData::glDraw(const GLC_RenderProperties&, GLenum mode)
 {
+	Q_ASSERT((NULL != QGLContext::currentContext()) &&  QGLContext::currentContext()->isValid());
 	Q_ASSERT(!isEmpty());
-	const bool vboIsUsed= GLC_State::vboUsed();
 
-	if (vboIsUsed && ((m_PositionSize == 0) || (0 == m_VboId)))
+	const bool vboIsUsed= m_UseVbo  && GLC_State::vboSupported();
+
+	if (vboIsUsed && ((m_PositionSize == 0) || !m_VerticeBuffer.isCreated()))
 	{
+		finishOffset();
+		buidIndex();
 		finishVbo();
 	}
-	else if (m_PositionSize == 0)
+	else if (!vboIsUsed && (m_PositionSize == 0))
 	{
+		finishOffset();
+		buidIndex();
 		m_PositionSize= m_Positions.size();
+		m_ColorSize= m_Colors.size();
 	}
 
 	// Activate VBO or Vertex Array
 	if (vboIsUsed)
 	{
-		useVBO(true);
+		activateVboAndIbo();
 		glVertexPointer(3, GL_FLOAT, 0, 0);
+		glEnableClientState(GL_VERTEX_ARRAY);
+		if (m_ColorSize > 0)
+		{
+			glColorPointer(4, GL_FLOAT, 0, 0);
+			glEnableClientState(GL_COLOR_ARRAY);
+		}
+
+		// Render polylines
+		for (int i= 0; i < m_VerticeGroupCount; ++i)
+		{
+			glDrawElements(mode, m_VerticeGrouprSizes.at(i), GL_UNSIGNED_INT, m_VerticeGroupOffset.at(i));
+		}
+
+		useVBO(GLC_WireData::GLC_Index, false);
 	}
 	else
 	{
 		glVertexPointer(3, GL_FLOAT, 0, m_Positions.data());
-	}
-	glEnableClientState(GL_VERTEX_ARRAY);
+		glEnableClientState(GL_VERTEX_ARRAY);
+		if (m_ColorSize > 0)
+		{
+			glColorPointer(4, GL_FLOAT, 0, m_Colors.data());
+			glEnableClientState(GL_COLOR_ARRAY);
+		}
+		// Render polylines
+		for (int i= 0; i < m_VerticeGroupCount; ++i)
+		{
+			glDrawElements(mode, m_VerticeGrouprSizes.at(i), GL_UNSIGNED_INT, &(m_IndexVector.data()[m_VerticeGroupOffseti.at(i)]));
+		}
 
-	// Render polylines
-	for (int i= 0; i < m_VerticeGroupCount; ++i)
-	{
-		glDrawArrays(mode, m_VerticeGroupOffset.at(i), m_VerticeGrouprSizes.at(i));
 	}
 
-	// Desactivate VBO or Vertex Array
-	if (vboIsUsed)
+	if (m_ColorSize > 0)
 	{
-		useVBO(false);
+		glDisableClientState(GL_COLOR_ARRAY);
 	}
 
 	glDisableClientState(GL_VERTEX_ARRAY);
-}
 
-void GLC_WireData::createVBOs()
-{
-	// Create position VBO
-	if (0 == m_VboId)
+	if (vboIsUsed)
 	{
-		glGenBuffers(1, &m_VboId);
+		QGLBuffer::release(QGLBuffer::IndexBuffer);
+		QGLBuffer::release(QGLBuffer::VertexBuffer);
 	}
 }
 
+
 void GLC_WireData::fillVBOs()
 {
-	const GLsizei dataNbr= static_cast<GLsizei>(m_Positions.size());
-	const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
-	glBufferData(GL_ARRAY_BUFFER, dataSize, m_Positions.data(), GL_STATIC_DRAW);
+	{
+		Q_ASSERT(m_VerticeBuffer.isCreated());
+		useVBO(GLC_WireData::GLC_Vertex, true);
+		const GLsizei dataNbr= static_cast<GLsizei>(m_Positions.size());
+		const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
+		m_VerticeBuffer.allocate(m_Positions.data(), dataSize);
+	}
+
+	{
+		Q_ASSERT(m_IndexBuffer.isCreated());
+		useVBO(GLC_WireData::GLC_Index, true);
+		const GLsizei dataNbr= static_cast<GLsizei>(m_IndexVector.size());
+		const GLsizeiptr dataSize= dataNbr * sizeof(GLuint);
+		m_IndexBuffer.allocate(m_IndexVector.data(), dataSize);
+	}
+
+	if (m_ColorBuffer.isCreated())
+	{
+		useVBO(GLC_WireData::GLC_Color, true);
+		const GLsizei dataNbr= static_cast<GLsizei>(m_Colors.size());
+		const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
+		m_ColorBuffer.allocate(m_Colors.data(), dataSize);
+	}
+}
+
+void GLC_WireData::buidIndex()
+{
+	const int size= m_Positions.size();
+	m_IndexVector.resize(size);
+	for (int i= 0; i < size; ++i)
+	{
+		m_IndexVector[i]= i;
+	}
+}
+
+void GLC_WireData::activateVboAndIbo()
+{
+	// Activate Vertices VBO
+	useVBO(GLC_WireData::GLC_Vertex, true);
+	glVertexPointer(3, GL_FLOAT, 0, 0);
+	glEnableClientState(GL_VERTEX_ARRAY);
+
+	// Activate Color VBO if needed
+	if (m_ColorSize > 0)
+	{
+		useVBO(GLC_WireData::GLC_Color, true);
+		glEnable(GL_COLOR_MATERIAL);
+		glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+		glColorPointer(4, GL_FLOAT, 0, 0);
+		glEnableClientState(GL_COLOR_ARRAY);
+	}
+
+	// Activate index Buffer object
+	useVBO(GLC_WireData::GLC_Index, true);
+}
+
+void GLC_WireData::finishOffset()
+{
+	m_VerticeGroupOffseti.remove(m_VerticeGroupOffseti.size() - 1);
+	m_VerticeGroupOffset.clear();
+	const int offsetSize= m_VerticeGroupOffseti.size();
+	for (int i= 0; i < offsetSize; ++i)
+	{
+		m_VerticeGroupOffset.append(BUFFER_OFFSET(static_cast<GLsizei>(m_VerticeGroupOffseti.at(i)) * sizeof(GLuint)));
+	}
 }
 
 QDataStream &operator<<(QDataStream &stream, const GLC_WireData &wireData)
@@ -303,10 +538,14 @@ QDataStream &operator<<(QDataStream &stream, const GLC_WireData &wireData)
 	stream << wireData.m_PositionSize;
 
 	stream << wireData.m_VerticeGrouprSizes;
-	stream << wireData.m_VerticeGroupOffset;
+	stream << wireData.m_VerticeGroupOffseti;
 	stream << wireData.m_VerticeGroupId;
 	stream << wireData.m_VerticeGroupCount;
 
+	// New version Data
+	stream << wireData.colorVector();
+	stream << wireData.m_ColorSize;
+
 	return stream;
 }
 
@@ -314,7 +553,7 @@ QDataStream &operator>>(QDataStream &stream, GLC_WireData &wireData)
 {
 	quint32 chunckId;
 	stream >> chunckId;
-	Q_ASSERT(chunckId == GLC_WireData::m_ChunkId);
+	Q_ASSERT((chunckId == GLC_WireData::m_ChunkId) || chunckId == 0xA706);
 
 	wireData.clear();
 	stream >> wireData.m_NextPrimitiveLocalId;
@@ -322,9 +561,16 @@ QDataStream &operator>>(QDataStream &stream, GLC_WireData &wireData)
 	stream >> wireData.m_PositionSize;
 
 	stream >> wireData.m_VerticeGrouprSizes;
-	stream >> wireData.m_VerticeGroupOffset;
+	stream >> wireData.m_VerticeGroupOffseti;
 	stream >> wireData.m_VerticeGroupId;
 	stream >> wireData.m_VerticeGroupCount;
 
+	if (chunckId == GLC_WireData::m_ChunkId)
+	{
+		// New version Data
+		stream >> wireData.m_Colors;
+		stream >> wireData.m_ColorSize;
+	}
+
 	return stream;
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_wiredata.h b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_wiredata.h
index 438d0a534..b4b384c72 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_wiredata.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/geometry/glc_wiredata.h
@@ -25,6 +25,8 @@
 #define GLC_WIREDATA_H_
 
 #include <QColor>
+#include <QGLBuffer>
+
 #include "../glc_global.h"
 #include "../glc_boundingbox.h"
 #include "../shading/glc_renderproperties.h"
@@ -40,6 +42,14 @@ class GLC_LIB_EXPORT GLC_WireData
 	friend GLC_LIB_EXPORT QDataStream &operator<<(QDataStream &, const GLC_WireData &);
 	friend GLC_LIB_EXPORT QDataStream &operator>>(QDataStream &, GLC_WireData &);
 
+	//! Enum of VBO TYPE
+	enum VboType
+	{
+		GLC_Vertex= 30,
+		GLC_Color,
+		GLC_Index
+	};
+
 //////////////////////////////////////////////////////////////////////
 /*! @name Constructor / Destructor */
 //@{
@@ -69,6 +79,12 @@ public:
 	//! Return this wire data Position Vector
 	GLfloatVector positionVector() const;
 
+	//! Return the color Vector
+	GLfloatVector colorVector() const;
+
+	//! Return the unique index vector
+	QVector<GLuint> indexVector() const;
+
 	//! Return true if this wire data is empty
 	inline bool isEmpty() const
 	{return ((m_PositionSize == 0) && m_Positions.isEmpty());}
@@ -82,12 +98,15 @@ public:
 
 	//! Return the vertice group offset from the given index
 	inline GLuint verticeGroupOffset(int index) const
-	{return m_VerticeGroupOffset.at(index);}
+	{return m_VerticeGroupOffseti.at(index);}
 
 	//! Return the vertice group size from the given index
 	inline GLsizei verticeGroupSize(int index) const
 	{return m_VerticeGrouprSizes.at(index);}
 
+	//! Return true if this wire data use indexed colors
+	inline bool useIndexdColors() const
+	{return (m_ColorSize > 0) || (m_Colors.size() > 0);}
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -98,6 +117,10 @@ public:
 	//! Add a Polyline to this wire and returns its id if id are managed
 	GLC_uint addVerticeGroup(const GLfloatVector&);
 
+	//! Add Colors
+	inline void addColors(const GLfloatVector& colors)
+	{m_Colors+= colors;}
+
 	//! Clear the content of this wire Data and makes it empty
 	void clear();
 
@@ -107,6 +130,9 @@ public:
 	//! Release client VBO
 	void releaseVboClientSide(bool update= false);
 
+	//! Set VBO usage
+	void setVboUsage(bool usage);
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -118,18 +144,25 @@ public:
 	void finishVbo();
 
 	//! Set vbo usage of this wire data
-	void useVBO(bool usage);
+	void useVBO(GLC_WireData::VboType type, bool usage);
 
 	//! Render this wire data using Opengl
 	/*! The mode can be : GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP GL_LINES*/
 	void glDraw(const GLC_RenderProperties&, GLenum mode);
 
 private:
-	//! Create this wire data VBO id
-	void createVBOs();
 
 	//! Fill this wire data VBO from memmory
 	void fillVBOs();
+
+	//! Built index
+	void buidIndex();
+
+	//! Activate VBO and IBO
+	void activateVboAndIbo();
+
+	//! Finish offset
+	void finishOffset();
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -137,7 +170,7 @@ private:
 //////////////////////////////////////////////////////////////////////
 private:
 	//! VBO ID
-	GLuint m_VboId;
+	QGLBuffer m_VerticeBuffer;
 
 	//! The next primitive local id
 	GLC_uint m_NextPrimitiveLocalId;
@@ -145,9 +178,24 @@ private:
 	//! Vertex Position Vector
 	GLfloatVector m_Positions;
 
+	//! Color Buffer
+	QGLBuffer m_ColorBuffer;
+
+	//! Color index
+	GLfloatVector m_Colors;
+
+	//! The Index Buffer
+	QGLBuffer m_IndexBuffer;
+
+	//! The Index Vector
+	QVector<GLuint> m_IndexVector;
+
 	//! The size of the VBO
 	int m_PositionSize;
 
+	//! The size of Color VBO
+	int m_ColorSize;
+
 	//! Wire data bounding box
 	GLC_BoundingBox* m_pBoundingBox;
 
@@ -155,7 +203,10 @@ private:
 	IndexSizes m_VerticeGrouprSizes;
 
 	//! Vector of vertice group offset
-	OffsetVectori m_VerticeGroupOffset;
+	OffsetVectori m_VerticeGroupOffseti;
+
+	//! VBO Vector of vertice group offset
+	OffsetVector m_VerticeGroupOffset;
 
 	//! Vertice groups id
 	QList<GLC_uint> m_VerticeGroupId;
@@ -163,6 +214,9 @@ private:
 	//! The number of vertice group
 	int m_VerticeGroupCount;
 
+	//! VBO usage
+	bool m_UseVbo;
+
 	//! Class chunk id
 	static quint32 m_ChunkId;
 };
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_cachemanager.cpp b/ground/openpilotgcs/src/libs/glc_lib/glc_cachemanager.cpp
index 4e33c40c2..a644c9be6 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_cachemanager.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_cachemanager.cpp
@@ -19,6 +19,7 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
  *****************************************************************************/
+//! \file glc_cachemanager.cpp implementation of the GLC_CacheManager class.
 
 #include "glc_cachemanager.h"
 #include <QtDebug>
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_context.cpp b/ground/openpilotgcs/src/libs/glc_lib/glc_context.cpp
new file mode 100644
index 000000000..48c43b9fc
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_context.cpp
@@ -0,0 +1,289 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************************/
+//! \file glc_context.cpp implementation of the GLC_Context class.
+
+#include "glc_context.h"
+#include "glc_contextmanager.h"
+#include "shading/glc_shader.h"
+
+#include "glc_state.h"
+
+GLC_Context* GLC_Context::m_pCurrentContext= NULL;
+
+GLC_Context::GLC_Context(const QGLFormat& format)
+: QGLContext(format)
+, m_CurrentMatrixMode()
+, m_MatrixStackHash()
+, m_ContextSharedData()
+, m_UniformShaderData()
+, m_LightingIsEnable()
+{
+	qDebug() << "GLC_Context::GLC_Context";
+	GLC_ContextManager::instance()->addContext(this);
+	init();
+}
+
+GLC_Context::~GLC_Context()
+{
+	qDebug() << "GLC_Context::~GLC_Context()";
+	GLC_ContextManager::instance()->remove(this);
+	QHash<GLenum, QStack<GLC_Matrix4x4>* >::iterator iStack= m_MatrixStackHash.begin();
+	while (iStack != m_MatrixStackHash.end())
+	{
+		delete iStack.value();
+		++iStack;
+	}
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Get Functions
+//////////////////////////////////////////////////////////////////////
+
+GLC_Context* GLC_Context::current()
+{
+	return m_pCurrentContext;
+}
+
+//////////////////////////////////////////////////////////////////////
+// OpenGL Functions
+//////////////////////////////////////////////////////////////////////
+void GLC_Context::glcMatrixMode(GLenum mode)
+{
+	Q_ASSERT(QGLContext::isValid());
+	Q_ASSERT((mode == GL_MODELVIEW) || (mode == GL_PROJECTION));
+
+	m_CurrentMatrixMode= mode;
+#ifdef GLC_OPENGL_ES_2
+
+#else
+	glMatrixMode(m_CurrentMatrixMode);
+#endif
+
+}
+
+void GLC_Context::glcLoadIdentity()
+{
+	Q_ASSERT(QGLContext::isValid());
+	m_MatrixStackHash.value(m_CurrentMatrixMode)->top().setToIdentity();
+
+#ifdef GLC_OPENGL_ES_2
+	m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
+#else
+	if (GLC_Shader::hasActiveShader())
+	{
+		m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
+	}
+	glLoadIdentity();
+#endif
+
+}
+
+void GLC_Context::glcPushMatrix()
+{
+	Q_ASSERT(QGLContext::isValid());
+	m_MatrixStackHash.value(m_CurrentMatrixMode)->push(m_MatrixStackHash.value(m_CurrentMatrixMode)->top());
+
+#ifndef GLC_OPENGL_ES_2
+	glPushMatrix();
+#endif
+
+}
+
+void GLC_Context::glcPopMatrix()
+{
+	Q_ASSERT(QGLContext::isValid());
+	m_MatrixStackHash.value(m_CurrentMatrixMode)->pop();
+
+#ifdef GLC_OPENGL_ES_2
+	this->glcLoadMatrix(m_MatrixStackHash.value(m_CurrentMatrixMode)->top());
+#else
+	if (GLC_Shader::hasActiveShader())
+	{
+		this->glcLoadMatrix(m_MatrixStackHash.value(m_CurrentMatrixMode)->top());
+	}
+	glPopMatrix();
+#endif
+
+}
+
+
+void GLC_Context::glcLoadMatrix(const GLC_Matrix4x4& matrix)
+{
+	m_MatrixStackHash.value(m_CurrentMatrixMode)->top()= matrix;
+
+#ifdef GLC_OPENGL_ES_2
+	m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
+#else
+	if (GLC_Shader::hasActiveShader())
+	{
+		m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
+	}
+	::glLoadMatrixd(matrix.getData());
+#endif
+
+}
+
+void GLC_Context::glcMultMatrix(const GLC_Matrix4x4& matrix)
+{
+	const GLC_Matrix4x4 current= m_MatrixStackHash.value(m_CurrentMatrixMode)->top();
+	m_MatrixStackHash.value(m_CurrentMatrixMode)->top()= m_MatrixStackHash.value(m_CurrentMatrixMode)->top() * matrix;
+#ifdef GLC_OPENGL_ES_2
+	m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
+#else
+	if (GLC_Shader::hasActiveShader())
+	{
+		m_UniformShaderData.setModelViewProjectionMatrix(m_MatrixStackHash.value(GL_MODELVIEW)->top(), m_MatrixStackHash.value(GL_PROJECTION)->top());
+	}
+	::glMultMatrixd(matrix.getData());
+#endif
+
+}
+
+void GLC_Context::glcScaled(double x, double y, double z)
+{
+	GLC_Matrix4x4 scale;
+	scale.setMatScaling(x, y, z);
+	glcMultMatrix(scale);
+}
+
+void GLC_Context::glcOrtho(double left, double right, double bottom, double top, double nearVal, double farVal)
+{
+	GLC_Matrix4x4 orthoMatrix;
+	double* m= orthoMatrix.setData();
+
+	const double tx= - (right + left) / (right - left);
+	const double ty= - (top + bottom) / (top - bottom);
+	const double tz= - (farVal + nearVal) / (farVal - nearVal);
+	m[0]= 2.0 / (right - left);
+	m[5]= 2.0 / (top - bottom);
+	m[10]= -2.0 / (farVal - nearVal);
+	m[12]= tx;
+	m[13]= ty;
+	m[14]= tz;
+
+	glcMultMatrix(orthoMatrix);
+}
+
+void GLC_Context::glcFrustum(double left, double right, double bottom, double top, double nearVal, double farVal)
+{
+	GLC_Matrix4x4 perspMatrix;
+	double* m= perspMatrix.setData();
+
+	const double a= (right + left) / (right - left);
+	const double b= (top + bottom) / (top - bottom);
+	const double c= - (farVal + nearVal) / (farVal - nearVal);
+	const double d= - (2.0 * farVal * nearVal) / (farVal - nearVal);
+
+	m[0]= (2.0 * nearVal) / (right - left);
+	m[5]= (2.0 * nearVal) / (top - bottom);
+	m[8]= a;
+	m[9]= b;
+	m[10]= c;
+	m[11]= -1.0;
+	m[14]= d;
+	m[15]= 0.0;
+
+	glcMultMatrix(perspMatrix);
+}
+
+void GLC_Context::glcEnableLighting(bool enable)
+{
+	if (enable != m_LightingIsEnable.top())
+	{
+		m_LightingIsEnable.top()= enable;
+
+#ifdef GLC_OPENGL_ES_2
+
+		m_UniformShaderData.setLightingState(m_LightingIsEnable);
+#else
+		if (GLC_Shader::hasActiveShader())
+		{
+			m_UniformShaderData.setLightingState(m_LightingIsEnable.top());
+		}
+		if (m_LightingIsEnable.top()) ::glEnable(GL_LIGHTING);
+		else ::glDisable(GL_LIGHTING);
+#endif
+
+	}
+}
+
+//////////////////////////////////////////////////////////////////////
+// Set Functions
+//////////////////////////////////////////////////////////////////////
+
+void GLC_Context::makeCurrent()
+{
+	QGLContext::makeCurrent();
+	if (!GLC_State::isValid())
+	{
+		GLC_State::init();
+	}
+	GLC_ContextManager::instance()->setCurrent(this);
+	m_pCurrentContext= this;
+}
+
+void GLC_Context::doneCurrent()
+{
+	QGLContext::doneCurrent();
+	GLC_ContextManager::instance()->setCurrent(NULL);
+	m_pCurrentContext= NULL;
+}
+
+bool GLC_Context::chooseContext(const QGLContext* shareContext)
+{
+	qDebug() << "GLC_Context::chooseContext";
+	const bool success= QGLContext::chooseContext(shareContext);
+	if (!success)
+	{
+		qDebug() << "enable to create context " << this;
+	}
+	else if (NULL != shareContext)
+	{
+		GLC_Context* pContext= const_cast<GLC_Context*>(dynamic_cast<const GLC_Context*>(shareContext));
+		Q_ASSERT(NULL != pContext);
+		m_ContextSharedData= pContext->m_ContextSharedData;
+	}
+	else
+	{
+		m_ContextSharedData= QSharedPointer<GLC_ContextSharedData>(new GLC_ContextSharedData());
+	}
+
+	return success;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Private services Functions
+//////////////////////////////////////////////////////////////////////
+void GLC_Context::init()
+{
+	QStack<GLC_Matrix4x4>* pStack1= new QStack<GLC_Matrix4x4>();
+	pStack1->push(GLC_Matrix4x4());
+	m_MatrixStackHash.insert(GL_MODELVIEW, pStack1);
+
+	QStack<GLC_Matrix4x4>* pStack2= new QStack<GLC_Matrix4x4>();
+	pStack2->push(GLC_Matrix4x4());
+	m_MatrixStackHash.insert(GL_PROJECTION, pStack2);
+
+	m_LightingIsEnable.push(false);
+}
+
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_context.h b/ground/openpilotgcs/src/libs/glc_lib/glc_context.h
new file mode 100644
index 000000000..da3378db8
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_context.h
@@ -0,0 +1,196 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************************/
+//! \file glc_context.h interface for the GLC_Context class.
+
+#ifndef GLC_CONTEXT_H_
+#define GLC_CONTEXT_H_
+
+#include <QtOpenGL>
+#include <QGLContext>
+#include <QGLFormat>
+#include <QSharedPointer>
+#include <QtDebug>
+
+#include "glc_config.h"
+#include "maths/glc_matrix4x4.h"
+#include "glc_contextshareddata.h"
+#include "glc_uniformshaderdata.h"
+
+class GLC_ContextSharedData;
+
+// OpenGL ES define
+#if defined(QT_OPENGL_ES_2)
+#define GLC_OPENGL_ES_2 1
+
+#define GL_MODELVIEW					0x1700
+#define GL_PROJECTION					0x1701
+#endif
+
+
+//#define GLC_OPENGL_ES_2 1
+
+//////////////////////////////////////////////////////////////////////
+//! \class GLC_Context
+/*! \brief GLC_Context : Encapsulates OpenGL rendering context*/
+
+/*! The GLC_Context class store all GLC state associated to an OpenGL rendering context.
+ * This class is also used to simplified OpenGL and OpenGL-ES interoperability
+ */
+//////////////////////////////////////////////////////////////////////
+class GLC_LIB_EXPORT GLC_Context : public QGLContext
+{
+//////////////////////////////////////////////////////////////////////
+/*! @name Constructor / Destructor */
+//@{
+//////////////////////////////////////////////////////////////////////
+
+public:
+	GLC_Context(const QGLFormat& format);
+	virtual ~GLC_Context();
+
+//@}
+//////////////////////////////////////////////////////////////////////
+/*! \name Get Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+public:
+	//! Return the current context
+	static GLC_Context* current();
+
+	//! Return the model view matrix
+	inline GLC_Matrix4x4 modelViewMatrix() const
+	{Q_ASSERT(m_MatrixStackHash.contains(GL_MODELVIEW)); return m_MatrixStackHash.value(GL_MODELVIEW)->top();}
+
+	//! Return the projection matrix
+	inline GLC_Matrix4x4 projectionMatrix() const
+	{Q_ASSERT(m_MatrixStackHash.contains(GL_PROJECTION)); return m_MatrixStackHash.value(GL_PROJECTION)->top();}
+
+	//! Return lighting enable state
+	inline bool lightingIsEnable() const
+	{return m_LightingIsEnable.top();}
+//@}
+//////////////////////////////////////////////////////////////////////
+/*! \name OpenGL Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+public:
+	//! Set the matrix mode
+	void glcMatrixMode(GLenum mode);
+
+	//! Replace the current matrix with the identity
+	void glcLoadIdentity();
+
+	//! push and pop the current matrix stack
+	void glcPushMatrix();
+	void glcPopMatrix();
+
+	//! Replace the current matrix with the specified matrix
+	void glcLoadMatrix(const GLC_Matrix4x4& matrix);
+
+	//! Multiply the current matrix with the specified matrix
+	void glcMultMatrix(const GLC_Matrix4x4& matrix);
+
+	//! Multiply the current matrix by a translation matrix
+	inline void glcTranslated(double x, double y, double z)
+	{glcMultMatrix(GLC_Matrix4x4(x, y, z));}
+
+	//! Multiply the current matrix by a general scaling matrix
+	void glcScaled(double x, double y, double z);
+
+	//! Multiply the current matrix with an orthographic matrix
+	void glcOrtho(double left, double right, double bottom, double top, double nearVal, double farVal);
+
+	//! Multiply the current matrix by a perspective matrix
+	void glcFrustum(double left, double right, double bottom, double top, double nearVal, double farVal);
+
+	//! Enable lighting
+	void glcEnableLighting(bool enable);
+
+//@}
+//////////////////////////////////////////////////////////////////////
+/*! \name Set Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+public:
+
+	//! Make this context the current one
+	virtual void makeCurrent();
+
+	//! Make no context to be the current one
+	virtual void doneCurrent();
+
+	//! Update uniform variable
+	inline void updateUniformVariables()
+	{m_UniformShaderData.updateAll(this);}
+
+//@}
+//////////////////////////////////////////////////////////////////////
+/*! \name Private services Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+protected:
+//@{
+
+	virtual bool chooseContext(const QGLContext* shareContext= 0);
+//@}
+
+//////////////////////////////////////////////////////////////////////
+/*! \name Private services Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+private:
+//@{
+
+	//! Init this context state
+	void init();
+//@}
+
+
+//////////////////////////////////////////////////////////////////////
+// Private members
+//////////////////////////////////////////////////////////////////////
+private:
+
+	//! The current matrix mode
+	GLenum m_CurrentMatrixMode;
+
+	//! Mapping between matrixMode and matrix stack
+	QHash<GLenum, QStack<GLC_Matrix4x4>* > m_MatrixStackHash;
+
+	//! The context shared data
+	QSharedPointer<GLC_ContextSharedData> m_ContextSharedData;
+
+	//! The uniform data of the current shader
+	GLC_UniformShaderData m_UniformShaderData;
+
+	//! The current context
+	static GLC_Context* m_pCurrentContext;
+
+	//! Enable lighting state
+	QStack<bool> m_LightingIsEnable;
+
+	//! Lights enable state
+	QHash<GLenum, bool> m_LightsEnableState;
+
+};
+
+#endif /* GLC_CONTEXT_H_ */
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_contextmanager.cpp b/ground/openpilotgcs/src/libs/glc_lib/glc_contextmanager.cpp
new file mode 100644
index 000000000..d0fbcb7e6
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_contextmanager.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************************/
+//! \file glc_contextmanager.cpp implementation of the GLC_ContextManager class.
+
+#include <QtDebug>
+
+#include "glc_contextmanager.h"
+#include "glc_state.h"
+
+GLC_ContextManager* GLC_ContextManager::m_pContextManager= NULL;
+
+GLC_ContextManager::GLC_ContextManager()
+: m_pCurrentContext(NULL)
+, m_SetOfContext()
+{
+
+
+}
+
+GLC_ContextManager::~GLC_ContextManager()
+{
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// Get Functions
+//////////////////////////////////////////////////////////////////////
+GLC_ContextManager* GLC_ContextManager::instance()
+{
+	if (NULL == m_pContextManager)
+	{
+		m_pContextManager= new GLC_ContextManager();
+	}
+
+	return m_pContextManager;
+}
+
+GLC_Context* GLC_ContextManager::currentContext() const
+{
+	return m_pCurrentContext;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Set Functions
+//////////////////////////////////////////////////////////////////////
+void GLC_ContextManager::addContext(GLC_Context* pContext)
+{
+	Q_ASSERT(!m_SetOfContext.contains(pContext));
+	m_SetOfContext.insert(pContext);
+}
+
+void GLC_ContextManager::remove(GLC_Context* pContext)
+{
+	Q_ASSERT(m_SetOfContext.contains(pContext));
+	m_SetOfContext.remove(pContext);
+	if (m_pCurrentContext == pContext)
+	{
+		m_pCurrentContext= NULL;
+	}
+}
+
+void GLC_ContextManager::setCurrent(GLC_Context* pContext)
+{
+
+	Q_ASSERT((NULL == pContext) || m_SetOfContext.contains(pContext));
+	m_pCurrentContext= pContext;
+}
+
+
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_contextmanager.h b/ground/openpilotgcs/src/libs/glc_lib/glc_contextmanager.h
new file mode 100644
index 000000000..7165dd13f
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_contextmanager.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************************/
+//! \file glc_contextmanager.h interface for the GLC_ContextManager class.
+
+#ifndef GLC_CONTEXTMANAGER_H_
+#define GLC_CONTEXTMANAGER_H_
+
+#include <QSet>
+
+#include "glc_config.h"
+
+
+class GLC_Context;
+
+//////////////////////////////////////////////////////////////////////
+//! \class GLC_ContextManager
+/*! \brief GLC_ContextManager : Manager a set of GLC_Context*/
+//////////////////////////////////////////////////////////////////////
+class GLC_LIB_EXPORT GLC_ContextManager
+{
+private:
+	GLC_ContextManager();
+public:
+	virtual ~GLC_ContextManager();
+
+//@}
+//////////////////////////////////////////////////////////////////////
+/*! \name Get Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+public:
+	//! Return the unique instance of context manager
+	static GLC_ContextManager* instance();
+
+	//! Return the current context
+	GLC_Context* currentContext() const;
+
+	//! Return true if there is a current context
+	inline bool currentContextExists() const
+	{return (NULL != m_pCurrentContext);}
+
+	//! Return true if this manager has context
+	inline bool hasContext() const
+	{return !m_SetOfContext.isEmpty();}
+
+//@}
+//////////////////////////////////////////////////////////////////////
+/*! \name Set Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+public:
+	//! Add the given context
+	void addContext(GLC_Context* pContext);
+
+	//! Remove the given context
+	void remove(GLC_Context* pContext);
+
+	//! Set the current the given context
+	void setCurrent(GLC_Context* pContext);
+
+//////////////////////////////////////////////////////////////////////
+/*! \name Private services Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+private:
+//@{
+
+//@}
+
+
+//////////////////////////////////////////////////////////////////////
+// Private members
+//////////////////////////////////////////////////////////////////////
+private:
+	//! The unique instance of the context manager
+	static GLC_ContextManager* m_pContextManager;
+
+	//! The current context
+	GLC_Context* m_pCurrentContext;
+
+	//! The Set of context to manage
+	QSet<GLC_Context*> m_SetOfContext;
+};
+
+#endif /* GLC_CONTEXTMANAGER_H_ */
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_openglstate.cpp b/ground/openpilotgcs/src/libs/glc_lib/glc_contextshareddata.cpp
similarity index 73%
rename from ground/openpilotgcs/src/libs/glc_lib/glc_openglstate.cpp
rename to ground/openpilotgcs/src/libs/glc_lib/glc_contextshareddata.cpp
index 0331cd8a9..0c108036e 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_openglstate.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_contextshareddata.cpp
@@ -19,16 +19,19 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
  *****************************************************************************/
-//! \file glc_openglstate.cpp implementation of the GLC_OpenGLState class.
+//! \file glc_contextshareddata.cpp implementation of the GLC_ContextSharedData class.
 
-#include "glc_openglstate.h"
+#include <QtDebug>
 
-GLC_OpenGLState::GLC_OpenGLState()
+#include "glc_contextshareddata.h"
+
+GLC_ContextSharedData::GLC_ContextSharedData()
 {
+	qDebug() << "GLC_ContextSharedData::GLC_ContextSharedData()";
 
 }
 
-GLC_OpenGLState::~GLC_OpenGLState()
+GLC_ContextSharedData::~GLC_ContextSharedData()
 {
-
+	qDebug() << "GLC_ContextSharedData::~GLC_ContextSharedData()";
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_openglstatemanager.h b/ground/openpilotgcs/src/libs/glc_lib/glc_contextshareddata.h
similarity index 76%
rename from ground/openpilotgcs/src/libs/glc_lib/glc_openglstatemanager.h
rename to ground/openpilotgcs/src/libs/glc_lib/glc_contextshareddata.h
index c9bc66272..8c6640384 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_openglstatemanager.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_contextshareddata.h
@@ -19,16 +19,18 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
  *****************************************************************************/
-//! \file glc_openglstatemanager.h interface for the GLC_OpenGLStateManager class.
+//! \file glc_contextshareddata.h interface for the GLC_ContextSharedData class.
 
-#ifndef GLC_OPENGLSTATEMANAGER_H_
-#define GLC_OPENGLSTATEMANAGER_H_
+#ifndef GLC_CONTEXTSHAREDDATA_H_
+#define GLC_CONTEXTSHAREDDATA_H_
 
-class GLC_OpenGLStateManager
+#include "glc_config.h"
+
+class GLC_LIB_EXPORT GLC_ContextSharedData
 {
 public:
-	GLC_OpenGLStateManager();
-	virtual ~GLC_OpenGLStateManager();
+	GLC_ContextSharedData();
+	virtual ~GLC_ContextSharedData();
 };
 
-#endif /* GLC_OPENGLSTATEMANAGER_H_ */
+#endif /* GLC_CONTEXTSHAREDDATA_H_ */
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_ext.cpp b/ground/openpilotgcs/src/libs/glc_lib/glc_ext.cpp
index 6d2742bdd..8275a085f 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_ext.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_ext.cpp
@@ -26,25 +26,9 @@
 #include <QGLContext>
 #include <QDebug>
 #include <QGLShaderProgram>
+#include <QGLBuffer>
 
 #if !defined(Q_OS_MAC)
-// ARB_vertex_buffer_object
-PFNGLBINDBUFFERARBPROC				glBindBuffer			= NULL;
-PFNGLDELETEBUFFERSARBPROC			glDeleteBuffers			= NULL;
-PFNGLGENBUFFERSARBPROC				glGenBuffers			= NULL;
-PFNGLISBUFFERARBPROC				glIsBuffer				= NULL;
-PFNGLBUFFERDATAARBPROC				glBufferData			= NULL;
-PFNGLBUFFERSUBDATAARBPROC			glBufferSubData			= NULL;
-PFNGLGETBUFFERSUBDATAARBPROC		glGetBufferSubData		= NULL;
-PFNGLMAPBUFFERARBPROC				glMapBuffer				= NULL;
-PFNGLUNMAPBUFFERARBPROC				glUnmapBuffer			= NULL;
-PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameteriv	= NULL;
-PFNGLGETBUFFERPOINTERVARBPROC		glGetBufferPointerv		= NULL;
-// glDrawRangElement
-//PFNGLDRAWRANGEELEMENTSPROC 			glDrawRangeElements		= NULL;
-
-// glMultiDrawElement
-PFNGLMULTIDRAWELEMENTSPROC			glMultiDrawElements		= NULL;
 
 // GL_point_parameters Point Sprite
 PFNGLPOINTPARAMETERFARBPROC			glPointParameterf		= NULL;
@@ -52,7 +36,6 @@ PFNGLPOINTPARAMETERFVARBPROC		glPointParameterfv		= NULL;
 
 #endif
 
-//const QString glExtension(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
 
 // Return true if the extension is supported
 bool glc::extensionIsSupported(const QString& extension)
@@ -64,28 +47,10 @@ bool glc::extensionIsSupported(const QString& extension)
 // Return true if VBO extension is succesfully loaded
 bool glc::loadVboExtension()
 {
-	bool result= true;
-#if !defined(Q_OS_MAC)
-	const QGLContext* pContext= QGLContext::currentContext();
-    glBindBuffer				= (PFNGLBINDBUFFERARBPROC)pContext->getProcAddress(QLatin1String("glBindBuffer"));
-    glDeleteBuffers				= (PFNGLDELETEBUFFERSARBPROC)pContext->getProcAddress(QLatin1String("glDeleteBuffers"));
-    glGenBuffers				= (PFNGLGENBUFFERSARBPROC)pContext->getProcAddress(QLatin1String("glGenBuffers"));
-    glIsBuffer					= (PFNGLISBUFFERARBPROC)pContext->getProcAddress(QLatin1String("glIsBuffer"));
-    glBufferData				= (PFNGLBUFFERDATAARBPROC)pContext->getProcAddress(QLatin1String("glBufferData"));
-    glBufferSubData				= (PFNGLBUFFERSUBDATAARBPROC)pContext->getProcAddress(QLatin1String("glBufferSubData"));
-    glGetBufferSubData			= (PFNGLGETBUFFERSUBDATAARBPROC)pContext->getProcAddress(QLatin1String("glGetBufferSubData"));
-    glMapBuffer					= (PFNGLMAPBUFFERARBPROC)pContext->getProcAddress(QLatin1String("glMapBuffer"));
-    glUnmapBuffer				= (PFNGLUNMAPBUFFERARBPROC)pContext->getProcAddress(QLatin1String("glUnmapBuffer"));
-    glGetBufferParameteriv		= (PFNGLGETBUFFERPARAMETERIVARBPROC)pContext->getProcAddress(QLatin1String("glGetBufferParameteriv"));
-    glGetBufferPointerv			= (PFNGLGETBUFFERPOINTERVARBPROC)pContext->getProcAddress(QLatin1String("glGetBufferPointerv"));
-    //glDrawRangeElements			= (PFNGLDRAWRANGEELEMENTSPROC)pContext->getProcAddress(QLatin1String("glDrawRangeElements"));
-    glMultiDrawElements			= (PFNGLMULTIDRAWELEMENTSPROC)pContext->getProcAddress(QLatin1String("glMultiDrawElements"));
-
-    result= glBindBuffer && glDeleteBuffers && glGenBuffers && glIsBuffer && glBufferData && glBufferSubData &&
-    glGetBufferSubData && glMapBuffer && glUnmapBuffer && glGetBufferParameteriv && glGetBufferPointerv && glMultiDrawElements;// and glDrawRangeElements;
-#endif
+	QGLBuffer buffer;
+	bool result= buffer.create();
+	buffer.destroy();
     return result;
-
 }
 
 // Load GLSL extensions
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_ext.h b/ground/openpilotgcs/src/libs/glc_lib/glc_ext.h
index 38c3d6154..d4ab75224 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_ext.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_ext.h
@@ -30,37 +30,7 @@
 // Buffer offset used by VBO
 #define BUFFER_OFFSET(i) ((char*)NULL + (i))
 
-#if defined(Q_OS_MAC)
-#include "gl.h"
-#include "glu.h"
-#endif
-
-#if defined(Q_OS_WIN32)
-#include "GL/gl.h"
-#include "GL/glu.h"
-#endif
-
-#if defined(Q_OS_LINUX)
-#include "GL/glu.h"
-#endif
-
 #if !defined(Q_OS_MAC)
-// ARB_vertex_buffer_object
-extern PFNGLBINDBUFFERARBPROC			glBindBuffer;
-extern PFNGLDELETEBUFFERSARBPROC		glDeleteBuffers;
-extern PFNGLGENBUFFERSARBPROC			glGenBuffers;
-extern PFNGLISBUFFERARBPROC				glIsBuffer;
-extern PFNGLBUFFERDATAARBPROC			glBufferData;
-extern PFNGLBUFFERSUBDATAARBPROC		glBufferSubData;
-extern PFNGLGETBUFFERSUBDATAARBPROC		glGetBufferSubData;
-extern PFNGLMAPBUFFERARBPROC			glMapBuffer;
-extern PFNGLUNMAPBUFFERARBPROC			glUnmapBuffer;
-extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameteriv;
-extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointerv;
-// glDrawRangElement
-//extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements;
-// glMultiDrawElement
-extern PFNGLMULTIDRAWELEMENTSPROC		glMultiDrawElements;
 
 // GL_point_parameters Point Sprite
 extern PFNGLPOINTPARAMETERFARBPROC  glPointParameterf;
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_factory.cpp b/ground/openpilotgcs/src/libs/glc_lib/glc_factory.cpp
index 73e335912..8ff879d91 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_factory.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_factory.cpp
@@ -37,6 +37,7 @@
 #include "viewport/glc_reptrackballmover.h"
 #include "viewport/glc_flymover.h"
 #include "viewport/glc_repflymover.h"
+#include "viewport/glc_tsrmover.h"
 #include "maths/glc_line3d.h"
 #include "maths/glc_geomtools.h"
 
@@ -44,7 +45,6 @@
 
 // init static member
 GLC_Factory* GLC_Factory::m_pFactory= NULL;
-QGLContext* GLC_Factory::m_pQGLContext= NULL;
 QList<GLC_WorldReaderPlugin*> GLC_Factory::m_WorldReaderPluginList;
 QSet<QString> GLC_Factory::m_SupportedExtensionSet;
 
@@ -52,15 +52,11 @@ QSet<QString> GLC_Factory::m_SupportedExtensionSet;
 // static method
 //////////////////////////////////////////////////////////////////////
 // Return the unique instance of the factory
-GLC_Factory* GLC_Factory::instance(const QGLContext *pContext)
+GLC_Factory* GLC_Factory::instance()
 {
 	if(m_pFactory == NULL)
 	{
-		m_pFactory= new GLC_Factory(pContext);
-	}
-	else if ((NULL != pContext) && (m_pQGLContext != pContext))
-	{
-		m_pQGLContext= const_cast<QGLContext*>(pContext);
+		m_pFactory= new GLC_Factory();
 	}
 	return m_pFactory;
 }
@@ -70,9 +66,8 @@ GLC_Factory* GLC_Factory::instance(const QGLContext *pContext)
 //////////////////////////////////////////////////////////////////////
 
 // Protected constructor
-GLC_Factory::GLC_Factory(const QGLContext *pContext)
+GLC_Factory::GLC_Factory()
 {
-	m_pQGLContext= (const_cast<QGLContext*>(pContext));
 	loadPlugins();
 }
 
@@ -231,7 +226,7 @@ GLC_World GLC_Factory::createWorldStructureFrom3dxml(QFile &file, bool GetExtRef
 
 	if (QFileInfo(file).suffix().toLower() == "3dxml")
 	{
-		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
+		GLC_3dxmlToWorld d3dxmlToWorld;
 		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
 		pWorld= d3dxmlToWorld.createWorldFrom3dxml(file, true, GetExtRefName);
 	}
@@ -253,9 +248,9 @@ GLC_3DRep GLC_Factory::create3DRepFromFile(const QString& fileName) const
 {
 	GLC_3DRep rep;
 
-	if ((QFileInfo(fileName).suffix().toLower() == "3dxml") || (QFileInfo(fileName).suffix().toLower() == "3drep"))
+	if ((QFileInfo(fileName).suffix().toLower() == "3dxml") || (QFileInfo(fileName).suffix().toLower() == "3drep") || (QFileInfo(fileName).suffix().toLower() == "xml"))
 	{
-		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
+		GLC_3dxmlToWorld d3dxmlToWorld;
 		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
 		rep= d3dxmlToWorld.create3DrepFrom3dxmlRep(fileName);
 	}
@@ -266,7 +261,7 @@ GLC_3DRep GLC_Factory::create3DRepFromFile(const QString& fileName) const
 
 GLC_FileLoader* GLC_Factory::createFileLoader() const
 {
-    return new GLC_FileLoader(m_pQGLContext);
+    return new GLC_FileLoader;
 }
 
 GLC_Material* GLC_Factory::createMaterial() const
@@ -303,12 +298,12 @@ GLC_Material* GLC_Factory::createMaterial(const QImage &image) const
 
 GLC_Texture* GLC_Factory::createTexture(const QString &textureFullFileName) const
 {
-	return new GLC_Texture(m_pQGLContext, textureFullFileName);
+	return new GLC_Texture(textureFullFileName);
 }
 
 GLC_Texture* GLC_Factory::createTexture(const QImage & image, const QString& imageFileName) const
 {
-	return new GLC_Texture(m_pQGLContext, image, imageFileName);
+	return new GLC_Texture(image, imageFileName);
 }
 
 GLC_MoverController GLC_Factory::createDefaultMoverController(const QColor& color, GLC_Viewport* pViewport)
@@ -371,6 +366,7 @@ GLC_MoverController GLC_Factory::createDefaultMoverController(const QColor& colo
 	pMover= new GLC_TurnTableMover(pViewport);
 	// Add the Turn Table Mover to the controller
 	defaultController.addMover(pMover, GLC_MoverController::TurnTable);
+
 	//////////////////////////////////////////////////////////////////////
 	// Fly Mover
 	//////////////////////////////////////////////////////////////////////
@@ -383,6 +379,14 @@ GLC_MoverController GLC_Factory::createDefaultMoverController(const QColor& colo
 	// Add the fly mover to the controller
 	defaultController.addMover(pMover, GLC_MoverController::Fly);
 
+	//////////////////////////////////////////////////////////////////////
+	// Translation, rotation and scaling Mover
+	//////////////////////////////////////////////////////////////////////
+	// Create the Turn Table Mover
+	pMover= new GLC_TsrMover(pViewport);
+	// Add the Turn Table Mover to the controller
+	defaultController.addMover(pMover, GLC_MoverController::TSR);
+
 	return defaultController;
 }
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_factory.h b/ground/openpilotgcs/src/libs/glc_lib/glc_factory.h
index d0436fe46..89ebd39eb 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_factory.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_factory.h
@@ -70,11 +70,11 @@ class GLC_LIB_EXPORT GLC_Factory : public QObject
 
 public:
 	//! Get unique instance of the factory
-	static GLC_Factory* instance(const QGLContext * pContext= NULL);
+	static GLC_Factory* instance();
 
 protected:
 	//! Constructor
-	GLC_Factory(const QGLContext *);
+	GLC_Factory();
 public:
 	//! Destructor
 	~GLC_Factory();
@@ -84,9 +84,6 @@ public:
 //@{
 //////////////////////////////////////////////////////////////////////
 public:
-	//! Return the current factory context
-	inline QGLContext* context() const
-	{return m_pQGLContext;}
 
 	//! Create a GLC_Point
 	GLC_3DRep createPoint(const GLC_Point3d &coord) const;
@@ -201,9 +198,6 @@ private:
 	//! The unique instance of the factory
 	static GLC_Factory* m_pFactory;
 
-	//! The QGLContext attached to the factory (rendering context)
-	static QGLContext* m_pQGLContext;
-
 	//! The list off worldReader plugins
 	static QList<GLC_WorldReaderPlugin*> m_WorldReaderPluginList;
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_global.h b/ground/openpilotgcs/src/libs/glc_lib/glc_global.h
index 23cdc158b..ca108b63e 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_global.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_global.h
@@ -120,7 +120,7 @@ namespace glc
 	GLC_LIB_EXPORT QString archiveEntryFileName(const QString& archiveString);
 
 	// GLC_Lib version
-	const QString version("2.1.0");
+	const QString version("2.2.0");
 	const QString description("GLC_lib is a Open Source C++ class library that enables the quick creation of an OpenGL application based on QT4.");
 
 };
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_lib.pro b/ground/openpilotgcs/src/libs/glc_lib/glc_lib.pro
index c7952b1e7..6966f94b5 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_lib.pro
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_lib.pro
@@ -9,11 +9,10 @@ QT += opengl \
     core
 
 
-#CONFIG += exceptions \
-#    release \
-#    warn_on
+CONFIG += exceptions \
+    warn_on
 #TARGET = GLC_lib
-#VERSION = 2.1.0
+VERSION = 2.2.0
 
 DEFINES += CREATE_GLC_LIB_DLL
 DEFINES += LIB3DS_EXPORTS
@@ -28,6 +27,8 @@ DEPENDPATH += .
 INCLUDEPATH += .
 INCLUDEPATH += ./3rdparty/zlib
 
+RESOURCES += glc_lib.qrc
+
 # Input					
 HEADERS_QUAZIP +=	3rdparty/quazip/crypt.h \
 					3rdparty/quazip/ioapi.h \
@@ -145,8 +146,9 @@ HEADERS_GLC_VIEWPORT +=	viewport/glc_camera.h \
 						viewport/glc_turntablemover.h \
 						viewport/glc_frustum.h \
 						viewport/glc_flymover.h \
-						viewport/glc_repflymover.h
-
+						viewport/glc_repflymover.h \
+						viewport/glc_userinput.h \
+						viewport/glc_tsrmover.h
 
 HEADERS_GLC += glc_global.h \
            glc_object.h \
@@ -163,7 +165,10 @@ HEADERS_GLC += glc_global.h \
            glc_log.h \
            glc_errorlog.h \
            glc_tracelog.h \
-           glc_openglstate.h
+           glc_context.h \
+           glc_contextmanager.h \
+           glc_contextshareddata.h \
+           glc_uniformshaderdata.h
            
 HEADERS_GLC_3DWIDGET += 3DWidget/glc_3dwidget.h \
 						3DWidget/glc_cuttingplane.h \
@@ -174,10 +179,11 @@ HEADERS_GLC_3DWIDGET += 3DWidget/glc_3dwidget.h \
 						3DWidget/glc_rotationmanipulator.h \
 						3DWidget/glc_axis.h
 
+HEADERS_GLC_GLU +=	glu/glc_glu.h
 
 HEADERS += $${HEADERS_QUAZIP} $${HEADERS_LIB3DS} $${HEADERS_GLC_MATHS} $${HEADERS_GLC_IO}
 HEADERS += $${HEADERS_GLC} $${HEADERS_GLEXT} $${HEADERS_GLC_SCENEGRAPH} $${HEADERS_GLC_GEOMETRY}
-HEADERS += $${HEADERS_GLC_SHADING} $${HEADERS_GLC_VIEWPORT} $${HEADERS_GLC_3DWIDGET}
+HEADERS += $${HEADERS_GLC_SHADING} $${HEADERS_GLC_VIEWPORT} $${HEADERS_GLC_3DWIDGET} $${HEADERS_GLC_GLU}
 		   
 SOURCES += 3rdparty/zlib/adler32.c \
            3rdparty/zlib/compress.c \
@@ -294,7 +300,9 @@ SOURCES +=	viewport/glc_camera.cpp \
 			viewport/glc_turntablemover.cpp \
 			viewport/glc_frustum.cpp \
 			viewport/glc_flymover.cpp \
-			viewport/glc_repflymover.cpp
+			viewport/glc_repflymover.cpp \
+			viewport/glc_userinput.cpp \
+			viewport/glc_tsrmover.cpp
 		
 SOURCES +=	glc_global.cpp \
 			glc_object.cpp \			
@@ -310,7 +318,10 @@ SOURCES +=	glc_global.cpp \
 			glc_log.cpp \
 			glc_errorlog.cpp \
 			glc_tracelog.cpp \
-			glc_openglstate.cpp
+			glc_context.cpp \
+			glc_contextmanager.cpp \
+			glc_contextshareddata.cpp \
+			glc_uniformshaderdata.cpp
 
 SOURCES +=	3DWidget/glc_3dwidget.cpp \
 			3DWidget/glc_cuttingplane.cpp \
@@ -321,7 +332,8 @@ SOURCES +=	3DWidget/glc_3dwidget.cpp \
 			3DWidget/glc_rotationmanipulator.cpp \
 			3DWidget/glc_axis.cpp
 			
-         
+SOURCES +=	glu/glc_project.cpp
+
 # Windows compilation configuration
 win32:CONFIG *= dll
 
@@ -413,12 +425,17 @@ HEADERS_INST = include/GLC_BoundingBox \
     		   include/GLC_ErrorLog \
     		   include/GLC_TraceLog \
     		   include/glcXmlUtil \
-    		   include/GLC_OpenGLState \
+    		   include/GLC_RenderState \
     		   include/GLC_FileLoader \
     		   include/GLC_WorldReaderPlugin \
     		   include/GLC_WorldReaderHandler \
     		   include/GLC_PointCloud \
-    		   include/GLC_SelectionSet
+    		   include/GLC_SelectionSet \
+    		   include/GLC_UserInput \
+    		   include/GLC_TsrMover \
+    		   include/GLC_Glu \
+    		   include/GLC_Context \
+    		   include/GLC_ContextManager
 
     			   
 # Linux and macx install configuration
@@ -439,6 +456,7 @@ unix {
 	include_glc_shading.path = $${INCLUDE_DIR}/GLC_lib/shading
 	include_glc_viewport.path = $${INCLUDE_DIR}/GLC_lib/viewport
 	include_glc_3dwidget.path = $${INCLUDE_DIR}/GLC_lib/3DWidget
+	include_glc_glu.path = $${INCLUDE_DIR}/GLC_lib/glu
 }
 
 # Windows Install configuration
@@ -457,6 +475,7 @@ win32 {
     include_glc_shading.path = $${INCLUDE_DIR}/shading
     include_glc_viewport.path = $${INCLUDE_DIR}/viewport
     include_glc_3dwidget.path = $${INCLUDE_DIR}/3DWidget
+    include_glc_glu.path = $${INCLUDE_DIR}/glu
 }    
 
 include.files = $${HEADERS_GLC} $${HEADERS_INST}
@@ -470,6 +489,7 @@ include_glc_geometry.files= $${HEADERS_GLC_GEOMETRY}
 include_glc_shading.files = $${HEADERS_GLC_SHADING}
 include_glc_viewport.files = $${HEADERS_GLC_VIEWPORT}
 include_glc_3dwidget.files = $${HEADERS_GLC_3DWIDGET}
+include_glc_glu.files = $${HEADERS_GLC_GLU}
 
 # install library
 target.path = $${LIB_DIR}
@@ -477,8 +497,15 @@ target.path = $${LIB_DIR}
 # "make install" configuration options
 INSTALLS += include_lib3ds include_glext include_quazip include_glc_maths include_glc_io
 INSTALLS += include_glc_scengraph include_glc_geometry include_glc_shading include_glc_viewport
-INSTALLS += include_glc_3dwidget
+INSTALLS += include_glc_3dwidget include_glc_glu
 
 INSTALLS += target
 INSTALLS +=include
 
+OTHER_FILES += \
+    qtc_packaging/debian_harmattan/rules \
+    qtc_packaging/debian_harmattan/README \
+    qtc_packaging/debian_harmattan/copyright \
+    qtc_packaging/debian_harmattan/control \
+    qtc_packaging/debian_harmattan/compat \
+    qtc_packaging/debian_harmattan/changelog
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_lib.qrc b/ground/openpilotgcs/src/libs/glc_lib/glc_lib.qrc
new file mode 100644
index 000000000..d74f34bc9
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_lib.qrc
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/GLC_lib_Shaders" >
+ 		<file alias="default_frag">shading/shaders/default.frag</file>
+ 		<file alias="default_vert">shading/shaders/default.vert</file>
+     </qresource>
+</RCC>
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_state.cpp b/ground/openpilotgcs/src/libs/glc_lib/glc_state.cpp
index 755436ffd..6f03b3609 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_state.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_state.cpp
@@ -48,6 +48,7 @@ GLC_CacheManager GLC_State::m_CacheManager;
 
 bool GLC_State::m_IsSpacePartitionningActivated= false;
 bool GLC_State::m_IsFrustumCullingActivated= false;
+bool GLC_State::m_IsValid= false;
 
 GLC_State::~GLC_State()
 {
@@ -145,13 +146,24 @@ bool GLC_State::isFrustumCullingActivated()
 
 void GLC_State::init()
 {
-	setVboSupport();
-	setGlslSupport();
-	setPointSpriteSupport();
-	setFrameBufferSupport();
-	m_Version= (char *) glGetString(GL_VERSION);
-	m_Vendor= (char *) glGetString(GL_VENDOR);
-	m_Renderer= (char *) glGetString(GL_RENDERER);
+	if (!m_IsValid)
+	{
+		Q_ASSERT((NULL != QGLContext::currentContext()) &&  QGLContext::currentContext()->isValid());
+		setVboSupport();
+		setGlslSupport();
+		setPointSpriteSupport();
+		setFrameBufferSupport();
+		m_Version= (char *) glGetString(GL_VERSION);
+		m_Vendor= (char *) glGetString(GL_VENDOR);
+		m_Renderer= (char *) glGetString(GL_RENDERER);
+
+		m_IsValid= true;
+	}
+}
+
+bool GLC_State::isValid()
+{
+	return m_IsValid;
 }
 
 void GLC_State::setVboSupport()
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_state.h b/ground/openpilotgcs/src/libs/glc_lib/glc_state.h
index 187ba389c..c6b52d7e7 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_state.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_state.h
@@ -103,6 +103,9 @@ public:
 
 	//! Return true if frustum culling is activated
 	static bool isFrustumCullingActivated();
+
+	//! Return true valid
+	static bool isValid();
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -209,6 +212,9 @@ private:
 	//! Frame buffer supported
 	static bool m_IsFrameBufferSupported;
 
+	//! State valid flag
+	static bool m_IsValid;
+
 };
 
 #endif /*GLC_STATE_H_*/
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_uniformshaderdata.cpp b/ground/openpilotgcs/src/libs/glc_lib/glc_uniformshaderdata.cpp
new file mode 100644
index 000000000..f994998de
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_uniformshaderdata.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************************/
+//! \file glc_uniformshaderdata.cpp implementation of the GLC_UniformShaderData class.
+
+#include <QtDebug>
+
+#include "shading/glc_shader.h"
+#include "glc_context.h"
+#include "glc_uniformshaderdata.h"
+
+
+GLC_UniformShaderData::GLC_UniformShaderData()
+{
+
+
+}
+
+GLC_UniformShaderData::~GLC_UniformShaderData()
+{
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// Set Functions
+//////////////////////////////////////////////////////////////////////
+void GLC_UniformShaderData::setLightValues(const GLC_Light& light)
+{
+
+}
+
+void GLC_UniformShaderData::setLightingState(bool enable)
+{
+	GLC_Shader* pCurrentShader= GLC_Shader::currentShaderHandle();
+	pCurrentShader->programShaderHandle()->setUniformValue(pCurrentShader->enableLightingId(), enable);
+}
+
+void GLC_UniformShaderData::setModelViewProjectionMatrix(const GLC_Matrix4x4& modelView, const GLC_Matrix4x4& projection)
+{
+	// Set model view matrix
+	const double* pMvmatrixData= modelView.getData();
+	GLfloat mvFloatMatrix[4][4];
+	GLfloat* pData= &(mvFloatMatrix[0][0]);
+	for (int i= 0; i < 16; ++i)
+	{
+		pData[i]= static_cast<GLfloat>(pMvmatrixData[i]);
+	}
+
+	// Set model view projection matrix
+	GLC_Matrix4x4 modelViewProjectionMatrix= projection * modelView;
+	const double* pMvpmatrixData= modelViewProjectionMatrix.getData();
+	GLfloat mvpFloatMatrix[4][4];
+	pData= &(mvpFloatMatrix[0][0]);
+	for (int i= 0; i < 16; ++i)
+	{
+		pData[i]= static_cast<GLfloat>(pMvpmatrixData[i]);
+	}
+
+	// Set the transpose of inv model view matrix (For normal computation)
+	GLC_Matrix4x4 invTransposeModelView= modelView.inverted();
+	invTransposeModelView.transpose();
+	GLfloat invTmdv[3][3];
+	{
+		const double* data= invTransposeModelView.getData();
+
+		invTmdv[0][0]= static_cast<GLfloat>(data[0]); invTmdv[1][0]= static_cast<GLfloat>(data[4]); invTmdv[2][0]= static_cast<GLfloat>(data[8]);
+		invTmdv[0][1]= static_cast<GLfloat>(data[1]); invTmdv[1][1]= static_cast<GLfloat>(data[5]); invTmdv[2][1]= static_cast<GLfloat>(data[9]);
+		invTmdv[0][2]= static_cast<GLfloat>(data[2]); invTmdv[1][2]= static_cast<GLfloat>(data[6]); invTmdv[2][2]= static_cast<GLfloat>(data[10]);
+	}
+
+	Q_ASSERT(GLC_Shader::hasActiveShader());
+
+	GLC_Shader* pCurrentShader= GLC_Shader::currentShaderHandle();
+	pCurrentShader->programShaderHandle()->setUniformValue(pCurrentShader->modelViewLocationId(), mvFloatMatrix);
+	pCurrentShader->programShaderHandle()->setUniformValue(pCurrentShader->mvpLocationId(), mvpFloatMatrix);
+	pCurrentShader->programShaderHandle()->setUniformValue(pCurrentShader->invModelViewLocationId(), invTmdv);
+}
+
+void GLC_UniformShaderData::updateAll(const GLC_Context* pContext)
+{
+	setModelViewProjectionMatrix(pContext->modelViewMatrix(), pContext->projectionMatrix());
+	setLightingState(pContext->lightingIsEnable());
+}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_uniformshaderdata.h b/ground/openpilotgcs/src/libs/glc_lib/glc_uniformshaderdata.h
new file mode 100644
index 000000000..c30e205b6
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glc_uniformshaderdata.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************************/
+//! \file glc_uniformshaderdata.h interface for the GLC_UniformShaderData class.
+
+#ifndef GLC_UNIFORMSHADERDATA_H_
+#define GLC_UNIFORMSHADERDATA_H_
+
+#include <QtOpenGL>
+
+#include "maths/glc_matrix4x4.h"
+#include "shading/glc_light.h"
+
+#include "glc_config.h"
+
+class GLC_Context;
+
+class GLC_LIB_EXPORT GLC_UniformShaderData
+{
+public:
+	GLC_UniformShaderData();
+	virtual ~GLC_UniformShaderData();
+
+//////////////////////////////////////////////////////////////////////
+/*! \name Set Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+public:
+	//! Set Light values from the given light
+	void setLightValues(const GLC_Light& light);
+
+	//! Set lighting enbale state
+	void setLightingState(bool enable);
+
+	//! Set the model view matrix
+	void setModelViewProjectionMatrix(const GLC_Matrix4x4& modelView, const GLC_Matrix4x4& projection);
+
+	//! Update all uniform variables
+	void updateAll(const GLC_Context* pContext);
+
+//@}
+
+//////////////////////////////////////////////////////////////////////
+// private members
+//////////////////////////////////////////////////////////////////////
+private:
+
+};
+
+#endif /* GLC_UNIFORMSHADERDATA_H_ */
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glu/glc_glu.h b/ground/openpilotgcs/src/libs/glc_lib/glu/glc_glu.h
new file mode 100644
index 000000000..218f0742b
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glu/glc_glu.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+*****************************************************************************/
+
+//! \file glc_glu.h declaration of glu functions
+
+
+
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+
+#ifndef GLC_GLU_H_
+#define GLC_GLU_H_
+
+#include <QtOpenGL>
+
+#include "../glc_config.h"
+
+namespace glc
+{
+	GLC_LIB_EXPORT void gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ);
+	GLC_LIB_EXPORT void gluOrtho2D (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);
+	GLC_LIB_EXPORT void gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
+	GLC_LIB_EXPORT void gluPickMatrix (GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint *viewport);
+	GLC_LIB_EXPORT GLint gluProject (GLdouble objX, GLdouble objY, GLdouble objZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* winX, GLdouble* winY, GLdouble* winZ);
+	GLC_LIB_EXPORT GLint gluUnProject (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* objX, GLdouble* objY, GLdouble* objZ);
+	GLC_LIB_EXPORT GLint gluUnProject4 (GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW);
+};
+
+
+#endif /*GLC_GLU_H_*/
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glu/glc_project.cpp b/ground/openpilotgcs/src/libs/glc_lib/glu/glc_project.cpp
new file mode 100644
index 000000000..cf76ea12b
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/glu/glc_project.cpp
@@ -0,0 +1,379 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+*****************************************************************************/
+
+//! \file glc_project implementation of glu project function
+
+
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#include "../glc_context.h"
+#include "glc_glu.h"
+
+/*
+** Make m an identity matrix
+*/
+static void __gluMakeIdentityd(GLdouble m[16])
+{
+    m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
+    m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
+    m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
+    m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
+}
+
+static void __gluMakeIdentityf(GLfloat m[16])
+{
+    m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
+    m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
+    m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
+    m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
+}
+
+void glc::gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
+{
+    GLC_Context::current()->glcOrtho(left, right, bottom, top, -1, 1);
+}
+
+#define __glPi 3.14159265358979323846
+
+void glc::gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
+{
+    GLdouble m[4][4];
+    double sine, cotangent, deltaZ;
+    double radians = fovy / 2 * __glPi / 180;
+
+    deltaZ = zFar - zNear;
+    sine = sin(radians);
+    if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
+	return;
+    }
+    cotangent = cos(radians) / sine;
+
+    __gluMakeIdentityd(&m[0][0]);
+    m[0][0] = cotangent / aspect;
+    m[1][1] = cotangent;
+    m[2][2] = -(zFar + zNear) / deltaZ;
+    m[2][3] = -1;
+    m[3][2] = -2 * zNear * zFar / deltaZ;
+    m[3][3] = 0;
+    GLC_Context::current()->glcMultMatrix(GLC_Matrix4x4(&m[0][0]));
+}
+
+static void normalize(float v[3])
+{
+    float r;
+
+    r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
+    if (r == 0.0) return;
+
+    v[0] /= r;
+    v[1] /= r;
+    v[2] /= r;
+}
+
+static void cross(float v1[3], float v2[3], float result[3])
+{
+    result[0] = v1[1]*v2[2] - v1[2]*v2[1];
+    result[1] = v1[2]*v2[0] - v1[0]*v2[2];
+    result[2] = v1[0]*v2[1] - v1[1]*v2[0];
+}
+
+void glc::gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
+	  GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
+	  GLdouble upz)
+{
+    float forward[3], side[3], up[3];
+    GLfloat m[4][4];
+
+    forward[0] = centerx - eyex;
+    forward[1] = centery - eyey;
+    forward[2] = centerz - eyez;
+
+    up[0] = upx;
+    up[1] = upy;
+    up[2] = upz;
+
+    normalize(forward);
+
+    /* Side = forward x up */
+    cross(forward, up, side);
+    normalize(side);
+
+    /* Recompute up as: up = side x forward */
+    cross(side, forward, up);
+
+    __gluMakeIdentityf(&m[0][0]);
+    m[0][0] = side[0];
+    m[1][0] = side[1];
+    m[2][0] = side[2];
+
+    m[0][1] = up[0];
+    m[1][1] = up[1];
+    m[2][1] = up[2];
+
+    m[0][2] = -forward[0];
+    m[1][2] = -forward[1];
+    m[2][2] = -forward[2];
+
+    GLC_Matrix4x4 translate;
+    translate.setMatTranslate(-eyex, -eyey, -eyez);
+    GLC_Matrix4x4 result= GLC_Matrix4x4(&m[0][0]) * translate;
+    GLC_Context::current()->glcMultMatrix(result);
+}
+
+static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4],
+		      GLdouble out[4])
+{
+    int i;
+
+    for (i=0; i<4; i++) {
+	out[i] = 
+	    in[0] * matrix[0*4+i] +
+	    in[1] * matrix[1*4+i] +
+	    in[2] * matrix[2*4+i] +
+	    in[3] * matrix[3*4+i];
+    }
+}
+
+/*
+** Invert 4x4 matrix.
+** Contributed by David Moore (See Mesa bug #6748)
+*/
+static int __gluInvertMatrixd(const GLdouble m[16], GLdouble invOut[16])
+{
+    double inv[16], det;
+    int i;
+
+    inv[0] =   m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]
+             + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
+    inv[4] =  -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]
+             - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
+    inv[8] =   m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]
+             + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
+    inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]
+             - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
+    inv[1] =  -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]
+             - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
+    inv[5] =   m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]
+             + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
+    inv[9] =  -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]
+             - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
+    inv[13] =  m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]
+             + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
+    inv[2] =   m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]
+             + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
+    inv[6] =  -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]
+             - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
+    inv[10] =  m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]
+             + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
+    inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]
+             - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
+    inv[3] =  -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]
+             - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
+    inv[7] =   m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]
+             + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
+    inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]
+             - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
+    inv[15] =  m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]
+             + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];
+
+    det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
+    if (det == 0)
+        return GL_FALSE;
+
+    det = 1.0 / det;
+
+    for (i = 0; i < 16; i++)
+        invOut[i] = inv[i] * det;
+
+    return GL_TRUE;
+}
+
+static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16],
+				GLdouble r[16])
+{
+    int i, j;
+
+    for (i = 0; i < 4; i++) {
+	for (j = 0; j < 4; j++) {
+	    r[i*4+j] = 
+		a[i*4+0]*b[0*4+j] +
+		a[i*4+1]*b[1*4+j] +
+		a[i*4+2]*b[2*4+j] +
+		a[i*4+3]*b[3*4+j];
+	}
+    }
+}
+
+GLint glc::gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
+	      const GLdouble modelMatrix[16], 
+	      const GLdouble projMatrix[16],
+              const GLint viewport[4],
+	      GLdouble *winx, GLdouble *winy, GLdouble *winz)
+{
+    double in[4];
+    double out[4];
+
+    in[0]=objx;
+    in[1]=objy;
+    in[2]=objz;
+    in[3]=1.0;
+    __gluMultMatrixVecd(modelMatrix, in, out);
+    __gluMultMatrixVecd(projMatrix, out, in);
+    if (in[3] == 0.0) return(GL_FALSE);
+    in[0] /= in[3];
+    in[1] /= in[3];
+    in[2] /= in[3];
+    /* Map x, y and z to range 0-1 */
+    in[0] = in[0] * 0.5 + 0.5;
+    in[1] = in[1] * 0.5 + 0.5;
+    in[2] = in[2] * 0.5 + 0.5;
+
+    /* Map x,y to viewport */
+    in[0] = in[0] * viewport[2] + viewport[0];
+    in[1] = in[1] * viewport[3] + viewport[1];
+
+    *winx=in[0];
+    *winy=in[1];
+    *winz=in[2];
+    return(GL_TRUE);
+}
+
+GLint glc::gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
+		const GLdouble modelMatrix[16], 
+		const GLdouble projMatrix[16],
+                const GLint viewport[4],
+	        GLdouble *objx, GLdouble *objy, GLdouble *objz)
+{
+    double finalMatrix[16];
+    double in[4];
+    double out[4];
+
+    __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
+    if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
+
+    in[0]=winx;
+    in[1]=winy;
+    in[2]=winz;
+    in[3]=1.0;
+
+    /* Map x and y from window coordinates */
+    in[0] = (in[0] - viewport[0]) / viewport[2];
+    in[1] = (in[1] - viewport[1]) / viewport[3];
+
+    /* Map to range -1 to 1 */
+    in[0] = in[0] * 2 - 1;
+    in[1] = in[1] * 2 - 1;
+    in[2] = in[2] * 2 - 1;
+
+    __gluMultMatrixVecd(finalMatrix, in, out);
+    if (out[3] == 0.0) return(GL_FALSE);
+    out[0] /= out[3];
+    out[1] /= out[3];
+    out[2] /= out[3];
+    *objx = out[0];
+    *objy = out[1];
+    *objz = out[2];
+    return(GL_TRUE);
+}
+
+GLint glc::gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw,
+	      const GLdouble modelMatrix[16], 
+	      const GLdouble projMatrix[16],
+	      const GLint viewport[4],
+	      GLclampd nearVal, GLclampd farVal,		    
+	      GLdouble *objx, GLdouble *objy, GLdouble *objz,
+	      GLdouble *objw)
+{
+    double finalMatrix[16];
+    double in[4];
+    double out[4];
+
+    __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
+    if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
+
+    in[0]=winx;
+    in[1]=winy;
+    in[2]=winz;
+    in[3]=clipw;
+
+    /* Map x and y from window coordinates */
+    in[0] = (in[0] - viewport[0]) / viewport[2];
+    in[1] = (in[1] - viewport[1]) / viewport[3];
+    in[2] = (in[2] - nearVal) / (farVal - nearVal);
+
+    /* Map to range -1 to 1 */
+    in[0] = in[0] * 2 - 1;
+    in[1] = in[1] * 2 - 1;
+    in[2] = in[2] * 2 - 1;
+
+    __gluMultMatrixVecd(finalMatrix, in, out);
+    if (out[3] == 0.0) return(GL_FALSE);
+    *objx = out[0];
+    *objy = out[1];
+    *objz = out[2];
+    *objw = out[3];
+    return(GL_TRUE);
+}
+
+void glc::gluPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay,
+		  GLint viewport[4])
+{
+    if (deltax <= 0 || deltay <= 0) { 
+	return;
+    }
+
+    /* Translate and scale the picked region to the entire window */
+    GLC_Matrix4x4 translate;
+    translate.setMatTranslate((viewport[2] - 2 * (x - viewport[0])) / deltax, (viewport[3] - 2 * (y - viewport[1])) / deltay, 0.0);
+
+    GLC_Matrix4x4 scaling;
+    scaling.setMatScaling(viewport[2] / deltax, viewport[3] / deltay, 0.0);
+    GLC_Context::current()->glcMultMatrix(translate * scaling);
+}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Context b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Context
new file mode 100644
index 000000000..d204f90bb
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Context
@@ -0,0 +1 @@
+#include "glc_context.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_ContextManager b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_ContextManager
new file mode 100644
index 000000000..8e7985eb4
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_ContextManager
@@ -0,0 +1 @@
+#include "glc_contextmanager.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Glu b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Glu
new file mode 100644
index 000000000..38ada69e1
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Glu
@@ -0,0 +1 @@
+#include "glu/glc_glu.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Octree b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Octree
index d9acc2869..28c84762c 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Octree
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_Octree
@@ -1 +1 @@
-#include <sceneGraph/glc_octree.h>
+#include "sceneGraph/glc_octree.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_OctreeNode b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_OctreeNode
index a22b7056a..abfdb83e9 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_OctreeNode
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_OctreeNode
@@ -1 +1 @@
-#include <sceneGraph/glc_octreenode.h>
+#include "sceneGraph/glc_octreenode.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_OpenGLState b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_OpenGLState
deleted file mode 100644
index b2f516dac..000000000
--- a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_OpenGLState
+++ /dev/null
@@ -1 +0,0 @@
-#include "glc_openglstate.h
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_RenderState b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_RenderState
new file mode 100644
index 000000000..aa799f8fe
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_RenderState
@@ -0,0 +1 @@
+#include "glc_renderstate.h
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_SpacePartitioning b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_SpacePartitioning
index 320e5e46e..6ddabbadd 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_SpacePartitioning
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_SpacePartitioning
@@ -1 +1 @@
-#include <sceneGraph/glc_spacepertitionning.h>
+#include "sceneGraph/glc_spacepertitionning.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructInstance b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructInstance
index 22fe9472b..7287ef0a0 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructInstance
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructInstance
@@ -1 +1 @@
-#include <sceneGraph/glc_structinstance.h>
+#include "sceneGraph/glc_structinstance.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructOccurence b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructOccurence
index cd63dc059..295022968 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructOccurence
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructOccurence
@@ -1 +1 @@
-#include <sceneGraph/glc_structoccurence.h>
+#include "sceneGraph/glc_structoccurence.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructReference b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructReference
index 28b7846ec..cc1d1983e 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructReference
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_StructReference
@@ -1 +1 @@
-#include <sceneGraph/glc_structreference.h>
+#include "sceneGraph/glc_structreference.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_TsrMover b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_TsrMover
new file mode 100644
index 000000000..d55ac1b43
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_TsrMover
@@ -0,0 +1 @@
+#include "viewport/tsrmover.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/include/GLC_UserInput b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_UserInput
new file mode 100644
index 000000000..49e7b16f0
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/include/GLC_UserInput
@@ -0,0 +1 @@
+#include "viewport/glc_userinput.h"
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dstoworld.cpp b/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dstoworld.cpp
index e638bcbba..4b7ac0542 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dstoworld.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dstoworld.cpp
@@ -45,10 +45,9 @@
 #include <QFileInfo>
 #include <QGLContext>
 
-GLC_3dsToWorld::GLC_3dsToWorld(const QGLContext *pContext)
+GLC_3dsToWorld::GLC_3dsToWorld()
 : m_pWorld(NULL)
 , m_FileName()
-, m_pQGLContext(pContext)
 , m_pCurrentMesh(NULL)
 , m_pLib3dsFile(NULL)
 , m_Materials()
@@ -387,7 +386,7 @@ void GLC_3dsToWorld::loadMaterial(Lib3dsMaterial* p3dsMaterial)
 			if (textureFile.open(QIODevice::ReadOnly))
 			{
 				// Create the texture and assign it to the material
-				GLC_Texture *pTexture = new GLC_Texture(m_pQGLContext, textureFile);
+				GLC_Texture *pTexture = new GLC_Texture(textureFile);
 				pMaterial->setTexture(pTexture);
 				m_ListOfAttachedFileName << textureFileName;
 				textureFile.close();
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dstoworld.h b/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dstoworld.h
index b5460f993..9aa7330c3 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dstoworld.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dstoworld.h
@@ -72,7 +72,7 @@ class GLC_LIB_EXPORT GLC_3dsToWorld : public QObject
 //////////////////////////////////////////////////////////////////////
 
 public:
-	GLC_3dsToWorld(const QGLContext*);
+	GLC_3dsToWorld();
 	virtual ~GLC_3dsToWorld();
 //@}
 
@@ -125,9 +125,6 @@ private:
 	//! The 3DS File name
 	QString m_FileName;
 
-	//! OpenGL Context
-	const QGLContext* m_pQGLContext;
-
 	//! The current mesh
 	GLC_Mesh* m_pCurrentMesh;
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dxmltoworld.cpp b/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dxmltoworld.cpp
index dc30a45fb..fcea092de 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dxmltoworld.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dxmltoworld.cpp
@@ -45,9 +45,8 @@ QMutex GLC_3dxmlToWorld::m_ZipMutex;
 
 static qint64 chunckSize= 10000000;
 
-GLC_3dxmlToWorld::GLC_3dxmlToWorld(const QGLContext* pContext)
+GLC_3dxmlToWorld::GLC_3dxmlToWorld()
 : QObject()
-, m_pQGLContext(pContext)
 , m_pStreamReader(NULL)
 , m_FileName()
 , m_p3dxmlArchive(NULL)
@@ -72,9 +71,11 @@ GLC_3dxmlToWorld::GLC_3dxmlToWorld(const QGLContext* pContext)
 , m_SetOfAttachedFileName()
 , m_CurrentFileName()
 , m_CurrentDateTime()
-, m_OccurenceAttrib()
+, m_V3OccurenceAttribHash()
+, m_V4OccurenceAttribList()
 , m_GetExternalRef3DName(false)
 , m_ByteArrayList()
+, m_IsVersion3(false)
 {
 
 }
@@ -90,13 +91,18 @@ GLC_3dxmlToWorld::~GLC_3dxmlToWorld()
 	clearMaterialHash();
 
 	// Clear specific attributes hash table
-	QHash<unsigned int, OccurenceAttrib*>::iterator iAttrib= m_OccurenceAttrib.begin();
-	while (m_OccurenceAttrib.constEnd() != iAttrib)
+	QHash<unsigned int, V3OccurenceAttrib*>::iterator iAttrib= m_V3OccurenceAttribHash.begin();
+	while (m_V3OccurenceAttribHash.constEnd() != iAttrib)
 	{
 		delete iAttrib.value();
 		++iAttrib;
 	}
-	m_OccurenceAttrib.clear();
+
+	const int v4OccurenceAttribCount= m_V4OccurenceAttribList.count();
+	for (int i= 0; i < v4OccurenceAttribCount; ++i)
+	{
+		delete m_V4OccurenceAttribList.at(i);
+	}
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -144,6 +150,9 @@ GLC_World* GLC_3dxmlToWorld::createWorldFrom3dxml(QFile &file, bool structureOnl
 		loadCatMaterialRef();
 	}
 
+	// Read the header
+	readHeader();
+
 	// Load the product structure
 	loadProductStructure();
 
@@ -179,7 +188,7 @@ GLC_3DRep GLC_3dxmlToWorld::create3DrepFrom3dxmlRep(const QString& fileName)
 		m_CurrentFileName= glc::archiveEntryFileName(fileName);
 
 		// Get the 3DXML time stamp
-		m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName).absolutePath() + QDir::separator() + QFileInfo(fileName).fileName()).lastModified();
+		m_CurrentDateTime= QFileInfo(QFileInfo(m_FileName)).lastModified();
 	}
 	else if (glc::isFileString(fileName))
 	{
@@ -231,7 +240,7 @@ GLC_3DRep GLC_3dxmlToWorld::create3DrepFrom3dxmlRep(const QString& fileName)
 			}
 		}
 	}
-	else if (QFileInfo(m_CurrentFileName).suffix().toLower() == "3drep")
+	else if ((QFileInfo(m_CurrentFileName).suffix().toLower() == "3drep") || (QFileInfo(m_CurrentFileName).suffix().toLower() == "xml"))
 	{
         if (GLC_State::cacheIsUsed() && GLC_State::currentCacheManager().isUsable(m_CurrentDateTime, QFileInfo(m_FileName).baseName(), QFileInfo(m_CurrentFileName).fileName()))
 		{
@@ -310,7 +319,7 @@ void GLC_3dxmlToWorld::goToRepId(const QString& id)
 	while(!m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Representation")
 			&& (m_pStreamReader->attributes().value("id").toString() == id)))
 	{
-		readNext();;
+		readNext();
 	}
 
 }
@@ -324,7 +333,7 @@ void GLC_3dxmlToWorld::gotToPolygonalRepType()
 	{
 		//qDebug() << m_pStreamReader->name();
 		//qDebug() << m_pStreamReader->attributes().value("xsi:type").toString();
-		readNext();;
+		readNext();
 	}
 
 }
@@ -347,10 +356,34 @@ QString GLC_3dxmlToWorld::readAttribute(const QString& name, bool required)
 	return attributeValue;
 }
 
+void GLC_3dxmlToWorld::readHeader()
+{
+	setStreamReaderToFile(m_RootName);
+
+	goToElement(m_pStreamReader, "Header");
+	if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
+	{
+		QString message(QString("GLC_3dxmlToWorld::readHeader Element Header Not found in ") + m_FileName);
+		GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
+		clear();
+		throw(fileFormatException);
+	}
+
+	while(endElementNotReached(m_pStreamReader, "Header"))
+	{
+		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SchemaVersion"))
+		{
+			QString version= getContent(m_pStreamReader, "SchemaVersion");
+			m_IsVersion3= version.startsWith('3');
+		}
+		readNext();
+	}
+}
+
 // Load the product structure
 void GLC_3dxmlToWorld::loadProductStructure()
 {
-	setStreamReaderToFile(m_RootName);
+
 	goToElement(m_pStreamReader, "ProductStructure");
 	if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
 	{
@@ -373,7 +406,7 @@ void GLC_3dxmlToWorld::loadProductStructure()
 			else loadInstanceRep();
 		}
 
-		readNext();;
+		readNext();
 	}
 
 	// Load Default view properties
@@ -382,11 +415,11 @@ void GLC_3dxmlToWorld::loadProductStructure()
 		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType())
 				&& ((m_pStreamReader->name() == "DefaultView") || (m_pStreamReader->name() == "GeometricRepresentationSet")))
 		{
-			if (m_pStreamReader->name() == "DefaultView") loadGraphicsProperties();
+			if (m_pStreamReader->name() == "DefaultView") loadDefaultView();
 			else if (m_pStreamReader->name() == "GeometricRepresentationSet") loadLocalRepresentations();
 
 		}
-		readNext();;
+		readNext();
 	}
 
 	// Check if an error Occur
@@ -478,17 +511,17 @@ void GLC_3dxmlToWorld::loadProductStructure()
 	// Update occurence number
 	m_pWorld->rootOccurence()->updateOccurenceNumber(1);
 
-	// Change occurence attributes
-	if (! m_OccurenceAttrib.isEmpty())
+	// Change occurence attributes for 3DXML V3
+	if (! m_V3OccurenceAttribHash.isEmpty())
 	{
-		//qDebug() << "Not visible occurence= " << m_OccurenceAttrib.size();
+		//qDebug() << "Not visible occurence= " << m_V3OccurenceAttribHash.size();
 		QList<GLC_StructOccurence*> occurenceList= m_pWorld->listOfOccurence();
 		const int size= occurenceList.size();
 		for (int i= 0; i < size; ++i)
 		{
-			if (m_OccurenceAttrib.contains(occurenceList.at(i)->occurenceNumber()))
+			if (m_V3OccurenceAttribHash.contains(occurenceList.at(i)->occurenceNumber()))
 			{
-				OccurenceAttrib* pOccurenceAttrib= m_OccurenceAttrib.value(occurenceList.at(i)->occurenceNumber());
+				V3OccurenceAttrib* pOccurenceAttrib= m_V3OccurenceAttribHash.value(occurenceList.at(i)->occurenceNumber());
 				occurenceList.at(i)->setVisibility(pOccurenceAttrib->m_IsVisible);
 				if (NULL != pOccurenceAttrib->m_pRenderProperties)
 				{
@@ -497,6 +530,27 @@ void GLC_3dxmlToWorld::loadProductStructure()
 			}
 		}
 	}
+
+	// Change occurence attributes for 3DXML V4
+	if (!m_V4OccurenceAttribList.isEmpty())
+	{
+		QHash<GLC_StructInstance*, unsigned int> instanceToIdHash;
+		const int assyCount= m_AssyLinkList.count();
+		for (int i= 0; i < assyCount; ++i)
+		{
+			AssyLink assyLink= m_AssyLinkList.at(i);
+			instanceToIdHash.insert(assyLink.m_pChildInstance, assyLink.m_InstanceId);
+		}
+
+		const int attribCount= m_V4OccurenceAttribList.count();
+		for (int i= 0; i < attribCount; ++i)
+		{
+			V4OccurenceAttrib* pCurrentV4OccurenceAttrib= m_V4OccurenceAttribList.at(i);
+			//qDebug() << pCurrentV4OccurenceAttrib->m_Path;
+			applyV4Attribute(m_pWorld->rootOccurence(), pCurrentV4OccurenceAttrib, instanceToIdHash);
+		}
+	}
+
 	// Check usage of Instance
 	InstanceOfExtRefHash::const_iterator iInstance= m_InstanceOfExtRefHash.constBegin();
 	while (m_InstanceOfExtRefHash.constEnd() != iInstance)
@@ -570,10 +624,10 @@ void GLC_3dxmlToWorld::loadReference3D()
 					}
 					userAttributes.insert(name, value);
 				}
-				readNext();;
+				readNext();
 			}
 		}
-		readNext();;
+		readNext();
 	}
 	if (!userAttributes.isEmpty())
 	{
@@ -591,6 +645,7 @@ void GLC_3dxmlToWorld::loadInstance3D()
 
 	const unsigned int instanceId= readAttribute("id", true).toUInt();
 	const QString instName(readAttribute("name", false));
+	goToElement(m_pStreamReader, "IsAggregatedBy");
 	const unsigned int aggregatedById= getContent(m_pStreamReader, "IsAggregatedBy").toUInt();
 	QString instanceOf= getContent(m_pStreamReader, "IsInstanceOf");
 	const QString matrixString= getContent(m_pStreamReader, "RelativeMatrix");
@@ -614,10 +669,10 @@ void GLC_3dxmlToWorld::loadInstance3D()
 					QString value= readAttribute("value", true);
 					userAttributes.insert(name, value);
 				}
-				readNext();;
+				readNext();
 			}
 		}
-		readNext();;
+		readNext();
 	}
 	if (!userAttributes.isEmpty())
 	{
@@ -687,7 +742,7 @@ void GLC_3dxmlToWorld::loadInstanceRep()
 {
 	const QString local= "urn:3DXML:Reference:loc:";
 
-	//const QString instName(readAttribute("name", true));
+	goToElement(m_pStreamReader, "IsAggregatedBy");
 	const unsigned int aggregatedById= getContent(m_pStreamReader, "IsAggregatedBy").toUInt();
 	QString instanceOf= getContent(m_pStreamReader, "IsInstanceOf");
 
@@ -745,7 +800,6 @@ void GLC_3dxmlToWorld::loadExternalRef3D()
 			GLC_3DRep* pRep= new GLC_3DRep(binaryRep.loadRep());
 
 			setRepresentationFileName(pRep);
-			factorizeMaterial(pRep);
 
 			GLC_StructReference* pCurrentRef= new GLC_StructReference(pRep);
 			pCurrentRef->setName(QFileInfo(m_CurrentFileName).baseName());
@@ -952,103 +1006,7 @@ GLC_StructReference* GLC_3dxmlToWorld::createReferenceRep(QString repId, GLC_3DR
 			currentMesh3DRep.addGeom(pMesh);
 		}
 
-		// Get the master lod accuracy
-		double masterLodAccuracy= readAttribute("accuracy", false).toDouble();
-
-		loadLOD(pMesh);
-		if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
-		{
-			QStringList stringList(m_FileName);
-			stringList.append(m_CurrentFileName);
-			stringList.append("Master LOD not found");
-			GLC_ErrorLog::addError(stringList);
-			return new GLC_StructReference("Empty Rep");
-		}
-
-		// Load Faces index data
-		while (endElementNotReached(m_pStreamReader, "Faces"))
-		{
-			readNext();;
-			if ( m_pStreamReader->name() == "Face")
-			{
-				loadFace(pMesh, 0, masterLodAccuracy);
-			}
-		}
-		checkForXmlError("End of Faces not found");
-
-		while (startElementNotReached(m_pStreamReader, "Edges") && startElementNotReached(m_pStreamReader, "VertexBuffer"))
-		{
-			readNext();;
-		}
-
-		checkForXmlError("Element VertexBuffer not found");
-		if (m_pStreamReader->name() == "Edges")
-		{
-			while (endElementNotReached(m_pStreamReader, "Edges"))
-			{
-				readNext();;
-				if ( m_pStreamReader->name() == "Polyline")
-				{
-					loadPolyline(pMesh);
-					readNext();;
-				}
-			}
-		}
-
-
-		{
-			QString verticePosition= getContent(m_pStreamReader, "Positions").replace(',', ' ');
-			//qDebug() << "Position " << verticePosition;
-			checkForXmlError("Error while retrieving Position ContentVertexBuffer");
-			// Load Vertice position
-			QTextStream verticeStream(&verticePosition);
-			QList<GLfloat> verticeValues;
-			QString buff;
-			while ((!verticeStream.atEnd()))
-			{
-				verticeStream >> buff;
-				verticeValues.append(buff.toFloat());
-			}
-			pMesh->addVertice(verticeValues.toVector());
-
-		}
-
-		{
-			QString normals= getContent(m_pStreamReader, "Normals").replace(',', ' ');
-			//qDebug() << "Normals " << normals;
-			checkForXmlError("Error while retrieving Normals values");
-			// Load Vertice Normals
-			QTextStream normalsStream(&normals);
-			QList<GLfloat> normalValues;
-			QString buff;
-			while ((!normalsStream.atEnd()))
-			{
-				normalsStream >> buff;
-				normalValues.append(buff.toFloat());
-			}
-			pMesh->addNormals(normalValues.toVector());
-		}
-
-		// Try to find texture coordinate
-		while (endElementNotReached(m_pStreamReader, "VertexBuffer"))
-		{
-			//qDebug() << "Try to find texture coordinate " << m_pStreamReader->name() << " " << m_pStreamReader->lineNumber();
-			if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "TextureCoordinates"))
-			{
-				QString texels= getContent(m_pStreamReader, "TextureCoordinates").replace(',', ' ');
-				checkForXmlError("Error while retrieving Texture coordinates");
-				QTextStream texelStream(&texels);
-				QList<GLfloat> texelValues;
-				QString buff;
-				while ((!texelStream.atEnd()))
-				{
-					texelStream >> buff;
-					texelValues.append(buff.toFloat());
-				}
-				pMesh->addTexels(texelValues.toVector());
-			}
-			readNext();;
-		}
+		loadRep(pMesh);
 
 		++numberOfMesh;
 	}
@@ -1166,8 +1124,6 @@ void GLC_3dxmlToWorld::createUnfoldedTree()
 		++iLink;
 	}
 
-	m_AssyLinkList.clear();
-
 	// Check the assembly structure occurence
 	ReferenceHash::const_iterator iRef= m_ReferenceHash.constBegin();
 	while (m_ReferenceHash.constEnd() != iRef)
@@ -1239,34 +1195,7 @@ void GLC_3dxmlToWorld::checkForXmlError(const QString& info)
 		throw(fileFormatException);
 	}
 }
-// Go to the master LOD
-void GLC_3dxmlToWorld::loadLOD(GLC_Mesh* pMesh)
-{
-	int lodIndex= 1;
-	while(!m_pStreamReader->atEnd() && !((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "Faces")))
-	{
-		readNext();;
-		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
-		{
-			m_pCurrentMaterial= loadSurfaceAttributes();
-		}
-		else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "PolygonalLOD"))
-		{
-			double accuracy= readAttribute("accuracy", true).toDouble();
-			// Load Faces index data
-			while (endElementNotReached(m_pStreamReader, "Faces"))
-			{
-				readNext();;
-				if ( m_pStreamReader->name() == "Face")
-				{
-					loadFace(pMesh, lodIndex, accuracy);
-				}
-			}
-			checkForXmlError("End of Faces not found");
-			++lodIndex;
-		}
-	}
-}
+
 // Load a face
 void GLC_3dxmlToWorld::loadFace(GLC_Mesh* pMesh, const int lod, double accuracy)
 {
@@ -1292,7 +1221,7 @@ void GLC_3dxmlToWorld::loadFace(GLC_Mesh* pMesh, const int lod, double accuracy)
 		{
 			pCurrentMaterial= loadSurfaceAttributes();
 		}
-		readNext();;
+		readNext();
 	}
 	if (NULL == pCurrentMaterial)
 	{
@@ -1365,14 +1294,30 @@ void GLC_3dxmlToWorld::loadPolyline(GLC_Mesh* pMesh)
 
 	data.replace(',', ' ');
 	QTextStream dataStream(&data);
-	GLfloatVector dataVector;
+	QList<GLfloat> values;
 	QString buff;
 	while ((!dataStream.atEnd()))
 	{
 		dataStream >> buff;
-		dataVector.append(buff.toFloat());
+		values.append(buff.toFloat());
 	}
-	pMesh->addVerticeGroup(dataVector);
+	if ((values.size() % 3) == 0)
+	{
+		pMesh->addVerticeGroup(values.toVector());
+	}
+	else
+	{
+		QString message(QString("polyline buffer is not a multiple of 3 ") + m_CurrentFileName);
+
+		QStringList stringList(message);
+		GLC_ErrorLog::addError(stringList);
+
+		GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
+		clear();
+		throw(fileFormatException);
+	}
+
+
 }
 
 // Clear material hash
@@ -1404,7 +1349,7 @@ GLC_Material* GLC_3dxmlToWorld::loadSurfaceAttributes()
 		{
 			while (endElementNotReached(m_pStreamReader, "MaterialApplication"))
 			{
-				readNext();;
+				readNext();
 				if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "MaterialId"))
 				{
 					checkForXmlError("Material ID not found");
@@ -1414,7 +1359,7 @@ GLC_Material* GLC_3dxmlToWorld::loadSurfaceAttributes()
 			}
 
 		}
-		readNext();;
+		readNext();
 	}
 
 	return pMaterial;
@@ -1566,7 +1511,7 @@ void GLC_3dxmlToWorld::loadLocalRepresentations()
 			}
 			delete pRef;
 		}
-		readNext();;
+		readNext();
 	}
 	//qDebug() << "Local rep loaded";
 
@@ -1586,7 +1531,7 @@ void GLC_3dxmlToWorld::loadLocalRepresentations()
 	}
 }
 
-void GLC_3dxmlToWorld::loadGraphicsProperties()
+void GLC_3dxmlToWorld::loadDefaultView()
 {
 	if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
 	{
@@ -1601,10 +1546,11 @@ void GLC_3dxmlToWorld::loadGraphicsProperties()
 	{
 		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "DefaultViewProperty"))
 		{
-			loadDefaultViewProperty();
+			if (m_IsVersion3) loadV3DefaultViewProperty();
+			else loadV4DefaultViewProperty();
 		}
 
-		readNext();;
+		readNext();
 	}
 
 	// Check if an error Occur
@@ -1618,7 +1564,7 @@ void GLC_3dxmlToWorld::loadGraphicsProperties()
 
 }
 
-void GLC_3dxmlToWorld::loadDefaultViewProperty()
+void GLC_3dxmlToWorld::loadV3DefaultViewProperty()
 {
 	goToElement(m_pStreamReader, "OccurenceId");
 	unsigned int occurenceId= getContent(m_pStreamReader, "OccurenceId").toUInt();
@@ -1635,13 +1581,13 @@ void GLC_3dxmlToWorld::loadDefaultViewProperty()
 					QString visibleString= readAttribute("visible", true);
 					if (visibleString != "true")
 					{
-						if (!m_OccurenceAttrib.contains(occurenceId))
+						if (!m_V3OccurenceAttribHash.contains(occurenceId))
 						{
-							OccurenceAttrib* pOccurenceAttrib= new OccurenceAttrib();
+							V3OccurenceAttrib* pOccurenceAttrib= new V3OccurenceAttrib();
 							pOccurenceAttrib->m_IsVisible= false;
-							m_OccurenceAttrib.insert(occurenceId, pOccurenceAttrib);
+							m_V3OccurenceAttribHash.insert(occurenceId, pOccurenceAttrib);
 						}
-						else m_OccurenceAttrib.value(occurenceId)->m_IsVisible= false;
+						else m_V3OccurenceAttribHash.value(occurenceId)->m_IsVisible= false;
 					}
 				}
 				else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
@@ -1669,21 +1615,21 @@ void GLC_3dxmlToWorld::loadDefaultViewProperty()
 						pRenderProperties->setOverwriteTransparency(static_cast<float>(alpha));
 						pRenderProperties->setRenderingMode(glc::OverwriteTransparency);
 					}
-					if (!m_OccurenceAttrib.contains(occurenceId))
+					if (!m_V3OccurenceAttribHash.contains(occurenceId))
 					{
-						OccurenceAttrib* pOccurenceAttrib= new OccurenceAttrib();
+						V3OccurenceAttrib* pOccurenceAttrib= new V3OccurenceAttrib();
 						pOccurenceAttrib->m_pRenderProperties= pRenderProperties;
-						m_OccurenceAttrib.insert(occurenceId, pOccurenceAttrib);
+						m_V3OccurenceAttribHash.insert(occurenceId, pOccurenceAttrib);
 					}
-					else m_OccurenceAttrib.value(occurenceId)->m_pRenderProperties= pRenderProperties;
+					else m_V3OccurenceAttribHash.value(occurenceId)->m_pRenderProperties= pRenderProperties;
 				}
 
-				readNext();;
+				readNext();
 			}
 
 		}
 
-		readNext();;
+		readNext();
 	}
 
 	// Check if an error Occur
@@ -1696,6 +1642,120 @@ void GLC_3dxmlToWorld::loadDefaultViewProperty()
 	}
 
 }
+
+void GLC_3dxmlToWorld::loadV4DefaultViewProperty()
+{
+	V4OccurenceAttrib* pV4OccurenceAttrib= new V4OccurenceAttrib();
+
+	while(endElementNotReached(m_pStreamReader, "DefaultViewProperty"))
+	{
+		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "OccurenceId"))
+		{
+			pV4OccurenceAttrib->m_Path= loadOccurencePath();
+		}
+		else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "RelativePosition"))
+		{
+			const QString matrix= getContent(m_pStreamReader, "RelativePosition");
+			pV4OccurenceAttrib->m_pMatrix= new GLC_Matrix4x4(loadMatrix(matrix));
+		}
+		else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GraphicProperties"))
+		{
+			loadGraphicProperties(pV4OccurenceAttrib);
+		}
+		readNext();
+	}
+
+	if(!pV4OccurenceAttrib->m_Path.isEmpty())
+	{
+		m_V4OccurenceAttribList.append(pV4OccurenceAttrib);
+	}
+	else
+	{
+		delete pV4OccurenceAttrib;
+	}
+
+	// Check if an error Occur
+	if (m_pStreamReader->hasError())
+	{
+		QString message(QString("GLC_3dxmlToWorld::loadV4DefaultViewProperty An error occur in ") + m_FileName);
+		GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
+		clear();
+		throw(fileFormatException);
+	}
+
+}
+
+QList<unsigned int> GLC_3dxmlToWorld::loadOccurencePath()
+{
+	QList<unsigned int> path;
+	while(endElementNotReached(m_pStreamReader, "OccurenceId"))
+	{
+		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "id"))
+		{
+			QString instanceId= getContent(m_pStreamReader, "id");
+			instanceId= instanceId.right(instanceId.length() - 1 - instanceId.indexOf('#'));
+			path.append(instanceId.toUInt());
+		}
+		readNext();
+	}
+
+	// Check if an error Occur
+	if (m_pStreamReader->hasError() || path.contains(0))
+	{
+		QString message(QString("GLC_3dxmlToWorld::loadOccurencePath An error occur in ") + m_FileName);
+		GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
+		clear();
+		throw(fileFormatException);
+	}
+
+	return path;
+}
+
+void GLC_3dxmlToWorld::loadGraphicProperties(V4OccurenceAttrib* pAttrib)
+{
+	while(endElementNotReached(m_pStreamReader, "GraphicProperties"))
+	{
+		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "GeneralAttributes"))
+		{
+			QString visibleString= readAttribute("visible", true);
+			if (visibleString != "true")
+			{
+				pAttrib->m_IsVisible= false;
+			}
+		}
+		else if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "SurfaceAttributes"))
+		{
+			goToElement(m_pStreamReader, "Color");
+			const double red= readAttribute("red", true).toDouble();
+			const double green= readAttribute("green", true).toDouble();
+			const double blue= readAttribute("blue", true).toDouble();
+			double alpha= 1.0;
+			QString alphaString= readAttribute("alpha", false);
+			if (!alphaString.isEmpty()) alpha= alphaString.toDouble();
+
+			GLC_RenderProperties* pRenderProperties= new GLC_RenderProperties();
+			if (red != -1.0f)
+			{
+				QColor diffuseColor;
+				diffuseColor.setRgbF(red, green, blue, alpha);
+				GLC_Material* pMaterial= new GLC_Material();
+				pMaterial->setDiffuseColor(diffuseColor);
+				pRenderProperties->setOverwriteMaterial(pMaterial);
+				pRenderProperties->setRenderingMode(glc::OverwriteMaterial);
+			}
+			else if (alpha < 1.0f)
+			{
+				pRenderProperties->setOverwriteTransparency(static_cast<float>(alpha));
+				pRenderProperties->setRenderingMode(glc::OverwriteTransparency);
+			}
+
+			pAttrib->m_pRenderProperties= pRenderProperties;
+		}
+
+		readNext();
+	}
+}
+
 // Load the extern representation
 void GLC_3dxmlToWorld::loadExternRepresentations()
 {
@@ -1734,7 +1794,6 @@ void GLC_3dxmlToWorld::loadExternRepresentations()
 				GLC_BSRep binaryRep= cacheManager.binary3DRep(QFileInfo(m_FileName).baseName(), m_CurrentFileName);
 				representation= binaryRep.loadRep();
 				setRepresentationFileName(&representation);
-				factorizeMaterial(&representation);
 			}
 			else
 			{
@@ -1853,110 +1912,8 @@ GLC_3DRep GLC_3dxmlToWorld::loadCurrentExtRep()
 			currentMeshRep.addGeom(pMesh);
 		}
 
-		// Get the master lod accuracy
-		double masteLodAccuracy= readAttribute("accuracy", false).toDouble();
+		loadRep(pMesh);
 
-		loadLOD(pMesh);
-		if (m_pStreamReader->atEnd() || m_pStreamReader->hasError())
-		{
-			QStringList stringList(m_FileName);
-			stringList.append(m_CurrentFileName);
-			stringList.append("Master LOD not found");
-			GLC_ErrorLog::addError(stringList);
-
-			pMesh->finish();
-			currentMeshRep.clean();
-
-			if (GLC_State::cacheIsUsed())
-			{
-				GLC_CacheManager currentManager= GLC_State::currentCacheManager();
-				currentManager.addToCache(QFileInfo(m_FileName).baseName(), currentMeshRep);
-			}
-
-			return currentMeshRep;
-		}
-
-		// Load Faces index data
-		while (endElementNotReached(m_pStreamReader, "Faces"))
-		{
-			readNext();;
-			if ( m_pStreamReader->name() == "Face")
-			{
-				loadFace(pMesh, 0, masteLodAccuracy);
-			}
-		}
-		checkForXmlError("End of Faces not found");
-
-		while (startElementNotReached(m_pStreamReader, "Edges") && startElementNotReached(m_pStreamReader, "VertexBuffer"))
-		{
-			readNext();;
-		}
-
-		checkForXmlError("Element VertexBuffer not found");
-		if (m_pStreamReader->name() == "Edges")
-		{
-			while (endElementNotReached(m_pStreamReader, "Edges"))
-			{
-				readNext();;
-				if ( m_pStreamReader->name() == "Polyline")
-				{
-					loadPolyline(pMesh);
-					readNext();;
-				}
-			}
-		}
-
-		{
-			QString verticePosition= getContent(m_pStreamReader, "Positions").replace(',', ' ');
-			//qDebug() << "Position " << verticePosition;
-			checkForXmlError("Error while retrieving Position ContentVertexBuffer");
-			// Load Vertice position
-			QTextStream verticeStream(&verticePosition);
-			QList<GLfloat> verticeValues;
-			QString buff;
-			while ((!verticeStream.atEnd()))
-			{
-				verticeStream >> buff;
-				verticeValues.append(buff.toFloat());
-			}
-			pMesh->addVertice(verticeValues.toVector());
-
-		}
-
-		{
-			QString normals= getContent(m_pStreamReader, "Normals").replace(',', ' ');
-			//qDebug() << "Normals " << normals;
-			checkForXmlError("Error while retrieving Normals values");
-			// Load Vertice Normals
-			QTextStream normalsStream(&normals);
-			QList<GLfloat> normalValues;
-			QString buff;
-			while ((!normalsStream.atEnd()))
-			{
-				normalsStream >> buff;
-				normalValues.append(buff.toFloat());
-			}
-			pMesh->addNormals(normalValues.toVector());
-		}
-		// Try to find texture coordinate
-		while (endElementNotReached(m_pStreamReader, "VertexBuffer"))
-		{
-			if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "TextureCoordinates"))
-			{
-				QString texels= getContent(m_pStreamReader, "TextureCoordinates").replace(',', ' ');
-				checkForXmlError("Error while retrieving Texture coordinates");
-				QTextStream texelStream(&texels);
-				QList<GLfloat> texelValues;
-				QString buff;
-				while ((!texelStream.atEnd()))
-				{
-					texelStream >> buff;
-					texelValues.append(buff.toFloat());
-				}
-				pMesh->addTexels(texelValues.toVector());
-			}
-			readNext();;
-		}
 		++numberOfMesh;
 	}
 
@@ -2001,7 +1958,7 @@ void GLC_3dxmlToWorld::loadCatMaterialRef()
 					//qDebug() << "Material " << currentMaterial.m_Name << " Added";
 				}
 			}
-			readNext();;
+			readNext();
 		}
 	}
 	// Load material files
@@ -2024,7 +1981,7 @@ void GLC_3dxmlToWorld::loadMaterialDef(const MaterialRef& materialRef)
 	checkForXmlError(QString("Element Osm not found in file : ") + materialRef.m_AssociatedFile);
 	while (endElementNotReached(m_pStreamReader, "Osm"))
 	{
-		readNext();;
+		readNext();
 		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && m_pStreamReader->name() == "Attr")
 		{
 			const QString currentName= readAttribute("Name", true);
@@ -2121,7 +2078,7 @@ void GLC_3dxmlToWorld::loadCatRepImage()
 					m_TextureImagesHash.insert(id,associatedFile);
 				}
 			}
-			readNext();;
+			readNext();
 		}
 		//qDebug() << "CATRepImage.3dxml Load";
 	}
@@ -2187,7 +2144,7 @@ GLC_Texture* GLC_3dxmlToWorld::loadTexture(QString fileName)
 	GLC_Texture* pTexture= NULL;
 	if (!resultImage.isNull())
 	{
-		pTexture= new GLC_Texture(m_pQGLContext, resultImage, resultImageFileName);
+		pTexture= new GLC_Texture(resultImage, resultImageFileName);
 	}
 	else
 	{
@@ -2199,47 +2156,6 @@ GLC_Texture* GLC_3dxmlToWorld::loadTexture(QString fileName)
 	return pTexture;
 }
 
-// Factorize material use
-void GLC_3dxmlToWorld::factorizeMaterial(GLC_3DRep* pRep)
-{
-	//qDebug() << "GLC_3dxmlToWorld::factorizeMaterial";
-	// Get the Set of materials of the rep
-	QSet<GLC_Material*> repMaterialSet= pRep->materialSet();
-	//! The hash table of rep material
-	QHash<GLC_uint, GLC_Material*> repMaterialHash;
-	// Construct the map of material String Hash and Id
-	QHash<QString, GLC_uint> materialMap;
-
-	{ // Fill the map of material
-		QSet<GLC_Material*>::const_iterator iMat= repMaterialSet.constBegin();
-		while(repMaterialSet.constEnd() != iMat)
-		{
-			GLC_Material* pCurrentMat= *iMat;
-			materialMap.insert(QString::number(pCurrentMat->hashCode()), pCurrentMat->id());
-			repMaterialHash.insert(pCurrentMat->id(), pCurrentMat);
-			++iMat;
-		}
-	}
-
-	// Make the factorization
-	QHash<QString, GLC_uint>::iterator iMat= materialMap.begin();
-	while (materialMap.constEnd() != iMat)
-	{
-		if (m_MaterialHash.contains(iMat.key()))
-		{
-			//qDebug() << "Replace Mat :" << iMat.key() << " " << iMat.value();
-			pRep->replaceMaterial(iMat.value(), m_MaterialHash.value(iMat.key()));
-		}
-		else
-		{
-			//qDebug() << "Indert mat " << iMat.key() << " " << iMat.value();
-			m_MaterialHash.insert(iMat.key(), repMaterialHash.value(iMat.value()));
-		}
-		++iMat;
-	}
-
-}
-
 void GLC_3dxmlToWorld::setRepresentationFileName(GLC_3DRep* pRep)
 {
 	if (m_IsInArchive)
@@ -2267,3 +2183,235 @@ void GLC_3dxmlToWorld::checkFileValidity(QIODevice* pIODevice)
 		pIODevice->seek(0);
 	}
 }
+
+void GLC_3dxmlToWorld::applyV4Attribute(GLC_StructOccurence* pOccurence, V4OccurenceAttrib* pV4OccurenceAttrib, QHash<GLC_StructInstance*, unsigned int>& instanceToIdHash)
+{
+	Q_ASSERT(pOccurence->hasChild() && !pV4OccurenceAttrib->m_Path.isEmpty());
+	unsigned int id= pV4OccurenceAttrib->m_Path.takeFirst();
+
+	const int childCount= pOccurence->childCount();
+	bool occurenceFound= false;
+	int i= 0;
+	while (!occurenceFound && (i < childCount))
+	{
+		GLC_StructOccurence* pChildOccurence= pOccurence->child(i);
+		if (instanceToIdHash.contains(pChildOccurence->structInstance()) && (instanceToIdHash.value(pChildOccurence->structInstance()) == id))
+		{
+			Q_ASSERT(id == instanceToIdHash.value(pChildOccurence->structInstance()));
+			occurenceFound= true;
+
+			if (pV4OccurenceAttrib->m_Path.isEmpty())
+			{
+				pChildOccurence->setVisibility(pV4OccurenceAttrib->m_IsVisible);
+				if (NULL != pV4OccurenceAttrib->m_pRenderProperties)
+				{
+					pChildOccurence->setRenderProperties(*(pV4OccurenceAttrib->m_pRenderProperties));
+				}
+				if (pV4OccurenceAttrib->m_pMatrix != NULL)
+				{
+					pChildOccurence->makeFlexible(*(pV4OccurenceAttrib->m_pMatrix));
+				}
+			}
+			else
+			{
+				applyV4Attribute(pChildOccurence, pV4OccurenceAttrib, instanceToIdHash);
+			}
+		}
+		else
+		{
+			++i;
+		}
+	}
+	if (!occurenceFound)
+	{
+		qDebug() << "GLC_3dxmlToWorld::applyV4Attribute Occurrence not found" << id;
+	}
+
+}
+
+void GLC_3dxmlToWorld::loadRep(GLC_Mesh* pMesh)
+{
+	double masteLodAccuracy= readAttribute("accuracy", false).toDouble();
+	int lodIndex= 1;
+
+	bool masterLodFound= false;
+	bool vertexBufferFound= false;
+
+	while (endElementNotReached(m_pStreamReader, "Rep") && endElementNotReached(m_pStreamReader, "Root"))
+	{
+		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()))
+		{
+			if (m_pStreamReader->name() == "SurfaceAttributes")
+			{
+				m_pCurrentMaterial= loadSurfaceAttributes();
+			}
+			else if (m_pStreamReader->name() == "PolygonalLOD")
+			{
+				double accuracy= readAttribute("accuracy", true).toDouble();
+				while (endElementNotReached(m_pStreamReader, "Faces"))
+				{
+					readNext();
+					if ( m_pStreamReader->name() == "Face")
+					{
+						loadFace(pMesh, lodIndex, accuracy);
+					}
+				}
+				checkForXmlError("End of Faces not found");
+				++lodIndex;
+			}
+			else if (m_pStreamReader->name() == "Faces")
+			{
+				masterLodFound= true;
+				while (endElementNotReached(m_pStreamReader, "Faces"))
+				{
+					readNext();
+					if ( m_pStreamReader->name() == "Face")
+					{
+						loadFace(pMesh, 0, masteLodAccuracy);
+					}
+				}
+				checkForXmlError("End of Faces not found");
+			}
+			else if (m_pStreamReader->name() == "Edges")
+			{
+				while (endElementNotReached(m_pStreamReader, "Edges"))
+				{
+					readNext();
+					if ( m_pStreamReader->name() == "Polyline")
+					{
+						loadPolyline(pMesh);
+						readNext();
+					}
+				}
+			}
+			else if (m_pStreamReader->name() == "VertexBuffer")
+			{
+				vertexBufferFound= true;
+				loadVertexBuffer(pMesh);
+			}
+			else readNext();
+		}
+		else
+		{
+			readNext();
+		}
+	}
+	checkForXmlError("End of Rep or Root not found");
+
+	if (!masterLodFound || !vertexBufferFound)
+	{
+		QString message;
+		if (!masterLodFound)
+		{
+			message= QString("Master LOD not found in file ") + m_FileName;
+		}
+		else
+		{
+			message= QString("Vertex Buffer not found in file ") + m_FileName;
+		}
+		GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
+		clear();
+		throw(fileFormatException);
+	}
+
+
+}
+
+void GLC_3dxmlToWorld::loadVertexBuffer(GLC_Mesh* pMesh)
+{
+	{
+		QString verticePosition= getContent(m_pStreamReader, "Positions").replace(',', ' ');
+		//qDebug() << "Position " << verticePosition;
+		checkForXmlError("Error while retrieving Position ContentVertexBuffer");
+		// Load Vertice position
+		QTextStream verticeStream(&verticePosition);
+		QList<GLfloat> verticeValues;
+		QString buff;
+		while ((!verticeStream.atEnd()))
+		{
+			verticeStream >> buff;
+			verticeValues.append(buff.toFloat());
+		}
+		if ((verticeValues.size() % 3) == 0)
+		{
+			pMesh->addVertice(verticeValues.toVector());
+		}
+		else
+		{
+			QString message(QString("Vertice buffer is not a multiple of 3 ") + m_CurrentFileName);
+
+			QStringList stringList(message);
+			GLC_ErrorLog::addError(stringList);
+
+			GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
+			clear();
+			throw(fileFormatException);
+		}
+	}
+
+	{
+		QString normals= getContent(m_pStreamReader, "Normals").replace(',', ' ');
+		//qDebug() << "Normals " << normals;
+		checkForXmlError("Error while retrieving Normals values");
+		// Load Vertice Normals
+		QTextStream normalsStream(&normals);
+		QList<GLfloat> normalValues;
+		QString buff;
+		while ((!normalsStream.atEnd()))
+		{
+			normalsStream >> buff;
+			normalValues.append(buff.toFloat());
+		}
+		if ((normalValues.size() % 3) == 0)
+		{
+			pMesh->addNormals(normalValues.toVector());
+		}
+		else
+		{
+			QString message(QString("Normal buffer is not a multiple of 3 ") + m_CurrentFileName);
+
+			QStringList stringList(message);
+			GLC_ErrorLog::addError(stringList);
+
+			GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
+			clear();
+			throw(fileFormatException);
+		}
+
+	}
+	// Try to find texture coordinate
+	while (endElementNotReached(m_pStreamReader, "VertexBuffer"))
+	{
+		if ((QXmlStreamReader::StartElement == m_pStreamReader->tokenType()) && (m_pStreamReader->name() == "TextureCoordinates"))
+		{
+			QString texels= getContent(m_pStreamReader, "TextureCoordinates").replace(',', ' ');
+			checkForXmlError("Error while retrieving Texture coordinates");
+			QTextStream texelStream(&texels);
+			QList<GLfloat> texelValues;
+			QString buff;
+			while ((!texelStream.atEnd()))
+			{
+				texelStream >> buff;
+				texelValues.append(buff.toFloat());
+			}
+
+			if ((texelValues.size() % 2) == 0)
+			{
+				pMesh->addTexels(texelValues.toVector());
+			}
+			else
+			{
+				QString message(QString("Texel buffer is not a multiple of 2 ") + m_CurrentFileName);
+
+				QStringList stringList(message);
+				GLC_ErrorLog::addError(stringList);
+
+				GLC_FileFormatException fileFormatException(message, m_FileName, GLC_FileFormatException::WrongFileFormat);
+				clear();
+				throw(fileFormatException);
+			}
+		}
+		readNext();
+	}
+	checkForXmlError("VertexBuffer not found");
+}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dxmltoworld.h b/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dxmltoworld.h
index 6bf002b54..1b2c094dd 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dxmltoworld.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_3dxmltoworld.h
@@ -34,7 +34,7 @@
 #include "../maths/glc_matrix4x4.h"
 #include "../sceneGraph/glc_3dviewinstance.h"
 
-#include "glc_config.h"
+#include "../glc_config.h"
 
 class GLC_World;
 class QGLContext;
@@ -42,6 +42,7 @@ class QuaZip;
 class QuaZipFile;
 class GLC_StructReference;
 class GLC_StructInstance;
+class GLC_StructOccurence;
 class GLC_Mesh;
 
 //////////////////////////////////////////////////////////////////////
@@ -78,15 +79,15 @@ class GLC_LIB_EXPORT GLC_3dxmlToWorld : public QObject
 		QString m_AssociatedFile;
 	};
 
-	//! \class OccurenceAttrib
-	/*! \brief OccurenceAttrib : Specifique occurence attribute */
-	struct OccurenceAttrib
+	//! \class V3OccurenceAttrib
+	/*! \brief V3OccurenceAttrib : Specifique occurence attribute */
+	struct V3OccurenceAttrib
 	{
-		inline OccurenceAttrib()
+		inline V3OccurenceAttrib()
 		: m_IsVisible(true)
 		, m_pRenderProperties(NULL)
 		{}
-		inline ~OccurenceAttrib()
+		inline ~V3OccurenceAttrib()
 		{delete m_pRenderProperties;}
 
 		//! Visibility attribute
@@ -95,6 +96,32 @@ class GLC_LIB_EXPORT GLC_3dxmlToWorld : public QObject
 		GLC_RenderProperties* m_pRenderProperties;
 	};
 
+	//! \class V3OccurenceAttrib
+	/*! \brief V3OccurenceAttrib : Specifique occurence attribute */
+	struct V4OccurenceAttrib
+	{
+		inline V4OccurenceAttrib()
+		: m_IsVisible(true)
+		, m_pRenderProperties(NULL)
+		, m_pMatrix(NULL)
+		, m_Path()
+		{}
+		inline ~V4OccurenceAttrib()
+		{
+			delete m_pRenderProperties;
+			delete m_pMatrix;
+		}
+
+		//! Visibility attribute
+		bool m_IsVisible;
+		//! Render properties attribute
+		GLC_RenderProperties* m_pRenderProperties;
+		//! Relative matrix
+		GLC_Matrix4x4* m_pMatrix;
+		//! The path of this attrib
+		QList<unsigned int> m_Path;
+	};
+
 	typedef QHash<unsigned int, GLC_StructReference*> ReferenceHash;
 	typedef QHash<GLC_StructInstance*, unsigned int> InstanceOfHash;
 	typedef QHash<GLC_StructInstance*, QString> InstanceOfExtRefHash;
@@ -111,7 +138,7 @@ class GLC_LIB_EXPORT GLC_3dxmlToWorld : public QObject
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Default constructor
-	GLC_3dxmlToWorld(const QGLContext*);
+	GLC_3dxmlToWorld();
 
 	virtual ~GLC_3dxmlToWorld();
 //@}
@@ -159,6 +186,9 @@ private:
 	//! Read the specified attribute
 	QString readAttribute(const QString&, bool required= false);
 
+	//! Read the Header
+	void readHeader();
+
 	//! Load the product structure
 	void loadProductStructure();
 
@@ -190,9 +220,6 @@ private:
 	//! Throw ecxeption if error occur
 	void checkForXmlError(const QString&);
 
-	//! Load Level of detail
-	void loadLOD(GLC_Mesh*);
-
 	//! Load a face
 	void loadFace(GLC_Mesh*, const int lod, double accuracy);
 
@@ -211,11 +238,20 @@ private:
 	//! Set the stream reader to the specified file
 	bool setStreamReaderToFile(QString, bool test= false);
 
-	//! Load graphics properties
-	void loadGraphicsProperties();
+	//! Load default view element
+	void loadDefaultView();
 
-	//! Load default view property
-	void loadDefaultViewProperty();
+	//! Load 3DXML V3 default view property
+	void loadV3DefaultViewProperty();
+
+	//! Load 3DXML V4 default view property
+	void loadV4DefaultViewProperty();
+
+	//! Return the occurence path of the current DefaultViewProperty
+	QList<unsigned int> loadOccurencePath();
+
+	//! Load Graphics properties element
+	void loadGraphicProperties(V4OccurenceAttrib* pAttrib);
 
 	//! Load the local representation
 	void loadLocalRepresentations();
@@ -238,9 +274,6 @@ private:
 	//! Try to construct a texture with the specified fileName
 	GLC_Texture* loadTexture(QString);
 
-	//! Factorize material use
-	void factorizeMaterial(GLC_3DRep*);
-
 	//! Set fileName of the given 3DRep
 	void setRepresentationFileName(GLC_3DRep* pRep);
 
@@ -268,15 +301,21 @@ private:
 	//! Check if the given file is binary
 	void checkFileValidity(QIODevice* pIODevice);
 
+	//! Apply the given attribute to the right occurence from the given occurence
+	void applyV4Attribute(GLC_StructOccurence* pOccurence, V4OccurenceAttrib* pV4OccurenceAttrib, QHash<GLC_StructInstance*, unsigned int>& InstanceToIdHash);
+
+	//! Load representation from 3DRep file
+	void loadRep(GLC_Mesh* pMesh);
+
+	//! Load The 3DXML vertex buffer
+	void loadVertexBuffer(GLC_Mesh* pMesh);
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
 // Private members
 //////////////////////////////////////////////////////////////////////
 private:
-	//! OpenGL Context
-	const QGLContext* m_pQGLContext;
-
 	//! Xml Reader
 	QXmlStreamReader* m_pStreamReader;
 
@@ -349,8 +388,11 @@ private:
 	//! The current file time and date
 	QDateTime m_CurrentDateTime;
 
-	//! Hash table of occurence specific attributes
-	QHash<unsigned int, OccurenceAttrib*> m_OccurenceAttrib;
+	//! Hash table of occurence specific attributes for 3DXML V3
+	QHash<unsigned int, V3OccurenceAttrib*> m_V3OccurenceAttribHash;
+
+	//! List of occurence specific attributes for 3DXML V4
+	QList<V4OccurenceAttrib*> m_V4OccurenceAttribList;
 
 	//! bool get external ref 3D name
 	bool m_GetExternalRef3DName;
@@ -359,6 +401,9 @@ private:
 
 	QList<QByteArray> m_ByteArrayList;
 
+	//! Flag to know if the 3DXML is in version 3.x
+	bool m_IsVersion3;
+
 };
 
 QXmlStreamReader::TokenType GLC_3dxmlToWorld::readNext()
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_colladatoworld.cpp b/ground/openpilotgcs/src/libs/glc_lib/io/glc_colladatoworld.cpp
index 6bc787274..c863be11b 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_colladatoworld.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_colladatoworld.cpp
@@ -33,13 +33,12 @@ static int currentNodeId= 0;
 using namespace glcXmlUtil;
 
 // Default constructor
-GLC_ColladaToWorld::GLC_ColladaToWorld(const QGLContext* pContext)
+GLC_ColladaToWorld::GLC_ColladaToWorld()
 : QObject()
 , m_pWorld(NULL)
-, m_pQGLContext(pContext)
 , m_pStreamReader(NULL)
 , m_FileName()
-, m_pFile()
+, m_pFile(NULL)
 , m_ImageFileHash()
 , m_MaterialLibHash()
 , m_SurfaceImageHash()
@@ -68,7 +67,7 @@ GLC_ColladaToWorld::GLC_ColladaToWorld(const QGLContext* pContext)
 // Destructor
 GLC_ColladaToWorld::~GLC_ColladaToWorld()
 {
-	// Normal ends, wold has not to be deleted
+	// Normal ends, world has not to be deleted
 	m_pWorld= NULL;
 	clear();
 }
@@ -138,6 +137,10 @@ GLC_World* GLC_ColladaToWorld::CreateWorldFromCollada(QFile &file)
 
 		m_pStreamReader->readNext();
 	}
+
+	m_pFile->close();
+	m_pFile= NULL;
+
 	// Link the textures to materials
 	linkTexturesToMaterials();
 
@@ -233,10 +236,11 @@ void GLC_ColladaToWorld::clear()
 	delete m_pWorld;
 	m_pWorld= NULL;
 
+
 	delete m_pStreamReader;
 	m_pStreamReader= NULL;
 
-	if (NULL != m_pFile) m_pFile->close();
+	if (m_pFile != NULL) m_pFile->close();
 	m_pFile= NULL;
 
 	m_ImageFileHash.clear();
@@ -1792,7 +1796,7 @@ void GLC_ColladaToWorld::linkTexturesToMaterials()
 			if (QFileInfo(fullImageFileName).exists())
 			{
 				m_ListOfAttachedFileName << fullImageFileName;
-				GLC_Texture* pTexture= new GLC_Texture(m_pQGLContext, fullImageFileName);
+				GLC_Texture* pTexture= new GLC_Texture(fullImageFileName);
 				pCurrentMaterial->setTexture(pTexture);
 			}
 			else if (QFileInfo(m_FileName).absolutePath() != QFileInfo(fullImageFileName).absolutePath())
@@ -1802,7 +1806,7 @@ void GLC_ColladaToWorld::linkTexturesToMaterials()
 				if (QFileInfo(fullImageFileName).exists())
 				{
 					m_ListOfAttachedFileName << fullImageFileName;
-					GLC_Texture* pTexture= new GLC_Texture(m_pQGLContext, fullImageFileName);
+					GLC_Texture* pTexture= new GLC_Texture(fullImageFileName);
 					pCurrentMaterial->setTexture(pTexture);
 				}
 				else
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_colladatoworld.h b/ground/openpilotgcs/src/libs/glc_lib/io/glc_colladatoworld.h
index 70c3a2042..9139305e2 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_colladatoworld.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_colladatoworld.h
@@ -161,7 +161,7 @@ private:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Default constructor
-	GLC_ColladaToWorld(const QGLContext*);
+	GLC_ColladaToWorld();
 
 	//! Destructor
 	virtual ~GLC_ColladaToWorld();
@@ -368,9 +368,6 @@ private:
 	//! The world to built
 	GLC_World* m_pWorld;
 
-	//! OpenGL Context
-	const QGLContext* m_pQGLContext;
-
 	//! Xml Reader
 	QXmlStreamReader* m_pStreamReader;
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_fileloader.cpp b/ground/openpilotgcs/src/libs/glc_lib/io/glc_fileloader.cpp
index 0801cfb98..49e364a53 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_fileloader.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_fileloader.cpp
@@ -42,8 +42,7 @@
 //////////////////////////////////////////////////////////////////////
 // Constructor
 //////////////////////////////////////////////////////////////////////
-GLC_FileLoader::GLC_FileLoader(const QGLContext *pContext)
-: m_pQGLContext(pContext)
+GLC_FileLoader::GLC_FileLoader()
 {
 }
 
@@ -89,7 +88,7 @@ GLC_World GLC_FileLoader::createWorldFromFile(QFile &file, QStringList* pAttache
 	GLC_World* pWorld= NULL;
 	if (QFileInfo(file).suffix().toLower() == "obj")
 	{
-		GLC_ObjToWorld objToWorld(m_pQGLContext);
+		GLC_ObjToWorld objToWorld;
 		connect(&objToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
 		pWorld= objToWorld.CreateWorldFromObj(file);
 		if (NULL != pAttachedFileName)
@@ -111,7 +110,7 @@ GLC_World GLC_FileLoader::createWorldFromFile(QFile &file, QStringList* pAttache
 	}
 	else if (QFileInfo(file).suffix().toLower() == "3ds")
 	{
-		GLC_3dsToWorld studioToWorld(m_pQGLContext);
+		GLC_3dsToWorld studioToWorld;
 		connect(&studioToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
 		pWorld= studioToWorld.CreateWorldFrom3ds(file);
 		if (NULL != pAttachedFileName)
@@ -121,7 +120,7 @@ GLC_World GLC_FileLoader::createWorldFromFile(QFile &file, QStringList* pAttache
 	}
 	else if (QFileInfo(file).suffix().toLower() == "3dxml")
 	{
-		GLC_3dxmlToWorld d3dxmlToWorld(m_pQGLContext);
+		GLC_3dxmlToWorld d3dxmlToWorld;
 		connect(&d3dxmlToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
 		pWorld= d3dxmlToWorld.createWorldFrom3dxml(file, false);
 		if (NULL != pAttachedFileName)
@@ -131,7 +130,7 @@ GLC_World GLC_FileLoader::createWorldFromFile(QFile &file, QStringList* pAttache
 	}
 	else if (QFileInfo(file).suffix().toLower() == "dae")
 	{
-		GLC_ColladaToWorld colladaToWorld(m_pQGLContext);
+		GLC_ColladaToWorld colladaToWorld;
 		connect(&colladaToWorld, SIGNAL(currentQuantum(int)), this, SIGNAL(currentQuantum(int)));
 		pWorld= colladaToWorld.CreateWorldFromCollada(file);
 		if (NULL != pAttachedFileName)
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_fileloader.h b/ground/openpilotgcs/src/libs/glc_lib/io/glc_fileloader.h
index e951fc527..199316b87 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_fileloader.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_fileloader.h
@@ -56,7 +56,7 @@ class GLC_LIB_EXPORT GLC_FileLoader : public QObject
 //////////////////////////////////////////////////////////////////////
 
 public:
-	GLC_FileLoader(const QGLContext*);
+	GLC_FileLoader();
 	virtual ~GLC_FileLoader();
 //@}
 //////////////////////////////////////////////////////////////////////
@@ -79,8 +79,6 @@ public:
 // Private members
 //////////////////////////////////////////////////////////////////////
 private:
-	//! OpenGL Context
-	const QGLContext* m_pQGLContext;
 };
 
 #endif /*GLC_FILELOADER_H_*/
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_objmtlloader.cpp b/ground/openpilotgcs/src/libs/glc_lib/io/glc_objmtlloader.cpp
index 442dedd01..7a3ae5cda 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_objmtlloader.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_objmtlloader.cpp
@@ -32,12 +32,11 @@
 #include <QtDebug>
 #include <QGLContext>
 
-GLC_ObjMtlLoader::GLC_ObjMtlLoader(const QGLContext *pContext, const QString& fileName)
+GLC_ObjMtlLoader::GLC_ObjMtlLoader(const QString& fileName)
 : m_FileName(fileName)
 , m_pCurrentMaterial(NULL)
 , m_Materials()
 , m_LoadStatus()
-, m_pQGLContext(pContext)
 , m_ListOfAttachedFileName()
 {
 }
@@ -214,7 +213,7 @@ void GLC_ObjMtlLoader::extractTextureFileName(QString &ligne)
 		{
 			m_ListOfAttachedFileName << textureFileName;
 			// Create the texture and assign it to current material
-			GLC_Texture *pTexture = new GLC_Texture(m_pQGLContext, textureFile);
+			GLC_Texture *pTexture = new GLC_Texture(textureFile);
 			m_pCurrentMaterial->setTexture(pTexture);
 			//qDebug() << "Texture File is : " << valueString;
 		}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_objmtlloader.h b/ground/openpilotgcs/src/libs/glc_lib/io/glc_objmtlloader.h
index 18bd5f929..9c9f34c5d 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_objmtlloader.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_objmtlloader.h
@@ -50,7 +50,7 @@ class GLC_LIB_EXPORT GLC_ObjMtlLoader
 //@{
 //////////////////////////////////////////////////////////////////////
 public:
-	GLC_ObjMtlLoader(const QGLContext*, const QString&);
+	GLC_ObjMtlLoader(const QString&);
 
 	virtual ~GLC_ObjMtlLoader();
 //@}
@@ -123,9 +123,6 @@ private:
 	//! the Load status
 	QString m_LoadStatus;
 
-	//! OpenGL Context
-	const QGLContext *m_pQGLContext;
-
 	//! The list of attached file name
 	QSet<QString> m_ListOfAttachedFileName;
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_objtoworld.cpp b/ground/openpilotgcs/src/libs/glc_lib/io/glc_objtoworld.cpp
index d9694aa0e..66b6ec224 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_objtoworld.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_objtoworld.cpp
@@ -40,10 +40,9 @@
 //////////////////////////////////////////////////////////////////////
 // Constructor
 //////////////////////////////////////////////////////////////////////
-GLC_ObjToWorld::GLC_ObjToWorld(const QGLContext *pContext)
+GLC_ObjToWorld::GLC_ObjToWorld()
 : m_pWorld(NULL)
 , m_FileName()
-, m_pQGLContext(pContext)
 , m_pMtlLoader(NULL)
 , m_CurrentLineNumber(0)
 , m_pCurrentObjMesh(NULL)
@@ -131,7 +130,7 @@ GLC_World* GLC_ObjToWorld::CreateWorldFromObj(QFile &file)
 	QString mtlLibFileName(getMtlLibFileName(mtlLibLine));
 	if (!mtlLibFileName.isEmpty())
 	{
-		m_pMtlLoader= new GLC_ObjMtlLoader(m_pQGLContext, mtlLibFileName);
+		m_pMtlLoader= new GLC_ObjMtlLoader(mtlLibFileName);
 		if (!m_pMtlLoader->loadMaterials())
 		{
 			delete m_pMtlLoader;
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_objtoworld.h b/ground/openpilotgcs/src/libs/glc_lib/io/glc_objtoworld.h
index 33e4f37aa..5d8585e7d 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_objtoworld.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_objtoworld.h
@@ -150,7 +150,7 @@ public:
 //////////////////////////////////////////////////////////////////////
 
 public:
-	GLC_ObjToWorld(const QGLContext*);
+	GLC_ObjToWorld();
 	virtual ~GLC_ObjToWorld();
 //@}
 
@@ -227,9 +227,6 @@ private:
 	//! The Obj File name
 	QString m_FileName;
 
-	//! OpenGL Context
-	const QGLContext* m_pQGLContext;
-
 	//! the Obj Mtl loader
 	GLC_ObjMtlLoader* m_pMtlLoader;
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_worldto3dxml.cpp b/ground/openpilotgcs/src/libs/glc_lib/io/glc_worldto3dxml.cpp
index 979c84bee..9270a42c6 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_worldto3dxml.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_worldto3dxml.cpp
@@ -23,8 +23,8 @@
 
 #include "glc_worldto3dxml.h"
 // Quazip library
-#include "../quazip/quazip.h"
-#include "../quazip/quazipfile.h"
+#include "../3rdparty/quazip/quazip.h"
+#include "../3rdparty/quazip/quazipfile.h"
 #include "../glc_exception.h"
 #include "../geometry/glc_mesh.h"
 
@@ -405,7 +405,7 @@ void GLC_WorldTo3dxml::exportAssemblyFromOccurence(const GLC_StructOccurence* pO
 		GLC_3DViewInstance* pInstance= m_World.collection()->instanceHandle(pOccurence->id());
 		Q_ASSERT(NULL != pInstance);
 		const bool isVisible= pInstance->isVisible();
-		const bool isOverload= !isVisible || !pInstance->renderPropertiesHandle()->isDefault();
+		const bool isOverload= !isVisible || !pInstance->renderPropertiesHandle()->isDefault() || pOccurence->isFlexible();
 		if (isOverload)
 		{
 			m_ListOfOverLoadedOccurence.append(pOccurence);
@@ -419,22 +419,22 @@ QString GLC_WorldTo3dxml::matrixString(const GLC_Matrix4x4& matrix)
 	QString resultMatrix;
 	const QChar spaceChar(' ');
 	// Rotation
-	resultMatrix+= QString::number(matrix.getData()[0]) + spaceChar;
-	resultMatrix+= QString::number(matrix.getData()[1]) + spaceChar;
-	resultMatrix+= QString::number(matrix.getData()[2]) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[0], 'g', 16) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[1], 'g', 16) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[2], 'g', 16) + spaceChar;
 
-	resultMatrix+= QString::number(matrix.getData()[4]) + spaceChar;
-	resultMatrix+= QString::number(matrix.getData()[5]) + spaceChar;
-	resultMatrix+= QString::number(matrix.getData()[6]) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[4], 'g', 16) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[5], 'g', 16) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[6], 'g', 16) + spaceChar;
 
-	resultMatrix+= QString::number(matrix.getData()[8]) + spaceChar;
-	resultMatrix+= QString::number(matrix.getData()[9]) + spaceChar;
-	resultMatrix+= QString::number(matrix.getData()[10]) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[8], 'g', 16) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[9], 'g', 16) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[10], 'g', 16) + spaceChar;
 
 	// Translation
-	resultMatrix+= QString::number(matrix.getData()[12]) + spaceChar;
-	resultMatrix+= QString::number(matrix.getData()[13]) + spaceChar;
-	resultMatrix+= QString::number(matrix.getData()[14]);
+	resultMatrix+= QString::number(matrix.getData()[12], 'g', 16) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[13], 'g', 16) + spaceChar;
+	resultMatrix+= QString::number(matrix.getData()[14], 'g', 16);
 
 	return resultMatrix;
 }
@@ -772,7 +772,7 @@ void GLC_WorldTo3dxml::writeMaterial(const GLC_Material* pMaterial)
 	}
 	else
 	{
-		materialName= pMaterial->name();
+		materialName= symplifyName(pMaterial->name());
 	}
 
 
@@ -1105,17 +1105,30 @@ void GLC_WorldTo3dxml::addImageTextureTo3dxml(const QImage& image, const QString
 	}
 }
 
-QString GLC_WorldTo3dxml::xmlFileName(const QString& fileName)
+QString GLC_WorldTo3dxml::xmlFileName(QString fileName)
 {
-	QString newName;
-	if (!m_3dxmlFileSet.contains(fileName))
+	QString prefix;
+	if (fileName.contains("urn:3DXML:"))
 	{
+		prefix= "urn:3DXML:";
+		fileName.remove(prefix);
+	}
+
+	fileName= symplifyName(fileName);
+
+
+
+	QString newName;
+	if (!m_3dxmlFileSet.contains(prefix + fileName))
+	{
+		fileName.prepend(prefix);
 		m_3dxmlFileSet << fileName;
 		newName= fileName;
 	}
 	else
 	{
 		newName= QFileInfo(fileName).completeBaseName() + QString::number(++m_FileNameIncrement) + '.' + QFileInfo(fileName).suffix();
+		newName.prepend(prefix);
 	}
 	return newName;
 }
@@ -1142,40 +1155,87 @@ void GLC_WorldTo3dxml::writeExtensionAttributes(GLC_Attributes* pAttributes)
 
 void GLC_WorldTo3dxml::writeOccurenceDefaultViewProperty(const GLC_StructOccurence* pOccurence)
 {
+	QList<unsigned int> path= instancePath(pOccurence);
+
 	GLC_3DViewInstance* pInstance= m_World.collection()->instanceHandle(pOccurence->id());
 	Q_ASSERT(NULL != pInstance);
 	const bool isVisible= pOccurence->isVisible();
-	const unsigned int occurrenceId= pOccurence->occurenceNumber();
 	m_pOutStream->writeStartElement("DefaultViewProperty");
-	m_pOutStream->writeTextElement("OccurenceId", QString::number(occurrenceId));
-	m_pOutStream->writeStartElement("GraphicProperties");
-	m_pOutStream->writeAttribute("xsi:type", "GraphicPropertiesType");
-	if (! isVisible)
+	m_pOutStream->writeStartElement("OccurenceId");
+	const QString prefix= "urn:3DXML:" + QFileInfo(m_FileName).fileName() + "#";
+	const int pathSize= path.size();
+	for (int i= 0; i < pathSize; ++i)
 	{
-		m_pOutStream->writeStartElement("GeneralAttributes");
-			m_pOutStream->writeAttribute("xsi:type", "GeneralAttributesType");
-			m_pOutStream->writeAttribute("visible", "false");
-			m_pOutStream->writeAttribute("selectable", "true");
-		m_pOutStream->writeEndElement(); // GeneralAttributes
+		m_pOutStream->writeTextElement("id", prefix + QString::number(path.at(i)));
 	}
-	if (!pInstance->renderPropertiesHandle()->isDefault())
+	m_pOutStream->writeEndElement(); // OccurenceId
+
+	if (pOccurence->isFlexible())
 	{
-		const GLC_RenderProperties* pProperties= pInstance->renderPropertiesHandle();
-		if (pProperties->overwriteTransparency() != -1.0f)
+		m_pOutStream->writeTextElement("RelativePosition", matrixString(pOccurence->occurrenceRelativeMatrix()));
+	}
+
+	if (!isVisible || !pInstance->renderPropertiesHandle()->isDefault())
+	{
+		qDebug() << "(!isVisible || !pInstance->renderPropertiesHandle()->isDefault())";
+		m_pOutStream->writeStartElement("GraphicProperties");
+		m_pOutStream->writeAttribute("xsi:type", "GraphicPropertiesType");
+		if (! isVisible)
 		{
-			m_pOutStream->writeStartElement("SurfaceAttributes");
-			m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType");
-				m_pOutStream->writeStartElement("Color");
-					m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
-					m_pOutStream->writeAttribute("red", "-1");
-					m_pOutStream->writeAttribute("green", "-1");
-					m_pOutStream->writeAttribute("blue", "-1");
-					m_pOutStream->writeAttribute("alpha", QString::number(pProperties->overwriteTransparency()));
-				m_pOutStream->writeEndElement(); // Color
-			m_pOutStream->writeEndElement(); // SurfaceAttributes
+			m_pOutStream->writeStartElement("GeneralAttributes");
+				m_pOutStream->writeAttribute("xsi:type", "GeneralAttributesType");
+				m_pOutStream->writeAttribute("visible", "false");
+				m_pOutStream->writeAttribute("selectable", "true");
+			m_pOutStream->writeEndElement(); // GeneralAttributes
 		}
+		if (!pInstance->renderPropertiesHandle()->isDefault())
+		{
+			const GLC_RenderProperties* pProperties= pInstance->renderPropertiesHandle();
+			if ((pProperties->renderingMode() == glc::OverwriteTransparency))
+			{
+				m_pOutStream->writeStartElement("SurfaceAttributes");
+				m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType");
+					m_pOutStream->writeStartElement("Color");
+						m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
+						m_pOutStream->writeAttribute("red", "-1");
+						m_pOutStream->writeAttribute("green", "-1");
+						m_pOutStream->writeAttribute("blue", "-1");
+						m_pOutStream->writeAttribute("alpha", QString::number(pProperties->overwriteTransparency()));
+					m_pOutStream->writeEndElement(); // Color
+				m_pOutStream->writeEndElement(); // SurfaceAttributes
+			}
+			else if ((pProperties->renderingMode() == glc::OverwriteTransparencyAndMaterial))
+			{
+				GLC_Material* pMaterial= pProperties->overwriteMaterial();
+				m_pOutStream->writeStartElement("SurfaceAttributes");
+				m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType");
+					m_pOutStream->writeStartElement("Color");
+						m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
+						m_pOutStream->writeAttribute("red", QString::number(pMaterial->diffuseColor().redF()));
+						m_pOutStream->writeAttribute("green", QString::number(pMaterial->diffuseColor().greenF()));
+						m_pOutStream->writeAttribute("blue", QString::number(pMaterial->diffuseColor().blueF()));
+						m_pOutStream->writeAttribute("alpha", QString::number(pProperties->overwriteTransparency()));
+					m_pOutStream->writeEndElement(); // Color
+				m_pOutStream->writeEndElement(); // SurfaceAttributes
+			}
+			else if ((pProperties->renderingMode() == glc::OverwriteMaterial))
+			{
+				GLC_Material* pMaterial= pProperties->overwriteMaterial();
+				m_pOutStream->writeStartElement("SurfaceAttributes");
+				m_pOutStream->writeAttribute("xsi:type", "SurfaceAttributesType");
+					m_pOutStream->writeStartElement("Color");
+						m_pOutStream->writeAttribute("xsi:type", "RGBAColorType");
+						m_pOutStream->writeAttribute("red", QString::number(pMaterial->diffuseColor().redF()));
+						m_pOutStream->writeAttribute("green", QString::number(pMaterial->diffuseColor().greenF()));
+						m_pOutStream->writeAttribute("blue", QString::number(pMaterial->diffuseColor().blueF()));
+						m_pOutStream->writeAttribute("alpha", QString::number(pMaterial->opacity()));
+					m_pOutStream->writeEndElement(); // Color
+				m_pOutStream->writeEndElement(); // SurfaceAttributes
+			}
+
+		}
+		m_pOutStream->writeEndElement(); // GraphicProperties
 	}
-	m_pOutStream->writeEndElement(); // GraphicProperties
 	m_pOutStream->writeEndElement(); // DefaultViewProperty
 }
 
@@ -1191,3 +1251,32 @@ bool GLC_WorldTo3dxml::continu()
 	}
 	return continuValue;
 }
+
+QString GLC_WorldTo3dxml::symplifyName(QString name)
+{
+	const int nameSize= name.size();
+	for (int i= 0; i < nameSize; ++i)
+	{
+		if (!name.at(i).isLetterOrNumber() && (name.at(i) != '.'))
+		{
+			name.replace(i, 1, '_');
+		}
+	}
+
+	return name;
+}
+
+QList<unsigned int> GLC_WorldTo3dxml::instancePath(const GLC_StructOccurence* pOccurence)
+{
+	QList<unsigned int> path;
+	if (!pOccurence->isOrphan())
+	{
+		GLC_StructInstance* pInstance= pOccurence->structInstance();
+		Q_ASSERT(m_InstanceToIdHash.contains(pInstance));
+		path.prepend(m_InstanceToIdHash.value(pInstance));
+		QList<unsigned int> subPath(instancePath(pOccurence->parent()));
+		subPath.append(path);
+		path= subPath;
+	}
+	return path;
+}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_worldto3dxml.h b/ground/openpilotgcs/src/libs/glc_lib/io/glc_worldto3dxml.h
index d9721f556..c9344e2a9 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/io/glc_worldto3dxml.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/io/glc_worldto3dxml.h
@@ -166,7 +166,7 @@ private:
 	void addImageTextureTo3dxml(const QImage& image, const QString& fileName);
 
 	//! Transform the given name to the 3DXML name (no double)
-	QString xmlFileName(const QString& fileName);
+	QString xmlFileName(QString fileName);
 
 	//! Write extension attributes to 3DXML
 	void writeExtensionAttributes(GLC_Attributes* pAttributes);
@@ -177,6 +177,12 @@ private:
 	//! return true if export must continu
 	bool continu();
 
+	//! Return the simplified name of the given name
+	QString symplifyName(QString name);
+
+	//! Return the path of the given occurence
+	QList<unsigned int> instancePath(const GLC_StructOccurence* pOccurence);
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
diff --git a/ground/openpilotgcs/src/libs/glc_lib/io/glc_xmlutil.h b/ground/openpilotgcs/src/libs/glc_lib/io/glc_xmlutil.h
old mode 100644
new mode 100755
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_geomtools.cpp b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_geomtools.cpp
index 8d88aa754..a9b2ace04 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_geomtools.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_geomtools.cpp
@@ -27,6 +27,9 @@
 
 #include <QtGlobal>
 
+
+double glc::comparedPrecision= glc::defaultPrecision;
+
 //////////////////////////////////////////////////////////////////////
 //Tools Functions
 //////////////////////////////////////////////////////////////////////
@@ -520,12 +523,112 @@ bool glc::lineIntersectPlane(const GLC_Line3d& line, const GLC_Plane& plane, GLC
 
 GLC_Point3d glc::project(const GLC_Point3d& point, const GLC_Line3d& line)
 {
-	// Create the plane from the point with normal define by the line direction
-	const GLC_Plane plane(line.direction().normalize(), point);
-	GLC_Point3d intersection;
-	const bool intersect= lineIntersectPlane(line, plane, &intersection);
-	Q_ASSERT(intersect == true);
-	return intersection;
+	const GLC_Vector3d lineDirection(line.direction().normalize());
+	double t= lineDirection * (point - line.startingPoint());
+	GLC_Point3d projectedPoint= line.startingPoint() + (t * lineDirection);
+	return projectedPoint;
 }
 
+double glc::pointLineDistance(const GLC_Point3d& point, const GLC_Line3d& line)
+{
+	const GLC_Vector3d lineDirection(line.direction().normalize());
+	double t= lineDirection * (point - line.startingPoint());
+	GLC_Point3d projectedPoint= line.startingPoint() + (t * lineDirection);
+	return (point - projectedPoint).length();
+}
 
+bool glc::pointsAreCollinear(const GLC_Point3d& p1, const GLC_Point3d& p2, const GLC_Point3d& p3)
+{
+	bool subject= false;
+	if (compare(p1, p2) || compare(p1, p3) || compare(p2, p3))
+	{
+		subject= true;
+	}
+	else
+	{
+		GLC_Vector3d p1p2= (p2 - p1).setLength(1.0);
+		GLC_Vector3d p2p3= (p3 - p2).setLength(1.0);
+		subject= (compare(p1p2, p2p3)  || compare(p1p2, p2p3.inverted()));
+	}
+	return subject;
+}
+
+bool glc::compare(double p1, double p2)
+{
+	return qAbs(p1 - p2) <= comparedPrecision;
+}
+
+bool glc::compareAngle(double p1, double p2)
+{
+	const double anglePrecision= toRadian(comparedPrecision);
+	return qAbs(p1 - p2) <= anglePrecision;
+}
+
+bool glc::compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2)
+{
+	bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision);
+	compareResult= compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision);
+	compareResult= compareResult && (qAbs(v1.z() - v2.z()) <= comparedPrecision);
+
+	return compareResult;
+}
+
+bool glc::compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2)
+{
+	bool compareResult= (qAbs(v1.getX() - v2.getX()) <= comparedPrecision);
+	return compareResult && (qAbs(v1.getY() - v2.getY()) <= comparedPrecision);
+}
+
+bool glc::compare(const QPointF& v1, const QPointF& v2)
+{
+	bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision);
+	return compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision);
+}
+
+bool glc::pointInPolygon(const GLC_Point2d& point, const QList<GLC_Point2d>& polygon)
+{
+	const int polygonSize= polygon.size();
+	bool inside= false;
+	int i= 0;
+	int j= polygonSize - 1;
+
+	while (i < polygonSize)
+	{
+		const GLC_Point2d point0= polygon.at(i);
+		const GLC_Point2d point1= polygon.at(j);
+		if (point.getY() < point1.getY())
+		{
+			//point1 above ray
+			if (point0.getY() <= point.getY())
+			{
+				//point2 on or below ray
+				const double val1= (point.getY() - point0.getY()) * (point1.getX() - point0.getX());
+				const double val2= (point.getX() - point0.getX()) * (point1.getY() - point0.getY());
+				if (val1 > val2) inside= !inside;
+			}
+		}
+		else if (point.getY() < point0.getY())
+		{
+			// point 1 on or below ray, point0 above ray
+			const double val1= (point.getY() - point0.getY()) * (point1.getX() - point0.getX());
+			const double val2= (point.getX() - point0.getX()) * (point1.getY() - point0.getY());
+			if (val1 < val2) inside= !inside;
+		}
+		j= i;
+		++i;
+	}
+	return inside;
+}
+
+double glc::zeroTo2PIAngle(double angle)
+{
+	if (qFuzzyCompare(fabs(angle), glc::PI))
+	{
+		angle= glc::PI;
+	}
+	else if (angle < 0)
+	{
+		angle= (2.0 * glc::PI) + angle;
+	}
+	return angle;
+}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_geomtools.h b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_geomtools.h
index 94f66ed66..0f8628ab9 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_geomtools.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_geomtools.h
@@ -27,6 +27,8 @@
 
 #include <QVector>
 #include <QList>
+#include <QPointF>
+
 #include "glc_vector3d.h"
 #include "glc_line3d.h"
 #include "glc_plane.h"
@@ -37,7 +39,8 @@
 
 namespace glc
 {
-
+	const double defaultPrecision= 0.01;
+	extern double comparedPrecision;
 //////////////////////////////////////////////////////////////////////
 /*! \name Tools Functions*/
 //@{
@@ -94,10 +97,33 @@ namespace glc
 
 	//! Return the midpoint of the two given points
 	inline GLC_Point3d midPoint(const GLC_Point3d& point1, const GLC_Point3d point2)
-	{
-		return point1 + (point2 - point1) * 0.5;
-	}
+	{return point1 + (point2 - point1) * 0.5;}
 
+	//! Return the perpendicular 2D vector of the given 2D vector
+	inline GLC_Vector2d perpVector(const GLC_Vector2d& vect)
+	{return GLC_Vector2d(-vect.getY(), vect.getX());}
+
+	//! Return the distance between the given point and line
+	GLC_LIB_EXPORT double pointLineDistance(const GLC_Point3d& point, const GLC_Line3d& line);
+
+	//! Return true if the given 3 points are collinear
+	GLC_LIB_EXPORT bool pointsAreCollinear(const GLC_Point3d& p1, const GLC_Point3d& p2, const GLC_Point3d& p3);
+
+	GLC_LIB_EXPORT bool compare(double p1, double p2);
+
+	GLC_LIB_EXPORT bool compareAngle(double p1, double p2);
+
+	GLC_LIB_EXPORT bool compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2);
+
+	GLC_LIB_EXPORT bool compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2);
+
+	GLC_LIB_EXPORT bool compare(const QPointF& v1, const QPointF& v2);
+
+	//! Return true if the given 2d point is inside the given polygon
+	GLC_LIB_EXPORT bool pointInPolygon(const GLC_Point2d& point, const QList<GLC_Point2d>& polygon);
+
+	//! Return the angle from 0 to 2PI from an given angle from -PI to PI
+	GLC_LIB_EXPORT double zeroTo2PIAngle(double angle);
 
 //@}
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_interpolator.cpp b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_interpolator.cpp
index 04912e448..e42d170a8 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_interpolator.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_interpolator.cpp
@@ -25,121 +25,99 @@
 #include "glc_interpolator.h"
 
 using namespace glc;
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
 
-// Contructeur par d�faut Interpolation Lin�aire
 GLC_Interpolator::GLC_Interpolator()
 : m_InterpolType(INTERPOL_LINEAIRE)
-, m_nNbrPas(1)
+, m_StepCount(1)
 {
 
 }
 
 //////////////////////////////////////////////////////////////////////
-// Fonction Set
+// Set Function
 //////////////////////////////////////////////////////////////////////
-// D�fini la matrice d'interpolation
 void GLC_Interpolator::SetInterpolMat(int NbrPas, const GLC_Vector3d &VectDepart, const GLC_Vector3d &VectArrive
 								   , INTERPOL_TYPE Interpolation)
 {
-	// Mise � jour des donn�es membre
 	m_InterpolType= Interpolation;
-	if (!NbrPas)
-	{
-		//TRACE("GLC_Interpolator::SetInterpolMat -> NbrPas == 0 \n");
-	}
-	else m_nNbrPas= NbrPas;
+	if (NbrPas != 0)
+	m_StepCount= NbrPas;
+
+	m_StartPoint= VectDepart;
+	m_EndPoint= VectArrive;
 
-	m_VectDepart= VectDepart;
-	m_VectArrive= VectArrive;
-	// Calcul de la matrice d'interpolation
 	CalcInterpolMat();
 }
-// Type d'interpolation
+
 void GLC_Interpolator::SetType(INTERPOL_TYPE Interpolation)
 {
 	if (m_InterpolType != Interpolation)
 	{
 		m_InterpolType= Interpolation;
-		// Calcul de la matrice d'interpolation
+
 		CalcInterpolMat();
 	}
 }
-// Nombre de pas
+
 void GLC_Interpolator::SetNbrPas(int NbrPas)
 {
-	if (!NbrPas)
-	{
-		//TRACE("GLC_Interpolator::SetNbrPas -> NbrPas == 0 \n");
-		return;
-	}
 
-	if (m_nNbrPas != NbrPas)
+	if ((NbrPas != 0) && (m_StepCount != NbrPas))
 	{
-		m_nNbrPas= NbrPas;
-		// Calcul de la matrice d'interpolation
+		m_StepCount= NbrPas;
+
 		CalcInterpolMat();
 	}
 }
-// Vecteur d'arriv�e et de depart
+
 void GLC_Interpolator::SetVecteurs(const GLC_Vector3d &VectDepart, const GLC_Vector3d &VectArrive)
 {
-	m_VectDepart= VectDepart;
-	m_VectArrive= VectArrive;
+	m_StartPoint= VectDepart;
+	m_EndPoint= VectArrive;
+
 
-	// Calcul de la matrice d'interpolation
 	CalcInterpolMat();
 
 }
 
 //////////////////////////////////////////////////////////////////////
-// Fonction Get
+// Private sevices functions
 //////////////////////////////////////////////////////////////////////
 
-//////////////////////////////////////////////////////////////////////
-// Fonctions de Service priv�e
-//////////////////////////////////////////////////////////////////////
-// Calcul La matrice d'interpolation
 bool GLC_Interpolator::CalcInterpolMat(void)
 {
-	// Verifie que les vecteur d'arriv� et de d�part sont diff�rent
-	if (m_VectDepart == m_VectArrive)
+
+	if (m_StartPoint != m_EndPoint)
 	{
-		//TRACE("GLC_Interpolator::CalcInterpolMat : Depart == Arrive\n");
-		return false;
+		switch (m_InterpolType)
+		{
+		case INTERPOL_LINEAIRE:
+			return CalcInterpolLineaireMat();
+			break;
+
+		case INTERPOL_ANGULAIRE:
+			return CalcInterpolAngulaireMat();
+			break;
+
+		case INTERPOL_HOMOTETIE:
+			return false;
+			break;
+
+		default:
+			return false;
+		}
 	}
+	else return false;
 
-	switch (m_InterpolType)
-	{
-	case INTERPOL_LINEAIRE:
-		return CalcInterpolLineaireMat();
-		break;
-
-	case INTERPOL_ANGULAIRE:
-		return CalcInterpolAngulaireMat();
-		break;
-
-	case INTERPOL_HOMOTETIE:
-		return false;
-		break;
-
-	default:
-		//TRACE("GLC_Interpolator::CalcInterpolMat : Type d'interpolation non valide\n");
-		return false;
-	}
 }
 
-// Calcul la matrice d'interpolation lin�aire
+
 bool GLC_Interpolator::CalcInterpolLineaireMat(void)
 {
 
-	// Calcul la matrice de translation
-	const GLC_Vector3d VectTrans= (m_VectArrive - m_VectDepart) * (1.0 / m_nNbrPas);
+	const GLC_Vector3d VectTrans= (m_EndPoint - m_StartPoint) * (1.0 / m_StepCount);
 	if(VectTrans.isNull())
 	{
-		//TRACE("GLC_Interpolator::CalcInterpolLineaireMat -> Translation NULL\n");
 		m_InterpolMat.setToIdentity();
 		return false;
 	}
@@ -150,17 +128,15 @@ bool GLC_Interpolator::CalcInterpolLineaireMat(void)
 	}
 }
 
-// Calcul la matrice d'interpolation angulaire
 bool GLC_Interpolator::CalcInterpolAngulaireMat(void)
 {
-	// Calcul de l'axe de rotation
-	const GLC_Vector3d AxeRot(m_VectDepart ^ m_VectArrive);
-	// Calcul de l'angle entre les vecteurs
-	const double Angle= m_VectArrive.angleWithVect(m_VectDepart) / m_nNbrPas;
-	// Calcul de la matrice de rotation
+
+	const GLC_Vector3d AxeRot(m_StartPoint ^ m_EndPoint);
+
+	const double Angle= m_EndPoint.angleWithVect(m_StartPoint) / m_StepCount;
+
 	if (qFuzzyCompare(Angle, 0.0))
 	{
-		//TRACE("GLC_Interpolator::CalcInterpolAngulaireMat -> Rotation NULL\n");
 		m_InterpolMat.setToIdentity();
 		return false;
 	}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_interpolator.h b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_interpolator.h
index f0cec314f..83db355cf 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_interpolator.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_interpolator.h
@@ -47,66 +47,65 @@ enum INTERPOL_TYPE
 class GLC_LIB_EXPORT GLC_Interpolator
 {
 
-//////////////////////////////////////////////////////////////////////
-// Construction
-//////////////////////////////////////////////////////////////////////
 public:
-	// Contructeur par d�faut Interpolation Lin�aire
+	//! Default linear interpolation constructor
 	GLC_Interpolator();
 
 //////////////////////////////////////////////////////////////////////
-// Fonctions Set
+// Set Function
 //////////////////////////////////////////////////////////////////////
 public:
-	// D�fini la matrice d'interpolation
+	//! Set interpolation matrix
 	void SetInterpolMat(int NbrPas, const GLC_Vector3d &VectDepart, const GLC_Vector3d &VectArrive
 		, INTERPOL_TYPE Interpolation = INTERPOL_LINEAIRE);
-	// Type d'interpolation
+
+	//! Set interpolation type
 	void SetType(INTERPOL_TYPE Interpolation);
-	// Nombre de pas
+
+	// Number of step
 	void SetNbrPas(int NbrPas);
-	// Vecteur d'arriv�e et de depart
+
+	//! Set start and end vector
 	void SetVecteurs(const GLC_Vector3d &VectDepart, const GLC_Vector3d &VectArrive);
 
 //////////////////////////////////////////////////////////////////////
-// Fonctions Get
+// Get Function
 //////////////////////////////////////////////////////////////////////
 public:
-	// Retourne la matrice d'interpolation
-	GLC_Matrix4x4 GetInterpolMat(void) const
-	{
-		return m_InterpolMat;
-	}
+	//! Return th interpolation matrix
+	inline GLC_Matrix4x4 GetInterpolMat(void) const
+	{return m_InterpolMat;}
 
 //////////////////////////////////////////////////////////////////////
-// Fonctions de Service priv�e
+// Private services functions
 //////////////////////////////////////////////////////////////////////
 private:
-	// Calcul La matrice d'interpolation
+	//! Compute interpolation matrix
 	bool CalcInterpolMat(void);
 
-	// Calcul la matrice d'interpolation lin�aire
+	//! Compute linear interolation matrix
 	bool CalcInterpolLineaireMat(void);
 
-	// Calcul la matrice d'interpolation angulaire
+	//! Compute angular interpolation matrix
 	bool CalcInterpolAngulaireMat(void);
 
 //////////////////////////////////////////////////////////////////////
 // Membres priv�s
 //////////////////////////////////////////////////////////////////////
 private:
-	// Vecteur de d�part
-	GLC_Vector3d m_VectDepart;
-	// Vecteur d'arriver
-	GLC_Vector3d m_VectArrive;
+	//! Start Point
+	GLC_Point3d m_StartPoint;
 
-	// Type d'interpolation courante
+	//! End Point
+	GLC_Point3d m_EndPoint;
+
+	//! Interpolation type
 	INTERPOL_TYPE m_InterpolType;
 
-	// Nombre de pas d'interpolation
-	int m_nNbrPas;
+	//! Interpolation step count
+	int m_StepCount;
 
-	// Matrice d'interpolation
+	//! Interpolation matrix
 	GLC_Matrix4x4 m_InterpolMat;
 };
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_line3d.h b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_line3d.h
index 835c1debd..85a0e123a 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_line3d.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_line3d.h
@@ -26,7 +26,7 @@
 
 #include "glc_vector3d.h"
 
-#include "glc_config.h"
+#include "../glc_config.h"
 
 //////////////////////////////////////////////////////////////////////
 //! \class GLC_Line3d
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_matrix4x4.h b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_matrix4x4.h
index 8faa2d2b9..651657166 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_matrix4x4.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_matrix4x4.h
@@ -278,17 +278,6 @@ the matrix :
 
 };
 
-//! Return the determinant of the given Matrix 3X3
-inline double getDeterminant3x3(const double *Mat3x3)
-{
-	double Determinant;
-
-	Determinant= Mat3x3[0] * ( Mat3x3[4] * Mat3x3[8] - Mat3x3[7] * Mat3x3[5]);
-	Determinant+= - Mat3x3[3] * ( Mat3x3[1] * Mat3x3[8] - Mat3x3[7] * Mat3x3[2]);
-	Determinant+= Mat3x3[6] * ( Mat3x3[1] * Mat3x3[5] - Mat3x3[4] * Mat3x3[2]);
-
-	return Determinant;
-}
 
 //////////////////////////////////////////////////////////////////////
 // Constructor/Destructor
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector2d.h b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector2d.h
old mode 100644
new mode 100755
index 0840db1e0..a85baf6e7
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector2d.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector2d.h
@@ -26,10 +26,12 @@
 #define GLC_VECTOR2D_H_
 
 #include <QString>
+#include <QPointF>
+
 #include "glc_utils_maths.h"
 #include "glc_vector2df.h"
 
-#include "glc_config.h"
+#include "../glc_config.h"
 
 //////////////////////////////////////////////////////////////////////
 // definition global
@@ -51,7 +53,7 @@ class GLC_LIB_EXPORT GLC_Vector2d
 	/*! Overload unary "-" operator*/
 	inline friend GLC_Vector2d operator - (const GLC_Vector2d &Vect)
 	{
-		return GLC_Vector2d(-Vect.dVecteur[0], -Vect.dVecteur[1]);
+		return GLC_Vector2d(-Vect.m_Vector[0], -Vect.m_Vector[1]);
 	}
 
 
@@ -67,15 +69,15 @@ public:
 	*/
 	inline GLC_Vector2d()
 	{
-		dVecteur[0]= 0.0;
-		dVecteur[1]= 0.0;
+		m_Vector[0]= 0.0;
+		m_Vector[1]= 0.0;
 	}
 
 	/*! Standard constructor With x, y = 0.0*/
 	inline GLC_Vector2d(const double &dX, const double &dY)
 	{
-		dVecteur[0]= dX;
-		dVecteur[1]= dY;
+		m_Vector[0]= dX;
+		m_Vector[1]= dY;
 	}
 
 	/*! Recopy constructor
@@ -86,9 +88,14 @@ public:
 	 */
 	inline GLC_Vector2d(const GLC_Vector2d &Vect)
 	{
-		dVecteur[0]= Vect.dVecteur[0];
-		dVecteur[1]= Vect.dVecteur[1];
+		m_Vector[0]= Vect.m_Vector[0];
+		m_Vector[1]= Vect.m_Vector[1];
 	}
+
+	//! Return the QPointF of this GLC_Vector
+	inline QPointF toQPointF() const
+	{return QPointF(m_Vector[0], m_Vector[1]);}
+
 //@}
 //////////////////////////////////////////////////////////////////////
 /*! @name Operator Overload */
@@ -99,7 +106,7 @@ public:
 	/*! Overload binary "+" operator*/
 	inline GLC_Vector2d operator + (const GLC_Vector2d &Vect) const
 	{
-		GLC_Vector2d VectResult(dVecteur[0] + Vect.dVecteur[0], dVecteur[1] + Vect.dVecteur[1]);
+		GLC_Vector2d VectResult(m_Vector[0] + Vect.m_Vector[0], m_Vector[1] + Vect.m_Vector[1]);
 
 		return VectResult;
 	}
@@ -107,8 +114,8 @@ public:
 	/*! Overload "=" operator*/
 	inline GLC_Vector2d& operator = (const GLC_Vector2d &Vect)
 	{
-		dVecteur[0]= Vect.dVecteur[0];
-		dVecteur[1]= Vect.dVecteur[1];
+		m_Vector[0]= Vect.m_Vector[0];
+		m_Vector[1]= Vect.m_Vector[1];
 
 		return *this;
 	}
@@ -116,8 +123,8 @@ public:
 	/*! Overload "=" operator*/
 	inline GLC_Vector2d& operator = (const GLC_Vector2df &Vect)
 	{
-		dVecteur[0]= static_cast<double>(Vect.vector[0]);
-		dVecteur[1]= static_cast<double>(Vect.vector[1]);
+		m_Vector[0]= static_cast<double>(Vect.vector[0]);
+		m_Vector[1]= static_cast<double>(Vect.vector[1]);
 
 		return *this;
 	}
@@ -134,7 +141,7 @@ public:
 	/*! Overload binary "-" operator*/
 	inline GLC_Vector2d operator - (const GLC_Vector2d &Vect) const
 	{
-		GLC_Vector2d VectResult(dVecteur[0] - Vect.dVecteur[0], dVecteur[1] - Vect.dVecteur[1]);
+		GLC_Vector2d VectResult(m_Vector[0] - Vect.m_Vector[0], m_Vector[1] - Vect.m_Vector[1]);
 
 		return VectResult;
 	}
@@ -149,27 +156,27 @@ public:
 	/*! Overload dot product "^" operator*/
 	inline double operator ^ (const GLC_Vector2d &Vect) const
 	{
-		return dVecteur[0] * Vect.dVecteur[1] - dVecteur[1] * Vect.dVecteur[0];
+		return m_Vector[0] * Vect.m_Vector[1] - m_Vector[1] * Vect.m_Vector[0];
 	}
 
 	/*! Overload scalar product "*" operator between 2 vector*/
 	inline double operator * (const GLC_Vector2d &Vect) const
 	{
-		return dVecteur[0] * Vect.dVecteur[0] + dVecteur[1] * Vect.dVecteur[1];
+		return m_Vector[0] * Vect.m_Vector[0] + m_Vector[1] * Vect.m_Vector[1];
 	}
 
 	/*! Overload scalar product "*" operator between 1 vector and one scalar*/
 	inline GLC_Vector2d operator * (double Scalaire) const
 	{
-		return GLC_Vector2d(dVecteur[0] * Scalaire, dVecteur[1] * Scalaire);;
+		return GLC_Vector2d(m_Vector[0] * Scalaire, m_Vector[1] * Scalaire);;
 	}
 
 
 	/*! Overload equality "==" operator*/
 	inline bool operator == (const GLC_Vector2d &Vect) const
 	{
-		bool bResult= qFuzzyCompare(dVecteur[0], Vect.dVecteur[0]);
-		bResult= bResult && qFuzzyCompare(dVecteur[1], Vect.dVecteur[1]);
+		bool bResult= qFuzzyCompare(m_Vector[0], Vect.m_Vector[0]);
+		bResult= bResult && qFuzzyCompare(m_Vector[1], Vect.m_Vector[1]);
 
 		return bResult;
 	}
@@ -190,33 +197,40 @@ public:
 	/*! X Composante*/
 	inline GLC_Vector2d& setX(const double &dX)
 	{
-		dVecteur[0]= dX;
+		m_Vector[0]= dX;
 		return *this;
 	}
 
 	/*! Y Composante*/
 	inline GLC_Vector2d& setY(const double &dY)
 	{
-		dVecteur[1]= dY;
+		m_Vector[1]= dY;
 		return *this;
 	}
 
 	/*! All Composante*/
 	inline GLC_Vector2d& setVect(const double &dX, const double &dY)
 	{
-		dVecteur[0]= dX;
-		dVecteur[1]= dY;
+		m_Vector[0]= dX;
+		m_Vector[1]= dY;
 		return *this;
 	}
 
 	/*! From another Vector*/
 	inline GLC_Vector2d& setVect(const GLC_Vector2d &Vect)
 	{
-		dVecteur[0]= Vect.dVecteur[0];
-		dVecteur[1]= Vect.dVecteur[1];
+		m_Vector[0]= Vect.m_Vector[0];
+		m_Vector[1]= Vect.m_Vector[1];
 		return *this;
 	}
 
+	//! Set vector lenght from the given scalar and return a reference of this vector
+	inline GLC_Vector2d& setLength(double);
+
+	//! Normalize this vector and return a reference to it
+	inline GLC_Vector2d& normalize()
+	{return setLength(1.0);}
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -227,32 +241,32 @@ public:
 	/*! X Composante*/
 	inline double getX(void) const
 	{
-		return dVecteur[0];
+		return m_Vector[0];
 	}
 	/*! Y Composante*/
 	inline double getY(void) const
 	{
-		return dVecteur[1];
+		return m_Vector[1];
 	}
 	/*! retourne un pointeur constant vers le tableau du vecteur.*/
 	inline const double *return_dVect(void) const
 	{
-		return dVecteur;
+		return m_Vector;
 	}
 	/*! Return true if the vector is null*/
 	inline bool isNull(void) const
 	{
-		return qFuzzyCompare(dVecteur[0], 0.0) && qFuzzyCompare(dVecteur[1], 0.0);
+		return qFuzzyCompare(m_Vector[0], 0.0) && qFuzzyCompare(m_Vector[1], 0.0);
 	}
 	//! return the string representation of vector
 	inline QString toString() const
 	{
-		return QString("[") + QString::number(dVecteur[0]) + QString(" , ") + QString::number(dVecteur[1]) + QString("]");
+		return QString("[") + QString::number(m_Vector[0]) + QString(" , ") + QString::number(m_Vector[1]) + QString("]");
 	}
 	//! return a vector perpendicular to this
 	inline GLC_Vector2d perp() const
 	{
-		return GLC_Vector2d(-dVecteur[1], dVecteur[0]);
+		return GLC_Vector2d(-m_Vector[1], m_Vector[0]);
 	}
 //@}
 
@@ -264,11 +278,25 @@ private:
 	*	vector[0]	X \n
 	*	vector[1]	Y \n
 	*/
-	double dVecteur[2];
+	double m_Vector[2];
 
 }; //class GLC_Vector2d
 
 //! Define GLC_Point2D
 typedef GLC_Vector2d GLC_Point2d;
 
+inline GLC_Vector2d& GLC_Vector2d::setLength(double norme)
+{
+	const double normCur= sqrt( m_Vector[0] * m_Vector[0] + m_Vector[1] * m_Vector[1]);
+
+	if (normCur != 0.0f)
+	{
+		const double Coef = norme / normCur;
+
+		m_Vector[0] = m_Vector[0] * Coef;
+		m_Vector[1] = m_Vector[1] * Coef;
+	}
+	return *this;
+}
+
 #endif /*GLC_VECTOR2D_H_*/
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector3d.h b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector3d.h
old mode 100644
new mode 100755
index 5c53b4159..c43db6c71
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector3d.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector3d.h
@@ -76,6 +76,9 @@ public:
 	//! Construct a 3d vector from another 3d float vector
 	inline GLC_Vector3d(const GLC_Vector3df &vector);
 
+	//! Construct a 3d vector from a 2d float vector
+	inline GLC_Vector3d(const GLC_Vector2d &vector);
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -111,9 +114,12 @@ public:
 	/*! retrieve component corresponding to mask vector NULL component*/
 	inline GLC_Vector2d toVector2d(const GLC_Vector3d& mask) const;
 
-	//! Return the Angle from this vector to the given vector
+	//! Return the Angle from this vector to the given vector (from 0 to PI)
 	inline double angleWithVect(GLC_Vector3d Vect) const;
 
+	//! Return the signed angle from this vector to th given vector with the given direction (from 0 to -PI and 0 to PI)
+	inline double signedAngleWithVect(GLC_Vector3d Vect, const GLC_Vector3d& dir) const;
+
 	//! Return the float 3D vector from this vector
 	inline GLC_Vector3df toVector3df() const
 	{return GLC_Vector3df(static_cast<float>(m_Vector[0]), static_cast<float>(m_Vector[1]), static_cast<float>(m_Vector[2]));}
@@ -289,6 +295,18 @@ inline QDataStream &operator>>(QDataStream &stream, GLC_Vector3d &vector)
 	return stream;
 }
 
+//! Return the determinant of the given Matrix 3X3
+inline double getDeterminant3x3(const double *Mat3x3)
+{
+	double Determinant;
+
+	Determinant= Mat3x3[0] * ( Mat3x3[4] * Mat3x3[8] - Mat3x3[7] * Mat3x3[5]);
+	Determinant+= - Mat3x3[3] * ( Mat3x3[1] * Mat3x3[8] - Mat3x3[7] * Mat3x3[2]);
+	Determinant+= Mat3x3[6] * ( Mat3x3[1] * Mat3x3[5] - Mat3x3[4] * Mat3x3[2]);
+
+	return Determinant;
+}
+
 //////////////////////////////////////////////////////////////////////
 // inline method implementation
 //////////////////////////////////////////////////////////////////////
@@ -314,6 +332,13 @@ GLC_Vector3d::GLC_Vector3d(const GLC_Vector3df &vector)
 	m_Vector[2]= static_cast<double>(vector.m_Vector[2]);
 }
 
+GLC_Vector3d::GLC_Vector3d(const GLC_Vector2d &vector)
+{
+	m_Vector[0]= vector.getX();
+	m_Vector[1]= vector.getY();
+	m_Vector[2]= 0.0;
+}
+
 GLC_Vector3d& GLC_Vector3d::operator = (const GLC_Vector3df &Vect)
 {
 	m_Vector[0]= static_cast<double>(Vect.m_Vector[0]);
@@ -419,6 +444,48 @@ double GLC_Vector3d::angleWithVect(GLC_Vector3d Vect) const
 	else return 0.0;
 }
 
+double GLC_Vector3d::signedAngleWithVect(GLC_Vector3d Vect, const GLC_Vector3d& dir) const
+{
+	double angle= 0.0;
+
+	GLC_Vector3d ThisVect(*this);
+	ThisVect.normalize();
+	Vect.normalize();
+	if (Vect == ThisVect.inverted())
+	{
+		angle= glc::PI;
+	}
+	else if (Vect != ThisVect)
+	{
+		// Rotation axis
+		const GLC_Vector3d VectAxeRot(ThisVect ^ Vect);
+		// Check if the rotation axis vector is null
+		if (!VectAxeRot.isNull())
+		{
+			double mat3x3[9];
+			mat3x3[0]= ThisVect.m_Vector[0];
+			mat3x3[1]= ThisVect.m_Vector[1];
+			mat3x3[2]= ThisVect.m_Vector[2];
+
+			mat3x3[3]= Vect.m_Vector[0];
+			mat3x3[4]= Vect.m_Vector[1];
+			mat3x3[5]= Vect.m_Vector[2];
+
+			mat3x3[6]= dir.m_Vector[0];
+			mat3x3[7]= dir.m_Vector[1];
+			mat3x3[8]= dir.m_Vector[2];
+
+			double det= getDeterminant3x3(mat3x3);
+
+			double sign= 1.0;
+			if (det != 0) sign= fabs(det) / det;
+			angle= acos(ThisVect * Vect) * sign;
+		}
+	}
+
+	return angle;
+}
+
 QString GLC_Vector3d::toString() const
 {
 	QString result("[");
diff --git a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector4d.h b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector4d.h
index 332481416..fee674224 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector4d.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/maths/glc_vector4d.h
@@ -110,8 +110,8 @@ public:
 	//! Copy from an GLC_Vector3d
 	inline GLC_Vector4d(const GLC_Vector2d &Vect)
 	{
-		vector[0]= Vect.dVecteur[0];
-		vector[1]= Vect.dVecteur[1];
+		vector[0]= Vect.m_Vector[0];
+		vector[1]= Vect.m_Vector[1];
 		vector[2]= 0.0;
 		vector[3]= 1.0;
 	}
@@ -168,8 +168,8 @@ public:
 	//! Overload "=" operator
 	inline GLC_Vector4d& operator = (const GLC_Vector2d &Vect)
 	{
-		vector[0]= Vect.dVecteur[0];
-		vector[1]= Vect.dVecteur[1];
+		vector[0]= Vect.m_Vector[0];
+		vector[1]= Vect.m_Vector[1];
 		vector[2]= 0.0;
 		vector[3]= 1.0;
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.cpp b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.cpp
index 5cdab1d51..274f540fa 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.cpp
@@ -40,7 +40,6 @@
 
 GLC_3DViewCollection::GLC_3DViewCollection()
 : m_3DViewInstanceHash()
-, m_pBoundingBox(NULL)
 , m_SelectedInstances()
 , m_ShadedPointerViewInstanceHash()
 , m_ShaderGroup()
@@ -50,6 +49,7 @@ GLC_3DViewCollection::GLC_3DViewCollection()
 , m_pViewport(NULL)
 , m_pSpacePartitioning(NULL)
 , m_UseSpacePartitioning(false)
+, m_IsViewable(true)
 {
 }
 
@@ -62,7 +62,7 @@ GLC_3DViewCollection::~GLC_3DViewCollection()
 // Set Functions
 //////////////////////////////////////////////////////////////////////
 
-bool GLC_3DViewCollection::bindShader(GLuint shaderId)
+bool GLC_3DViewCollection::bindShader(GLC_uint shaderId)
 {
 	if (m_ShadedPointerViewInstanceHash.contains(shaderId))
 	{
@@ -76,7 +76,7 @@ bool GLC_3DViewCollection::bindShader(GLuint shaderId)
 	}
 }
 
-bool GLC_3DViewCollection::unBindShader(GLuint shaderId)
+bool GLC_3DViewCollection::unBindShader(GLC_uint shaderId)
 {
 	bool result= false;
 	if (m_ShadedPointerViewInstanceHash.contains(shaderId))
@@ -127,7 +127,7 @@ bool GLC_3DViewCollection::unBindAllShader()
     return result;
 }
 
-bool GLC_3DViewCollection::add(const GLC_3DViewInstance& node, GLuint shaderID)
+bool GLC_3DViewCollection::add(const GLC_3DViewInstance& node, GLC_uint shaderID)
 {
 	bool result= false;
 	const GLC_uint key= node.id();
@@ -170,19 +170,10 @@ bool GLC_3DViewCollection::add(const GLC_3DViewInstance& node, GLuint shaderID)
 		result=true;
 	}
 
-	if(result)
-	{
-		// Bounding box validity
-		if (NULL != m_pBoundingBox)
-		{
-			delete m_pBoundingBox;
-			m_pBoundingBox= NULL;
-		}
-	}
 	return result;
 }
 
-void GLC_3DViewCollection::changeShadingGroup(GLC_uint instanceId, GLuint shaderId)
+void GLC_3DViewCollection::changeShadingGroup(GLC_uint instanceId, GLC_uint shaderId)
 {
 	// Test if the specified instance exist
 	Q_ASSERT(m_3DViewInstanceHash.contains(instanceId));
@@ -254,13 +245,6 @@ bool GLC_3DViewCollection::remove(GLC_uint Key)
 
 		m_3DViewInstanceHash.remove(Key);		// Delete the conteneur
 
-		// Bounding box validity
-		if (NULL != m_pBoundingBox)
-		{
-			delete m_pBoundingBox;
-			m_pBoundingBox= NULL;
-		}
-
 		//qDebug("GLC_3DViewCollection::removeNode : Element succesfuly deleted");
 		return true;
 
@@ -293,13 +277,6 @@ void GLC_3DViewCollection::clear(void)
 	// Clear main Hash table
     m_3DViewInstanceHash.clear();
 
-	// delete the boundingBox
-	if (m_pBoundingBox != NULL)
-	{
-		delete m_pBoundingBox;
-		m_pBoundingBox= NULL;
-	}
-
 	// delete the space partitioning
 	delete m_pSpacePartitioning;
 }
@@ -438,12 +415,6 @@ void GLC_3DViewCollection::setVisibility(const GLC_uint key, const bool visibili
 	if (iNode != m_3DViewInstanceHash.end())
 	{	// Ok, the key exist
 		iNode.value().setVisibility(visibility);
-		// Bounding box validity
-		if (NULL != m_pBoundingBox)
-		{
-			delete m_pBoundingBox;
-			m_pBoundingBox= NULL;
-		}
 	}
 }
 
@@ -457,14 +428,6 @@ void GLC_3DViewCollection::showAll()
     	iEntry.value().setVisibility(true);
     	iEntry++;
     }
-
-    // Bounding box validity
-	if (NULL != m_pBoundingBox)
-	{
-		delete m_pBoundingBox;
-		m_pBoundingBox= NULL;
-	}
-
 }
 
 void GLC_3DViewCollection::hideAll()
@@ -478,13 +441,6 @@ void GLC_3DViewCollection::hideAll()
     	iEntry++;
     }
 
-	// Bounding box validity
-	if (NULL != m_pBoundingBox)
-	{
-		delete m_pBoundingBox;
-		m_pBoundingBox= NULL;
-	}
-
 }
 
 void GLC_3DViewCollection::bindSpacePartitioning(GLC_SpacePartitioning* pSpacePartitioning)
@@ -526,6 +482,17 @@ void GLC_3DViewCollection::updateInstanceViewableState(const GLC_Frustum& frustu
 	m_pSpacePartitioning->updateViewableInstances(frustum);
 }
 
+void GLC_3DViewCollection::setVboUsage(bool usage)
+{
+	ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
+
+    while (iEntry != m_3DViewInstanceHash.constEnd())
+    {
+    	iEntry.value().setVboUsage(usage);
+    	iEntry++;
+    }
+}
+
 QList<GLC_3DViewInstance*> GLC_3DViewCollection::instancesHandle()
 {
 	QList<GLC_3DViewInstance*> instancesList;
@@ -583,48 +550,22 @@ GLC_3DViewInstance* GLC_3DViewCollection::instanceHandle(GLC_uint Key)
 
 GLC_BoundingBox GLC_3DViewCollection::boundingBox(bool allObject)
 {
-	// If the bounding box is not valid delete it
-	if (allObject)
-	{
-		delete m_pBoundingBox;
-		m_pBoundingBox= NULL;
-	}
-	else
-	{
-		setBoundingBoxValidity();
-	}
-
+	GLC_BoundingBox boundingBox;
 	// Check if the bounding box have to be updated
-	if ((m_pBoundingBox == NULL) && !m_3DViewInstanceHash.isEmpty())
+	if (!m_3DViewInstanceHash.isEmpty())
 	{
-		// There is objects in the collection and the collection or bounding box is not valid
-		m_pBoundingBox= new GLC_BoundingBox();
-
 		ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
 	    while (iEntry != m_3DViewInstanceHash.constEnd())
 	    {
 	        if(allObject || iEntry.value().isVisible() == m_IsInShowSate)
 	        {
 	        	// Combine Collection BoundingBox with element Bounding Box
-	        	m_pBoundingBox->combine(iEntry.value().boundingBox());
+	        	boundingBox.combine(iEntry.value().boundingBox());
 	        }
 	        ++iEntry;
 	    }
 	}
-
-	if (NULL == m_pBoundingBox) m_pBoundingBox= new GLC_BoundingBox;
-
-	if (allObject)
-	{
-		GLC_BoundingBox allBoundingBox(*m_pBoundingBox);
-		delete m_pBoundingBox;
-		m_pBoundingBox= NULL;
-		return allBoundingBox;
-	}
-	else
-	{
-		return *m_pBoundingBox;
-	}
+	return boundingBox;
 }
 
 int GLC_3DViewCollection::drawableObjectsSize() const
@@ -672,7 +613,7 @@ int GLC_3DViewCollection::numberOfUsedShadingGroup() const
 
 void GLC_3DViewCollection::render(GLuint groupId, glc::RenderFlag renderFlag)
 {
-	if (!isEmpty())
+	if (!isEmpty() && m_IsViewable)
 	{
 		if (renderFlag == glc::WireRenderFlag)
 		{
@@ -682,12 +623,12 @@ void GLC_3DViewCollection::render(GLuint groupId, glc::RenderFlag renderFlag)
 		if (GLC_State::isInSelectionMode())
 		{
 			glDisable(GL_BLEND);
-			glDisable(GL_LIGHTING);
+			GLC_Context::current()->glcEnableLighting(false);
 			glDisable(GL_TEXTURE_2D);
 		}
 		else
 		{
-			glEnable(GL_LIGHTING);
+			GLC_Context::current()->glcEnableLighting(true);
 		}
 		glDraw(groupId, renderFlag);
 
@@ -699,12 +640,12 @@ void GLC_3DViewCollection::render(GLuint groupId, glc::RenderFlag renderFlag)
 }
 void GLC_3DViewCollection::renderShaderGroup(glc::RenderFlag renderFlag)
 {
-	if (!isEmpty())
+	if (!isEmpty() && m_IsViewable)
 	{
 		if (GLC_State::isInSelectionMode())
 		{
 			glDisable(GL_BLEND);
-			glDisable(GL_LIGHTING);
+			GLC_Context::current()->glcEnableLighting(false);
 			glDisable(GL_TEXTURE_2D);
 		}
 
@@ -717,7 +658,7 @@ void GLC_3DViewCollection::renderShaderGroup(glc::RenderFlag renderFlag)
 	}
 }
 
-void GLC_3DViewCollection::glDraw(GLuint groupId, glc::RenderFlag renderFlag)
+void GLC_3DViewCollection::glDraw(GLC_uint groupId, glc::RenderFlag renderFlag)
 {
 	// Set render Mode and OpenGL state
 	if (!GLC_State::isInSelectionMode() && (groupId == 0))
@@ -773,30 +714,3 @@ void GLC_3DViewCollection::glDraw(GLuint groupId, glc::RenderFlag renderFlag)
 		glEnable(GL_DEPTH_TEST);
 	}
 }
-
-void GLC_3DViewCollection::setBoundingBoxValidity(void)
-{
-	if (NULL != m_pBoundingBox)
-	{
-		if (!m_3DViewInstanceHash.isEmpty())
-		{
-			// Check instance bounding box validity
-			ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
-		    while (iEntry != m_3DViewInstanceHash.constEnd())
-		    {
-		    	if (!iEntry.value().boundingBoxValidity())
-		    	{
-					delete m_pBoundingBox;
-					m_pBoundingBox= NULL;
-					return;
-		    	}
-		    	iEntry++;
-		    }
-		}
-		else if (!m_pBoundingBox->isEmpty())
-		{
-			delete m_pBoundingBox;
-			m_pBoundingBox= NULL;
-		}
-	}
-}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.h b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.h
index f4bd55c34..9fc6d4384 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewcollection.h
@@ -45,10 +45,10 @@ typedef QHash< GLC_uint, GLC_3DViewInstance> ViewInstancesHash;
 typedef QHash<GLC_uint, GLC_3DViewInstance*> PointerViewInstanceHash;
 
 //! Hash table of GLC_3DViewInstance Hash table which use a shader
-typedef QHash<GLuint, PointerViewInstanceHash*> HashList;
+typedef QHash<GLC_uint, PointerViewInstanceHash*> HashList;
 
 //! Map Shader id to instances id (instances which use the shader)
-typedef QHash<GLC_uint, GLuint> ShaderIdToInstancesId;
+typedef QHash<GLC_uint, GLC_uint> ShaderIdToInstancesId;
 
 //////////////////////////////////////////////////////////////////////
 //! \class GLC_3DViewCollection
@@ -132,7 +132,7 @@ public:
 	int drawableObjectsSize() const;
 
 	//! Return the element shading group
-	inline GLuint shadingGroup(GLC_uint key) const
+	inline GLC_uint shadingGroup(GLC_uint key) const
 	{ return m_ShaderGroup.value(key);}
 
 	//! Return true if the element is in a shading group
@@ -153,6 +153,9 @@ public:
 	inline GLC_SpacePartitioning* spacePartitioningHandle()
 	{return m_pSpacePartitioning;}
 
+	//! Return true if the collection is viewable
+	inline bool isViewable() const
+	{return m_IsViewable;}
 
 //@}
 
@@ -164,11 +167,11 @@ public:
 
 	//! Bind the specified shader to the collection
 	 /* return true if success false if shader is already bind*/
-	bool bindShader(GLuint);
+	bool bindShader(GLC_uint shaderId);
 
 	//! Unbind the specified shader from the collection
 	/* return true if success false otherwise*/
-	bool unBindShader(GLuint);
+	bool unBindShader(GLC_uint shaderId);
 
 	//! Unbind All shader
 	bool unBindAllShader();
@@ -176,13 +179,13 @@ public:
 	//! Add a GLC_3DViewInstance in the collection
 	/*! return true if success false otherwise
 	 * If shading group is specified, add instance in desire shading group*/
-	bool add(const GLC_3DViewInstance& ,GLuint shaderID=0);
+	bool add(const GLC_3DViewInstance& ,GLC_uint shaderID=0);
 
 	//! Change instance shading group
 	/* Move the specified instances into
 	 * the specified shading group
 	 * Return true if success false otherwise*/
-	void changeShadingGroup(GLC_uint, GLuint);
+	void changeShadingGroup(GLC_uint instanceId, GLC_uint shaderId);
 
 	//! Remove a GLC_Geometry from the collection and delete it
 	/*! 	- Find the GLC_Geometry in the collection
@@ -192,28 +195,28 @@ public:
 	 * 		- Remove the Display list container from collection
 	 * 		- Invalidate the collection
 	 * return true if success false otherwise*/
-	bool remove(GLC_uint Key);
+	bool remove(GLC_uint instanceId);
 
 	//! Remove and delete all GLC_Geometry from the collection
 	void clear(void);
 
 	//! Select a Instance
-	bool select(GLC_uint, bool primitive= false);
+	bool select(GLC_uint instanceId, bool primitive= false);
 
 	//! Select all instances in current show state or in all show state
 	void selectAll(bool allShowState= false);
 
 	//! unselect a Instance
-	bool unselect(GLC_uint);
+	bool unselect(GLC_uint instanceId);
 
 	//! unselect all Instance
 	void unselectAll();
 
 	//! Set the polygon mode for all Instance
-	void setPolygonModeForAll(GLenum, GLenum);
+	void setPolygonModeForAll(GLenum face, GLenum mode);
 
 	//! Set Instance visibility
-	void setVisibility(const GLC_uint, const bool);
+	void setVisibility(const GLC_uint instanceId, const bool visible);
 
 	//! Show all instances of the collection
 	void showAll();
@@ -223,15 +226,7 @@ public:
 
 	//! Set the Show or noShow state
 	inline void swapShowState()
-	{
-		m_IsInShowSate= !m_IsInShowSate;
-		// Bounding box validity
-		if (NULL != m_pBoundingBox)
-		{
-			delete m_pBoundingBox;
-			m_pBoundingBox= NULL;
-		}
-	}
+	{m_IsInShowSate= !m_IsInShowSate;}
 
 	//! Set the LOD usage
 	inline void setLodUsage(const bool usage, GLC_Viewport* pView)
@@ -261,6 +256,14 @@ public:
 	//! Set the attached viewport of this collection
 	inline void setAttachedViewport(GLC_Viewport* pViewport)
 	{m_pViewport= pViewport;}
+
+	//! Set the collection viewable state
+	inline void setViewable(bool viewable)
+	{m_IsViewable= viewable;}
+
+	//! Set VBO usage
+	void setVboUsage(bool usage);
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -287,24 +290,13 @@ public:
 
 private:
 	//! Display collection's member
-	void glDraw(GLuint, glc::RenderFlag);
+	void glDraw(GLC_uint groupID, glc::RenderFlag renderFlag);
 
 	//! Draw instances of a PointerViewInstanceHash
 	inline void glDrawInstancesOf(PointerViewInstanceHash*, glc::RenderFlag);
 
 //@}
 
-//////////////////////////////////////////////////////////////////////
-/*! \name Privates services Functions*/
-//@{
-//////////////////////////////////////////////////////////////////////
-
-private:
-	//! Set the Bounding box validity
-	void setBoundingBoxValidity(void);
-
-//@}
-
 //////////////////////////////////////////////////////////////////////
 // Private members
 //////////////////////////////////////////////////////////////////////
@@ -312,9 +304,6 @@ private:
 	//! GLC_3DViewInstance Hash Table
 	ViewInstancesHash m_3DViewInstanceHash;
 
-	//! BoundingBox of the collection
-	GLC_BoundingBox* m_pBoundingBox;
-
 	//! Selected Node Hash Table
 	PointerViewInstanceHash m_SelectedInstances;
 
@@ -342,6 +331,9 @@ private:
 	//! The space partition usage
 	bool m_UseSpacePartitioning;
 
+	//! Viewable state
+	bool m_IsViewable;
+
 
 };
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.cpp b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.cpp
index cd3a4c98b..567774d54 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.cpp
@@ -192,11 +192,17 @@ void GLC_3DViewInstance::setGlobalDefaultLod(int lod)
 	m_GlobalDefaultLOD= lod;
 }
 
+void GLC_3DViewInstance::setVboUsage(bool usage)
+{
+	m_3DRep.setVboUsage(usage);
+}
+
 // Clone the instance
 GLC_3DViewInstance GLC_3DViewInstance::deepCopy() const
 {
 
 	GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(m_3DRep.deepCopy());
+	Q_ASSERT(NULL != pRep);
 	GLC_3DRep newRep(*pRep);
 	delete pRep;
 	GLC_3DViewInstance cloneInstance(newRep);
@@ -231,7 +237,7 @@ GLC_3DViewInstance GLC_3DViewInstance::instanciate()
 
 
 // Set the instance Geometry
-bool GLC_3DViewInstance::setGeometry(GLC_Geometry* pGeom)
+bool GLC_3DViewInstance::addGeometry(GLC_Geometry* pGeom)
 {
 	if (m_3DRep.contains(pGeom))
 	{
@@ -299,7 +305,7 @@ void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Vie
 	m_RenderProperties.setRenderingFlag(renderFlag);
 
 	// Save current OpenGL Matrix
-	glPushMatrix();
+	GLC_Context::current()->glcPushMatrix();
 	OpenglVisProperties();
 
 	// Change front face orientation if this instance absolute matrix is indirect
@@ -350,7 +356,7 @@ void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Vie
 		}
 	}
 	// Restore OpenGL Matrix
-	glPopMatrix();
+	GLC_Context::current()->glcPopMatrix();
 
 	// Restore front face orientation if this instance absolute matrix is indirect
 	if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect)
@@ -371,7 +377,7 @@ void GLC_3DViewInstance::renderForBodySelection()
 	m_RenderProperties.setRenderingMode(glc::BodySelection);
 
 	// Save current OpenGL Matrix
-	glPushMatrix();
+	GLC_Context::current()->glcPushMatrix();
 	OpenglVisProperties();
 
 	GLubyte colorId[4];
@@ -389,7 +395,7 @@ void GLC_3DViewInstance::renderForBodySelection()
 	// Restore rendering mode
 	m_RenderProperties.setRenderingMode(previousRenderMode);
 	// Restore OpenGL Matrix
-	glPopMatrix();
+	GLC_Context::current()->glcPopMatrix();
 }
 
 // Display the instance in Primitive selection mode and return the body index
@@ -402,7 +408,7 @@ int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId)
 	m_RenderProperties.setRenderingMode(glc::PrimitiveSelection);
 
 	// Save current OpenGL Matrix
-	glPushMatrix();
+	GLC_Context::current()->glcPushMatrix();
 	OpenglVisProperties();
 
 	const int size= m_3DRep.numberOfBody();
@@ -423,7 +429,7 @@ int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId)
 	m_RenderProperties.setRenderingMode(previousRenderMode);
 
 	// Restore OpenGL Matrix
-	glPopMatrix();
+	GLC_Context::current()->glcPopMatrix();
 
 	return i;
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.h b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.h
index 3ec626417..257f08874 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_3dviewinstance.h
@@ -32,10 +32,11 @@
 #include "../glc_state.h"
 #include "../geometry/glc_3drep.h"
 #include "../shading/glc_renderproperties.h"
+#include "../glc_context.h"
 
 #include <QMutex>
 
-#include "glc_config.h"
+#include "../glc_config.h"
 
 class GLC_Viewport;
 
@@ -197,10 +198,7 @@ public:
 public:
 
 	//! Set the instance Geometry
-	/*!
-	 *  instance must be null
-	 */
-	bool setGeometry(GLC_Geometry* pGeom);
+	bool addGeometry(GLC_Geometry* pGeom);
 
 	//! Remove empty geometries
 	inline void removeEmptyGeometry()
@@ -274,6 +272,9 @@ public:
 	inline void setRenderProperties(const GLC_RenderProperties& renderProperties)
 	{m_RenderProperties= renderProperties;}
 
+	//! Set VBO usage
+	void setVboUsage(bool usage);
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -298,7 +299,7 @@ private:
 		// Polygons display mode
 		glPolygonMode(m_RenderProperties.polyFaceMode(), m_RenderProperties.polygonMode());
 		// Change the current matrix
-		glMultMatrixd(m_AbsoluteMatrix.getData());
+		GLC_Context::current()->glcMultMatrix(m_AbsoluteMatrix);
 	}
 
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structinstance.cpp b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structinstance.cpp
index 11ff8c483..0137c5def 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structinstance.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structinstance.cpp
@@ -180,3 +180,12 @@ GLC_StructInstance::~GLC_StructInstance()
 	else qDebug() << "GLC_StructInstance::~GLC_StructInstance() of empty instance";
 
 }
+
+void GLC_StructInstance::updateOccurencesAbsoluteMatrix()
+{
+	const int occurenceCount= m_ListOfOccurences.count();
+	for (int i= 0; i < occurenceCount; ++i)
+	{
+		m_ListOfOccurences.at(i)->updateChildrenAbsoluteMatrix();
+	}
+}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structinstance.h b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structinstance.h
index 4c43fb000..3ae653965 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structinstance.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structinstance.h
@@ -166,12 +166,15 @@ public:
 	{m_Name= name;}
 
 	//! Set the instance attributes
-	void setAttributes(const GLC_Attributes& attr)
+	inline void setAttributes(const GLC_Attributes& attr)
 	{
 		delete m_pAttributes;
 		m_pAttributes= new GLC_Attributes(attr);
 	}
 
+	//! Update absolute matrix off children and all occurences of this instance
+	void updateOccurencesAbsoluteMatrix();
+
 
 //@}
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.cpp b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.cpp
index 6a18155bb..2c9c6d939 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.cpp
@@ -41,6 +41,7 @@ GLC_StructOccurence::GLC_StructOccurence()
 , m_IsVisible(true)
 , m_pRenderProperties(NULL)
 , m_AutomaticCreationOf3DViewInstance(true)
+, m_pRelativeMatrix(NULL)
 {
 	// Update instance
 	m_pStructInstance->structOccurenceCreated(this);
@@ -60,6 +61,7 @@ GLC_StructOccurence::GLC_StructOccurence(GLC_StructInstance* pStructInstance, GL
 , m_IsVisible(true)
 , m_pRenderProperties(NULL)
 , m_AutomaticCreationOf3DViewInstance(true)
+, m_pRelativeMatrix(NULL)
 {
 	// Update the number of occurences
 	if (pStructInstance->hasStructOccurence())
@@ -107,6 +109,7 @@ GLC_StructOccurence::GLC_StructOccurence(GLC_3DRep* pRep)
 , m_IsVisible(true)
 , m_pRenderProperties(NULL)
 , m_AutomaticCreationOf3DViewInstance(true)
+, m_pRelativeMatrix(NULL)
 {
 	m_pStructInstance= new GLC_StructInstance(pRep);
 	setName(m_pStructInstance->name());
@@ -128,6 +131,7 @@ GLC_StructOccurence::GLC_StructOccurence(GLC_WorldHandle* pWorldHandle, const GL
 , m_IsVisible(structOccurence.m_IsVisible)
 , m_pRenderProperties(NULL)
 , m_AutomaticCreationOf3DViewInstance(structOccurence.m_AutomaticCreationOf3DViewInstance)
+, m_pRelativeMatrix(NULL)
 {
 	if (shareInstance)
 	{
@@ -170,7 +174,7 @@ GLC_StructOccurence::GLC_StructOccurence(GLC_WorldHandle* pWorldHandle, const GL
 	if (NULL != m_pWorldHandle)
 	{
 		m_pWorldHandle->addOccurence(this, instanceIsSelected, shaderId);
-		if (NULL != m_pRenderProperties)
+		if (NULL != m_pRenderProperties && this->has3DViewInstance())
 		{
 			m_pWorldHandle->collection()->instanceHandle(id())->setRenderProperties(*m_pRenderProperties);
 			delete m_pRenderProperties;
@@ -178,6 +182,12 @@ GLC_StructOccurence::GLC_StructOccurence(GLC_WorldHandle* pWorldHandle, const GL
 		}
 	}
 
+	// Check flexibility
+	if (NULL != structOccurence.m_pRelativeMatrix)
+	{
+		m_pRelativeMatrix= new GLC_Matrix4x4(*(structOccurence.m_pRelativeMatrix));
+	}
+
 	// Update Absolute matrix
 	updateAbsoluteMatrix();
 
@@ -236,12 +246,23 @@ GLC_StructOccurence::~GLC_StructOccurence()
 	}
 
 	delete m_pRenderProperties;
+	delete m_pRelativeMatrix;
 }
 
 //////////////////////////////////////////////////////////////////////
 // Get Functions
 //////////////////////////////////////////////////////////////////////
 
+GLC_Matrix4x4 GLC_StructOccurence::occurrenceRelativeMatrix() const
+{
+	GLC_Matrix4x4 matrix;
+	if (NULL != m_pRelativeMatrix)
+	{
+		matrix= *m_pRelativeMatrix;
+	}
+	return matrix;
+}
+
 bool GLC_StructOccurence::hasRepresentation() const
 {
 	if ((NULL != m_pStructInstance) && (m_pStructInstance->hasStructOccurence()))
@@ -288,14 +309,11 @@ QList<GLC_StructOccurence*> GLC_StructOccurence::subOccurenceList() const
 	for (int i= 0; i < childCount; ++i)
 	{
 		GLC_StructOccurence* pCurrentChild= m_Childs.at(i);
+		subOccurence.append(pCurrentChild);
 		if (pCurrentChild->hasChild())
 		{
 			subOccurence.append(pCurrentChild->subOccurenceList());
 		}
-		else
-		{
-			subOccurence.append(pCurrentChild);
-		}
 	}
 
 	return subOccurence;
@@ -484,13 +502,23 @@ QSet<GLC_StructReference*> GLC_StructOccurence::parentsReferences(const GLC_Stru
 // Update the absolute matrix
 GLC_StructOccurence* GLC_StructOccurence::updateAbsoluteMatrix()
 {
-	if (NULL != m_pParent)
+	GLC_Matrix4x4 relativeMatrix;
+	if (NULL == m_pRelativeMatrix)
 	{
-		m_AbsoluteMatrix= m_pParent->absoluteMatrix() * m_pStructInstance->relativeMatrix();
+		relativeMatrix= m_pStructInstance->relativeMatrix();
 	}
 	else
 	{
-		m_AbsoluteMatrix= m_pStructInstance->relativeMatrix();
+		relativeMatrix= *m_pRelativeMatrix;
+	}
+
+	if (NULL != m_pParent)
+	{
+		m_AbsoluteMatrix= m_pParent->absoluteMatrix() * relativeMatrix;
+	}
+	else
+	{
+		m_AbsoluteMatrix= relativeMatrix;
 	}
 	// If the occurence have a representation, update it.
 
@@ -563,33 +591,6 @@ bool GLC_StructOccurence::removeChild(GLC_StructOccurence* pChild)
 	return m_Childs.removeOne(pChild);
 }
 
-// Detach the occurence from the GLC_World
-void GLC_StructOccurence::detach()
-{
-	if (NULL != m_pWorldHandle)
-	{
-		// retrieve renderProperties if needed
-		if (m_pWorldHandle->collection()->contains(m_Uid))
-		{
-			GLC_3DViewInstance* pInstance= m_pWorldHandle->collection()->instanceHandle(m_Uid);
-			if (!pInstance->renderPropertiesHandle()->isDefault())
-			{
-				Q_ASSERT(NULL == m_pRenderProperties);
-				m_pRenderProperties= new GLC_RenderProperties(*(pInstance->renderPropertiesHandle()));
-			}
-		}
-		m_pWorldHandle->removeOccurence(this);
-		m_pWorldHandle= NULL;
-		if (!m_Childs.isEmpty())
-		{
-			const int size= m_Childs.size();
-			for (int i= 0; i < size; ++i)
-			{
-				m_Childs[i]->detach();
-			}
-		}
-	}
-}
 
 // Reverse Normals of this Occurence and childs
 void GLC_StructOccurence::reverseNormals()
@@ -611,10 +612,23 @@ bool GLC_StructOccurence::create3DViewInstance()
 		{
 			GLC_3DViewInstance instance(*p3DRep);
 			instance.setName(name());
+
 			// Force instance representation id
 			instance.setId(id());
+
+			if (NULL != m_pRenderProperties)
+			{
+				instance.setRenderProperties(*m_pRenderProperties);
+				delete m_pRenderProperties;
+				m_pRenderProperties= NULL;
+			}
+
 			creationSuccess= m_pWorldHandle->collection()->add(instance);
 			m_pWorldHandle->collection()->setVisibility(m_Uid, m_IsVisible);
+			if (m_pWorldHandle->selectionSetHandle()->contains(m_Uid))
+			{
+				m_pWorldHandle->collection()->select(m_Uid);
+			}
 		}
 	}
 	return creationSuccess;
@@ -814,3 +828,51 @@ void GLC_StructOccurence::setReference(GLC_StructReference* pRef)
 
 	m_pStructInstance->setReference(pRef);
 }
+
+void GLC_StructOccurence::makeFlexible(const GLC_Matrix4x4& relativeMatrix)
+{
+	delete m_pRelativeMatrix;
+	m_pRelativeMatrix= new GLC_Matrix4x4(relativeMatrix);
+
+	updateChildrenAbsoluteMatrix();
+}
+
+void GLC_StructOccurence::makeRigid()
+{
+	delete m_pRelativeMatrix;
+	m_pRelativeMatrix= NULL;
+
+	updateChildrenAbsoluteMatrix();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Private services function
+//////////////////////////////////////////////////////////////////////
+
+void GLC_StructOccurence::detach()
+{
+	if (NULL != m_pWorldHandle)
+	{
+		// retrieve renderProperties if needed
+		if (m_pWorldHandle->collection()->contains(m_Uid))
+		{
+			GLC_3DViewInstance* pInstance= m_pWorldHandle->collection()->instanceHandle(m_Uid);
+			if (!pInstance->renderPropertiesHandle()->isDefault())
+			{
+				Q_ASSERT(NULL == m_pRenderProperties);
+				m_pRenderProperties= new GLC_RenderProperties(*(pInstance->renderPropertiesHandle()));
+			}
+		}
+		m_pWorldHandle->removeOccurence(this);
+		m_pWorldHandle= NULL;
+		if (!m_Childs.isEmpty())
+		{
+			const int size= m_Childs.size();
+			for (int i= 0; i < size; ++i)
+			{
+				m_Childs[i]->detach();
+			}
+		}
+	}
+}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.h b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.h
index fb2bdfe65..8bbc14668 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_structoccurence.h
@@ -80,6 +80,9 @@ public:
 	inline GLC_Matrix4x4 absoluteMatrix() const
 	{ return m_AbsoluteMatrix;}
 
+	//! Return the surcharged relative matrix
+	GLC_Matrix4x4 occurrenceRelativeMatrix() const;
+
 	//! Return true if this occurence is orphan
 	inline bool isOrphan() const
 	{ return NULL == m_pParent;}
@@ -178,7 +181,9 @@ public:
 	inline bool useAutomatic3DViewInstanceCreation() const
 	{return m_AutomaticCreationOf3DViewInstance;}
 
-
+	//! Return true if this occurence is flexible
+	inline bool isFlexible() const
+	{return (m_pRelativeMatrix != NULL);}
 //@}
 //////////////////////////////////////////////////////////////////////
 /*! \name Set Functions*/
@@ -250,7 +255,11 @@ public:
 	inline void setAutomatic3DViewInstanceCreationUsage(bool usage)
 	{m_AutomaticCreationOf3DViewInstance= usage;}
 
+	//! Make this occurence a flexible occurence
+	void makeFlexible(const GLC_Matrix4x4& relativeMatrix);
 
+	//! Make this occurence rigid
+	void makeRigid();
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -297,6 +306,9 @@ private:
 	//! Automatique cr�ation of 3DViewInstance
 	bool m_AutomaticCreationOf3DViewInstance;
 
+	//! The relative matrix of this occurence if this occurence is flexible
+	GLC_Matrix4x4* m_pRelativeMatrix;
+
 };
 
 #endif /* GLC_STRUCTOCCURENCE_H_ */
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_world.cpp b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_world.cpp
index cbb82e9bb..24dcafe0f 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_world.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_world.cpp
@@ -32,7 +32,6 @@ GLC_World::GLC_World()
 , m_pRoot(new GLC_StructOccurence())
 {
 	m_pRoot->setWorldHandle(m_pWorldHandle);
-	//qDebug() << "GLC_World::GLC_World() : " << (*m_pNumberOfWorld) << " " << this;
 }
 
 // Copy constructor
@@ -43,14 +42,13 @@ GLC_World::GLC_World(const GLC_World& world)
 	//qDebug() << "GLC_World::GLC_World() : " << (*m_pNumberOfWorld) << " " << this;
 	// Increment the number of world
 	m_pWorldHandle->increment();
+
 }
 
 GLC_World::~GLC_World()
 {
-
 	// Decrement the number of world
 	m_pWorldHandle->decrement();
-	//qDebug() << "GLC_World::GLC_World() : " << (*m_pNumberOfWorld) << " " << this;
 	if (m_pWorldHandle->isOrphan())
 	{
 		// this is the last World, delete the root product and collection
@@ -63,7 +61,6 @@ GLC_World::~GLC_World()
 // Merge this world with another world
 void GLC_World::mergeWithAnotherWorld(GLC_World& anotherWorld)
 {
-	qDebug() << "GLC_World::mergeWithAnotherWorld";
 	GLC_StructOccurence* pAnotherRoot= anotherWorld.rootOccurence();
 	if (pAnotherRoot->childCount() > 0)
 	{
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.cpp b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.cpp
index 561053207..e170aaafb 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.cpp
@@ -131,14 +131,14 @@ void GLC_WorldHandle::removeOccurence(GLC_StructOccurence* pOccurence)
 	m_Collection.remove(pOccurence->id());
 }
 
-void GLC_WorldHandle::select(GLC_uint occurenceId, bool propagate)
+void GLC_WorldHandle::select(GLC_uint occurenceId)
 {
 	Q_ASSERT(m_OccurenceHash.contains(occurenceId));
 	m_SelectionSet.insert(occurenceId);
 	m_Collection.select(occurenceId);
 
 	const GLC_StructOccurence* pSelectedOccurence= m_OccurenceHash.value(occurenceId);
-	if (propagate && pSelectedOccurence->hasChild())
+	if (pSelectedOccurence->hasChild())
 	{
 		QList<GLC_StructOccurence*> subOccurenceList= pSelectedOccurence->subOccurenceList();
 		const int subOccurenceCount= subOccurenceList.size();
@@ -147,8 +147,8 @@ void GLC_WorldHandle::select(GLC_uint occurenceId, bool propagate)
 			const GLC_uint currentOccurenceId= subOccurenceList.at(i)->id();
 			if (m_Collection.contains(currentOccurenceId))
 			{
-				GLC_3DViewInstance* pInstance= m_Collection.instanceHandle(currentOccurenceId);
-				m_Collection.select(currentOccurenceId);			}
+				m_Collection.select(currentOccurenceId);
+			}
 		}
 	}
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.h b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.h
index 9e835785d..bfc10195a 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/sceneGraph/glc_worldhandle.h
@@ -143,7 +143,7 @@ public:
 
 	//! Select the given occurence id
 	/*! The given occurence id must belong to this worldhandle*/
-	void select(GLC_uint occurenceId, bool propagate= true);
+	void select(GLC_uint occurenceId);
 
 	//! Unselect the given occurence id
 	/*! The given occurence id must belong to this worldhandle*/
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_light.cpp b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_light.cpp
index 16b932c65..c08708c59 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_light.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_light.cpp
@@ -22,23 +22,23 @@
 
 //! \file glc_light.cpp implementation of the GLC_Light class.
 
-#include "glc_light.h"
-#include "../glc_openglexception.h"
-
+#include <QGLContext>
 #include <QtDebug>
 
-GLint GLC_Light::m_MaxLight= 0;
-QSet<GLenum> GLC_Light::m_FreeLightSet;
+#include "glc_light.h"
+#include "../glc_openglexception.h"
+#include "../glc_context.h"
+
+GLint GLC_Light::m_MaxLight= 8;
+QHash<const QGLContext*, QSet<GLenum> > GLC_Light::m_ContextToFreeLightSet;
 
 //////////////////////////////////////////////////////////////////////
 // Constructor Destructor
 //////////////////////////////////////////////////////////////////////
-GLC_Light::GLC_Light(const QColor& color)
+GLC_Light::GLC_Light(const QGLContext* pContext, const QColor& color)
 :GLC_Object("Light")
 , m_LightID(-1)
 , m_LightType(LightPosition)
-, m_ListID(0)
-, m_ListIsValid(false)
 , m_AmbientColor(Qt::black)
 , m_DiffuseColor(color)
 , m_SpecularColor(Qt::white)
@@ -50,19 +50,16 @@ GLC_Light::GLC_Light(const QColor& color)
 , m_LinearAttenuation(0.0f)
 , m_QuadraticAttenuation(0.0f)
 , m_TwoSided(false)
+, m_pContext(const_cast<QGLContext*>(pContext))
+, m_IsValid(false)
 {
-	if (0 == m_MaxLight) init();
-	Q_ASSERT(!m_FreeLightSet.isEmpty());
-	m_LightID= *(m_FreeLightSet.constBegin());
-	m_FreeLightSet.remove(m_LightID);
+	addNewLight();
 }
 
-GLC_Light::GLC_Light(LightType lightType, const QColor& color)
+GLC_Light::GLC_Light(LightType lightType, const QGLContext* pContext, const QColor& color)
 :GLC_Object("Light")
 , m_LightID(-1)
 , m_LightType(lightType)
-, m_ListID(0)
-, m_ListIsValid(false)
 , m_AmbientColor(Qt::black)
 , m_DiffuseColor(color)
 , m_SpecularColor(Qt::white)
@@ -74,19 +71,16 @@ GLC_Light::GLC_Light(LightType lightType, const QColor& color)
 , m_LinearAttenuation(0.0f)
 , m_QuadraticAttenuation(0.0f)
 , m_TwoSided(false)
+, m_pContext(const_cast<QGLContext*>(pContext))
+, m_IsValid(false)
 {
-	if (0 == m_MaxLight) init();
-	Q_ASSERT(!m_FreeLightSet.isEmpty());
-	m_LightID= *(m_FreeLightSet.constBegin());
-	m_FreeLightSet.remove(m_LightID);
+	addNewLight();
 }
 
 GLC_Light::GLC_Light(const GLC_Light& light)
 :GLC_Object(light)
 , m_LightID(-1)
 , m_LightType(light.m_LightType)
-, m_ListID(0)
-, m_ListIsValid(false)
 , m_AmbientColor(light.m_AmbientColor)
 , m_DiffuseColor(light.m_DiffuseColor)
 , m_SpecularColor(light.m_SpecularColor)
@@ -98,17 +92,15 @@ GLC_Light::GLC_Light(const GLC_Light& light)
 , m_LinearAttenuation(light.m_LinearAttenuation)
 , m_QuadraticAttenuation(light.m_QuadraticAttenuation)
 , m_TwoSided(light.m_TwoSided)
+, m_pContext(light.m_pContext)
+, m_IsValid(false)
 {
-	if (0 == m_MaxLight) init();
-	Q_ASSERT(!m_FreeLightSet.isEmpty());
-	m_LightID= *(m_FreeLightSet.constBegin());
-	m_FreeLightSet.remove(m_LightID);
+	addNewLight();
 }
 
 GLC_Light::~GLC_Light(void)
 {
-	deleteList();
-	m_FreeLightSet << m_LightID;
+	removeThisLight();
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -120,199 +112,130 @@ int GLC_Light::maxLightCount()
 	return m_MaxLight;
 }
 
-int GLC_Light::builtAbleLightCount()
+int GLC_Light::builtAbleLightCount(QGLContext* pContext)
 {
-	return m_FreeLightSet.size();
+	if (m_ContextToFreeLightSet.contains(pContext))
+	{
+		return m_ContextToFreeLightSet.value(pContext).size();
+	}
+	else return m_MaxLight;
 }
 
 /////////////////////////////////////////////////////////////////////
 // Set Functions
 //////////////////////////////////////////////////////////////////////
-void GLC_Light::init()
+void GLC_Light::initForThisContext()
 {
-	m_MaxLight= 8;
 	for (int i= 0; i < m_MaxLight; ++i)
 	{
-		m_FreeLightSet.insert(GL_LIGHT0 + i);
+		m_ContextToFreeLightSet[m_pContext].insert(GL_LIGHT0 + i);
 	}
 }
 
 void GLC_Light::setPosition(const GLC_Point3d &pos)
 {
 	m_Position= pos;
-	m_ListIsValid = false;
 }
 
 void GLC_Light::setPosition(GLfloat x, GLfloat y, GLfloat z)
 {
 	m_Position.setVect(static_cast<double>(x), static_cast<double>(y), static_cast<double>(z));
-	m_ListIsValid = false;
 }
 
 void GLC_Light::setAmbientColor(const QColor& color)
 {
 	m_AmbientColor= color;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 void GLC_Light::setDiffuseColor(const QColor& color)
 {
 	m_DiffuseColor= color;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 void GLC_Light::setSpecularColor(const QColor& color)
 {
 	m_SpecularColor= color;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 void GLC_Light::setTwoSided(const bool mode)
 {
-	if (m_TwoSided != mode)
-	{
-		m_TwoSided= mode;
-		m_ListIsValid = false;
-	}
+	m_TwoSided= mode;
+	m_IsValid= false;
 }
 
 void GLC_Light::setConstantAttenuation(GLfloat constantAttenuation)
 {
 	m_ConstantAttenuation= constantAttenuation;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 void GLC_Light::setLinearAttenuation(GLfloat linearAttenuation)
 {
 	m_LinearAttenuation= linearAttenuation;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 void GLC_Light::setQuadraticAttenuation(GLfloat quadraticAttenuation)
 {
 	m_QuadraticAttenuation= quadraticAttenuation;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 void GLC_Light::setSpotDirection(const GLC_Vector3d& direction)
 {
 	m_SpotDirection= direction;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 void GLC_Light::setSpotCutoffAngle(GLfloat cutoffAngle)
 {
 	m_SpotCutoffAngle= cutoffAngle;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 void GLC_Light::setSpotEponent(GLfloat exponent)
 {
 	m_SpotExponent= exponent;
-	m_ListIsValid = false;
+	m_IsValid= false;
 }
 
 //////////////////////////////////////////////////////////////////////
 // OpenGL Functions
 //////////////////////////////////////////////////////////////////////
 
-void GLC_Light::creationList(GLenum Mode)
+
+void GLC_Light::disable()
 {
-	if(0 == m_ListID)		// OpenGL list not created
+	if (NULL != m_pContext)
 	{
-		m_ListID= glGenLists(1);
-
-		if (0 == m_ListID)	// OpenGL List Id not get
-		{
-			glDraw();
-			qDebug("GLC_Light::CreationListe Display list not create");
-		}
-	}
-	if (0 != m_ListID)
-	{
-		// OpenGL list creation and execution
-		glNewList(m_ListID, Mode);
-
-		// Light execution
-		glDraw();
-
-		glEndList();
-
-		m_ListIsValid= true;
-	}
-
-	// OpenGL error handler
-	GLenum error= glGetError();
-	if (error != GL_NO_ERROR)
-	{
-		GLC_OpenGlException OpenGlException("GLC_Light::CreationList ", error);
-		throw(OpenGlException);
+		glDisable(m_LightID);
 	}
 }
 
-void GLC_Light::glExecute(GLenum Mode)
+
+void GLC_Light::glExecute()
 {
-
-	if (!m_ListIsValid)
+	if (NULL == m_pContext)
 	{
-		// OpenGL list is not valid
-		/*
-		GLfloat value;
-		glGetFloatv(GL_CONSTANT_ATTENUATION, &value);
-		qDebug() << "GL_CONSTANT_ATTENUATION " << value;
-		glGetFloatv(GL_LINEAR_ATTENUATION, &value);
-		qDebug() << "GL_LINEAR_ATTENUATION " << value;
-		glGetFloatv(GL_QUADRATIC_ATTENUATION, &value);
-		qDebug() << "GL_QUADRATIC_ATTENUATION " << value;
-		*/
-		creationList(Mode);
-	}
-	else
-	{
-		glCallList(m_ListID);
+		m_pContext= const_cast<QGLContext*>(QGLContext::currentContext());
+		Q_ASSERT(NULL != m_pContext);
+		addNewLight();
 	}
 
-	// OpenGL error handler
-	GLenum error= glGetError();
-	if (error != GL_NO_ERROR)
+	GLC_Context::current()->glcEnableLighting(true);
+	glEnable(m_LightID);
+
+	if (m_pContext != QGLContext::currentContext())
 	{
-		GLC_OpenGlException OpenGlException("GLC_Light::GlExecute ", error);
-		throw(OpenGlException);
+		Q_ASSERT(QGLContext::areSharing(m_pContext, QGLContext::currentContext()));
+		m_IsValid= false;
 	}
+	Q_ASSERT(m_pContext->isValid());
 
-}
-
-void GLC_Light::glDraw(void)
-{
-	// Set the lighting model
-	if (m_TwoSided)
-	{
-		glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
-	}
-	else
-	{
-		glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
-	}
-
-	// Color
-	GLfloat setArray[4]= {static_cast<GLfloat>(m_AmbientColor.redF()),
-									static_cast<GLfloat>(m_AmbientColor.greenF()),
-									static_cast<GLfloat>(m_AmbientColor.blueF()),
-									static_cast<GLfloat>(m_AmbientColor.alphaF())};
-	glLightfv(m_LightID, GL_AMBIENT, setArray);		// Setup The Ambient Light
-
-	setArray[0]= static_cast<GLfloat>(m_DiffuseColor.redF());
-	setArray[1]= static_cast<GLfloat>(m_DiffuseColor.greenF());
-	setArray[2]= static_cast<GLfloat>(m_DiffuseColor.blueF());
-	setArray[3]= static_cast<GLfloat>(m_DiffuseColor.alphaF());
-	glLightfv(m_LightID, GL_DIFFUSE, setArray);		// Setup The Diffuse Light
-
-
-	setArray[0]= static_cast<GLfloat>(m_SpecularColor.redF());
-	setArray[1]= static_cast<GLfloat>(m_SpecularColor.greenF());
-	setArray[2]= static_cast<GLfloat>(m_SpecularColor.blueF());
-	setArray[3]= static_cast<GLfloat>(m_SpecularColor.alphaF());
-	glLightfv(m_LightID, GL_SPECULAR, setArray);	// Setup The specular Light
+	GLfloat setArray[4];
 
 	// Position
 	setArray[0]= static_cast<GLfloat>(m_Position.x());
@@ -328,30 +251,67 @@ void GLC_Light::glDraw(void)
 	{
 		setArray[3]= 1.0f;
 		glLightfv(m_LightID, GL_POSITION, setArray);	// Position of the Light
-		glLightf(m_LightID, GL_CONSTANT_ATTENUATION, m_ConstantAttenuation);
-		glLightf(m_LightID, GL_LINEAR_ATTENUATION, m_LinearAttenuation);
-		glLightf(m_LightID, GL_QUADRATIC_ATTENUATION, m_QuadraticAttenuation);
-
 	}
 
-	// Spot light parameters
-	if (LightSpot == m_LightType)
+
+	if (!m_IsValid)
 	{
-		// Spot Direction
-		setArray[0]= static_cast<GLfloat>(m_SpotDirection.x());
-		setArray[1]= static_cast<GLfloat>(m_SpotDirection.y());
-		setArray[2]= static_cast<GLfloat>(m_SpotDirection.z());
-		glLightfv(m_LightID, GL_SPOT_DIRECTION, setArray);
-		glLightf(m_LightID, GL_SPOT_EXPONENT, m_SpotExponent);
-		glLightf(m_LightID, GL_SPOT_CUTOFF, m_SpotCutoffAngle);
-	}
+		// Set the lighting model
+		if (m_TwoSided)
+		{
+			glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
+		}
+		else
+		{
+			glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+		}
 
+		// Color
+		setArray[0]= static_cast<GLfloat>(m_AmbientColor.redF());
+		setArray[1]= static_cast<GLfloat>(m_AmbientColor.greenF());
+		setArray[2]= static_cast<GLfloat>(m_AmbientColor.blueF());
+		setArray[3]= static_cast<GLfloat>(m_AmbientColor.alphaF());
+		glLightfv(m_LightID, GL_AMBIENT, setArray);		// Setup The Ambient Light
+
+		setArray[0]= static_cast<GLfloat>(m_DiffuseColor.redF());
+		setArray[1]= static_cast<GLfloat>(m_DiffuseColor.greenF());
+		setArray[2]= static_cast<GLfloat>(m_DiffuseColor.blueF());
+		setArray[3]= static_cast<GLfloat>(m_DiffuseColor.alphaF());
+		glLightfv(m_LightID, GL_DIFFUSE, setArray);		// Setup The Diffuse Light
+
+
+		setArray[0]= static_cast<GLfloat>(m_SpecularColor.redF());
+		setArray[1]= static_cast<GLfloat>(m_SpecularColor.greenF());
+		setArray[2]= static_cast<GLfloat>(m_SpecularColor.blueF());
+		setArray[3]= static_cast<GLfloat>(m_SpecularColor.alphaF());
+		glLightfv(m_LightID, GL_SPECULAR, setArray);	// Setup The specular Light
+
+		if (LightDirection != m_LightType)
+			glLightf(m_LightID, GL_CONSTANT_ATTENUATION, m_ConstantAttenuation);
+			glLightf(m_LightID, GL_LINEAR_ATTENUATION, m_LinearAttenuation);
+			glLightf(m_LightID, GL_QUADRATIC_ATTENUATION, m_QuadraticAttenuation);
+
+		// Spot light parameters
+		if (LightSpot == m_LightType)
+		{
+			// Spot Direction
+			setArray[0]= static_cast<GLfloat>(m_SpotDirection.x());
+			setArray[1]= static_cast<GLfloat>(m_SpotDirection.y());
+			setArray[2]= static_cast<GLfloat>(m_SpotDirection.z());
+			glLightfv(m_LightID, GL_SPOT_DIRECTION, setArray);
+			glLightf(m_LightID, GL_SPOT_EXPONENT, m_SpotExponent);
+			glLightf(m_LightID, GL_SPOT_CUTOFF, m_SpotCutoffAngle);
+		}
+
+		m_IsValid= true;
+	}
 
 	// OpenGL error handler
 	GLenum error= glGetError();
 	if (error != GL_NO_ERROR)
 	{
-		GLC_OpenGlException OpenGlException("GLC_Light::GlDraw ", error);
+		qDebug() << "GLC_Light::glExecute Exception, id= " << m_LightID;
+		GLC_OpenGlException OpenGlException("GLC_Light::glExecute ", error);
 		throw(OpenGlException);
 	}
 
@@ -361,12 +321,44 @@ void GLC_Light::glDraw(void)
 // Private services Functions
 //////////////////////////////////////////////////////////////////////
 
-void GLC_Light::deleteList(void)
+
+//////////////////////////////////////////////////////////////////////
+// Private services fonction
+//////////////////////////////////////////////////////////////////////
+void GLC_Light::addNewLight()
 {
-	// if the list is valid, the list is deleted
-	if (glIsList(m_ListID))
+	if (NULL != m_pContext)
 	{
-		disable();
-		glDeleteLists(m_ListID, 1);
+		if (!m_ContextToFreeLightSet.contains(m_pContext))
+		{
+			m_ContextToFreeLightSet.insert(m_pContext, QSet<GLenum>());
+			initForThisContext();
+		}
+
+		// Some OpenGL driver support only Light0 ???
+		if (m_ContextToFreeLightSet.value(m_pContext).size() == m_MaxLight)
+		{
+			m_LightID= GL_LIGHT0;
+		}
+		else
+		{
+			m_LightID= *(m_ContextToFreeLightSet[m_pContext].constBegin());
+		}
+
+		m_ContextToFreeLightSet[m_pContext].remove(m_LightID);
+	}
+}
+
+void GLC_Light::removeThisLight()
+{
+	if (NULL != m_pContext)
+	{
+		Q_ASSERT(m_ContextToFreeLightSet.contains(m_pContext));
+		Q_ASSERT(!m_ContextToFreeLightSet[m_pContext].contains(m_LightID));
+		m_ContextToFreeLightSet[m_pContext].insert(m_LightID);
+		if (m_ContextToFreeLightSet[m_pContext].size() == m_MaxLight)
+		{
+			m_ContextToFreeLightSet.remove(m_pContext);
+		}
 	}
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_light.h b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_light.h
index 6714f3a33..761e76d2f 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_light.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_light.h
@@ -27,11 +27,15 @@
 
 #include <QColor>
 #include <QSet>
+#include <QHash>
+
 #include "../glc_object.h"
 #include "../maths/glc_vector3d.h"
 
 #include "../glc_config.h"
 
+class QGLContext;
+
 //////////////////////////////////////////////////////////////////////
 //! \class GLC_Light
 /*! \brief GLC_Light : OpenGL Point Light*/
@@ -57,11 +61,11 @@ public:
 public:
 	//! Construct a default GLC_Light
 	/*! By default, ambient color is black, diffuse Color is white and specular color is white*/
-	GLC_Light(const QColor& color= Qt::white);
+	GLC_Light(const QGLContext* pContext= NULL, const QColor& color= Qt::white);
 
 	//! Construct a default GLC_Light
 	/*! By default, ambient color is black, diffuse Color is white and specular color is white*/
-	GLC_Light(LightType lightType, const QColor& color= Qt::white);
+	GLC_Light(LightType lightType, const QGLContext* pContext= NULL, const QColor& color= Qt::white);
 
 	//! Copy constructor
 	GLC_Light(const GLC_Light& light);
@@ -79,7 +83,7 @@ public:
 	static int maxLightCount();
 
 	//! Return the number of builtable light
-	static int builtAbleLightCount();
+	static int builtAbleLightCount(QGLContext* pContext);
 
 	//! Return a GLC_Point3d representing light position
 	inline GLC_Point3d position(void) const
@@ -139,8 +143,8 @@ public:
 //@{
 //////////////////////////////////////////////////////////////////////
 public:
-	//! Init Max number of light
-	static void init();
+	//! Init Max number of light for this light context
+	void initForThisContext();
 
 	//! Set lihgt's position by a point
 	void setPosition(const GLC_Point3d &pos);
@@ -185,16 +189,12 @@ public:
 //@{
 //////////////////////////////////////////////////////////////////////
 public:
-	//! Enable the light
-	inline void enable() const
-	{glEnable(m_LightID);}
 
 	// Disable the light
-	inline void disable() const
-	{glDisable(m_LightID);}
+	void disable();
 
 	//! Execute OpenGL light
-	virtual void glExecute(GLenum Mode= GL_COMPILE_AND_EXECUTE);
+	virtual void glExecute();
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -203,21 +203,23 @@ public:
 //////////////////////////////////////////////////////////////////////
 
 private:
-	//! OpenGL light set up
-	void glDraw();
 
-	//! Display List creation
-	void creationList(GLenum Mode);
-
-	//! Delete OpenGL Display list
-	void deleteList();
 
 //@}
 
+//////////////////////////////////////////////////////////////////////
+// Private services fonction
+//////////////////////////////////////////////////////////////////////
+private:
+	//! Add context new light
+	void addNewLight();
+
+	//! Remove contetx light
+	void removeThisLight();
+
 //////////////////////////////////////////////////////////////////////
 // Private Members
 //////////////////////////////////////////////////////////////////////
-
 private:
 	//! OpenGL light ID
 	GLenum m_LightID;
@@ -225,12 +227,6 @@ private:
 	//! The Light type
 	LightType m_LightType;
 
-	//! OpenGL Display list ID
-	GLuint m_ListID;
-
-	//! OpenGL list validity
-	bool m_ListIsValid;
-
 	//! Light ambiant color
 	QColor m_AmbientColor;
 	//! Light diffuse color
@@ -266,7 +262,13 @@ private:
 	//! Maximum number of light
 	static GLint m_MaxLight;
 
-	//! Free light set
-	static QSet<GLenum> m_FreeLightSet;
+	//! The context of this light
+	QGLContext* m_pContext;
+
+	//! Flag to know if this light is valid
+	bool m_IsValid;
+
+	//! Mapping between context and light set
+	static QHash<const QGLContext*, QSet<GLenum> > m_ContextToFreeLightSet;
 };
 #endif //GLC_LIGHT_H_
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_material.cpp b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_material.cpp
index 412a00008..a60e1b94c 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_material.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_material.cpp
@@ -25,6 +25,7 @@
 #include "glc_material.h"
 #include "../geometry/glc_geometry.h"
 #include "../glc_factory.h"
+#include "../glc_openglexception.h"
 
 #include <QtDebug>
 
@@ -100,8 +101,8 @@ GLC_Material::GLC_Material(const QString& name ,const GLfloat *pDiffuseColor)
 	// Others
 	initOtherColor();
 }
-GLC_Material::GLC_Material(GLC_Texture* pTexture, const char *pName)
-:GLC_Object(pName)
+GLC_Material::GLC_Material(GLC_Texture* pTexture, const QString& name)
+:GLC_Object(name)
 , m_AmbientColor()
 , m_DiffuseColor()
 , m_SpecularColor()
@@ -460,11 +461,15 @@ void GLC_Material::setOpacity(const qreal alpha)
 //////////////////////////////////////////////////////////////////////
 
 // Load the texture
-void GLC_Material::glLoadTexture(void)
+void GLC_Material::glLoadTexture(QGLContext* pContext)
 {
 	if (m_pTexture != NULL)
 	{
-		m_pTexture->glLoadTexture();
+		m_pTexture->glLoadTexture(pContext);
+	}
+	else
+	{
+		qDebug() << "GLC_Material::glLoadTexture : Material without texture !";
 	}
 }
 
@@ -492,9 +497,10 @@ void GLC_Material::glExecute()
 								emissiveColor().blueF(),
 								emissiveColor().alphaF()};
 
+	const bool textureIsEnable= glIsEnabled(GL_TEXTURE_2D);
 	if (m_pTexture != NULL)
 	{
-		glEnable(GL_TEXTURE_2D);
+		if (!textureIsEnable) glEnable(GL_TEXTURE_2D);
 		m_pTexture->glcBindTexture();
 		if (GLC_State::glslUsed())
 		{
@@ -511,13 +517,13 @@ void GLC_Material::glExecute()
 
 		if (GLC_State::glslUsed() && GLC_Shader::hasActiveShader())
 		{
-				glEnable(GL_TEXTURE_2D);
+				if (!textureIsEnable) glEnable(GL_TEXTURE_2D);
 				GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("tex", GLint(0));
 				GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("useTexture", false);
 		}
 		else
 		{
-			glDisable(GL_TEXTURE_2D);
+			if (textureIsEnable) glDisable(GL_TEXTURE_2D);
 		}
 
 	}
@@ -530,14 +536,15 @@ void GLC_Material::glExecute()
 
 	glColor4fv(pDiffuseColor);
 
+
 	// OpenGL Error handler
-	GLenum errCode;
-	if ((errCode= glGetError()) != GL_NO_ERROR)
+	GLenum error= glGetError();
+	if (error != GL_NO_ERROR)
 	{
-		const GLubyte* errString;
-		errString = gluErrorString(errCode);
-		qDebug("GLC_Material::GlExecute OpenGL Error %s", errString);
+		GLC_OpenGlException OpenGlException("GLC_Material::glExecute() ", error);
+		throw(OpenGlException);
 	}
+
 }
 
 // Execute OpenGL Material
@@ -563,9 +570,11 @@ void GLC_Material::glExecute(float overwriteTransparency)
 								emissiveColor().blueF(),
 								overwriteTransparency};
 
+	const bool textureIsEnable= glIsEnabled(GL_TEXTURE_2D);
+
 	if (m_pTexture != NULL)
 	{
-		glEnable(GL_TEXTURE_2D);
+		if (!textureIsEnable) glEnable(GL_TEXTURE_2D);
 		m_pTexture->glcBindTexture();
 		if (GLC_State::glslUsed())
 		{
@@ -578,7 +587,7 @@ void GLC_Material::glExecute(float overwriteTransparency)
 	}
 	else
 	{
-		glDisable(GL_TEXTURE_2D);
+		if (textureIsEnable) glDisable(GL_TEXTURE_2D);
 		if (GLC_State::glslUsed())
 		{
 			if (GLC_Shader::hasActiveShader())
@@ -598,12 +607,11 @@ void GLC_Material::glExecute(float overwriteTransparency)
 	glColor4fv(pDiffuseColor);
 
 	// OpenGL Error handler
-	GLenum errCode;
-	if ((errCode= glGetError()) != GL_NO_ERROR)
+	GLenum error= glGetError();
+	if (error != GL_NO_ERROR)
 	{
-		const GLubyte* errString;
-		errString = gluErrorString(errCode);
-		qDebug("GLC_Material::glExecute(float) OpenGL Error %s", errString);
+		GLC_OpenGlException OpenGlException("GLC_Material::glExecute(float overwriteTransparency) ", error);
+		throw(OpenGlException);
 	}
 }
 
@@ -687,7 +695,7 @@ QDataStream &operator>>(QDataStream &stream, GLC_Material &material)
 	stream >> hasTexture;
 	if (hasTexture)
 	{
-		GLC_Texture texture(GLC_Factory::instance()->context());
+		GLC_Texture texture;
 		stream >> texture;
 		material.setTexture(new GLC_Texture(texture));
 	}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_material.h b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_material.h
index 759f3953a..668b47aae 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_material.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_material.h
@@ -68,7 +68,7 @@ public:
 	GLC_Material(const QString& name, const GLfloat *);
 
 	//! Construct textured GLC_Material
-	GLC_Material(GLC_Texture* pTexture, const char *pName);
+	GLC_Material(GLC_Texture* pTexture, const QString& name= QString());
 
 	//! Copy constructor
 	/*! Hast usage table are not copying
@@ -215,7 +215,7 @@ public:
 public:
 
 	//! Load the texture
-	void glLoadTexture(void);
+	void glLoadTexture(QGLContext* pContext= NULL);
 
 	//! Execute OpenGL Material
 	virtual void glExecute();
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_renderproperties.cpp b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_renderproperties.cpp
index c6c974958..184bbc77c 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_renderproperties.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_renderproperties.cpp
@@ -178,7 +178,7 @@ bool GLC_RenderProperties::needToRenderWithTransparency() const
 		Q_ASSERT(NULL != m_pOverwriteMaterial);
 		renderWithTransparency= m_pOverwriteMaterial->isTransparent();
 	}
-	else if (m_RenderMode == glc::OverwriteTransparency)
+	else if ((m_RenderMode == glc::OverwriteTransparency) || (m_RenderMode == glc::OverwriteTransparencyAndMaterial))
 	{
 		Q_ASSERT(-1.0f != m_OverwriteOpacity);
 		renderWithTransparency= (m_OverwriteOpacity < 1.0f);
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_renderproperties.h b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_renderproperties.h
index 1b8c48e5d..40a23578c 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_renderproperties.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_renderproperties.h
@@ -43,6 +43,7 @@ namespace glc
 		NormalRenderMode,
 		OverwriteMaterial,
 		OverwriteTransparency,
+		OverwriteTransparencyAndMaterial,
 		PrimitiveSelected,
 		OverwritePrimitiveMaterial,
 		BodySelection,
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_selectionmaterial.cpp b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_selectionmaterial.cpp
index ff27e1e39..7b341e5d7 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_selectionmaterial.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_selectionmaterial.cpp
@@ -21,10 +21,13 @@
 *****************************************************************************/
 //! \file glc_selectionmaterial.cpp implementation of the GLC_SelectionMaterial class.
 
+#include <QGLContext>
+
 #include "glc_selectionmaterial.h"
 #include "glc_material.h"
 
-GLC_Shader* GLC_SelectionMaterial::m_pSelectionShader= NULL;
+
+QHash<const QGLContext*, GLC_Shader*> GLC_SelectionMaterial::m_SelectionShaderHash;
 GLC_uint GLC_SelectionMaterial::m_SelectionMaterialId= 0;
 GLC_Material* GLC_SelectionMaterial::m_pMaterial= NULL;
 
@@ -96,32 +99,82 @@ void GLC_SelectionMaterial::glExecute()
 	}
 }
 
-void GLC_SelectionMaterial::initShader()
+void GLC_SelectionMaterial::initShader(const QGLContext* pContext)
 {
-	if (m_pSelectionShader == NULL)
-	{
-		m_pSelectionShader= new GLC_Shader;
-	}
-	m_pSelectionShader->createAndCompileProgrammShader();
+	Q_ASSERT(m_SelectionShaderHash.contains(pContext));
+	m_SelectionShaderHash.value(pContext)->createAndCompileProgrammShader();
 }
 
-void GLC_SelectionMaterial::setShaders(QFile& vertex, QFile& fragment)
+void GLC_SelectionMaterial::setShaders(QFile& vertex, QFile& fragment, const QGLContext* pContext)
 {
-	if (m_pSelectionShader == NULL)
+	if (m_SelectionShaderHash.contains(pContext))
 	{
-		m_pSelectionShader= new GLC_Shader;
+		deleteShader(pContext);
+	}
+	GLC_Shader* pShader= new GLC_Shader;
+
+	pShader->setVertexAndFragmentShader(vertex, fragment);
+	m_SelectionShaderHash.insert(pContext, pShader);
+}
+
+
+void GLC_SelectionMaterial::useShader()
+{
+	QGLContext* pContext= const_cast<QGLContext*>(QGLContext::currentContext());
+	Q_ASSERT(NULL != pContext);
+	Q_ASSERT(pContext->isValid());
+	if(!m_SelectionShaderHash.contains(pContext))
+	{
+		Q_ASSERT(pContext->isSharing());
+		pContext= sharingContext(pContext);
+		Q_ASSERT(NULL != pContext);
 	}
 
-	m_pSelectionShader->setVertexAndFragmentShader(vertex, fragment);
+	m_SelectionShaderHash.value(pContext)->use();
+}
+
+void GLC_SelectionMaterial::unUseShader()
+{
+	QGLContext* pContext= const_cast<QGLContext*>(QGLContext::currentContext());
+	Q_ASSERT(NULL != pContext);
+	Q_ASSERT(pContext->isValid());
+	if(!m_SelectionShaderHash.contains(pContext))
+	{
+		Q_ASSERT(pContext->isSharing());
+		pContext= sharingContext(pContext);
+		Q_ASSERT(NULL != pContext);
+	}
+
+	m_SelectionShaderHash.value(pContext)->unuse();
+}
+
+//////////////////////////////////////////////////////////////////////
+// Private services fonction
+//////////////////////////////////////////////////////////////////////
+QGLContext* GLC_SelectionMaterial::sharingContext(const QGLContext* pContext)
+{
+	QGLContext* pSharingContext= NULL;
+	QHash<const QGLContext*, GLC_Shader*>::const_iterator iContext= m_SelectionShaderHash.constBegin();
+
+	while ((NULL == pSharingContext) && (iContext != m_SelectionShaderHash.constEnd()))
+	{
+		const QGLContext* pCurrentContext= iContext.key();
+		if (QGLContext::areSharing(pContext, pCurrentContext))
+		{
+			pSharingContext= const_cast<QGLContext*>(pCurrentContext);
+		}
+		++iContext;
+	}
+
+	return pSharingContext;
 }
 
 //! delete shader
-void GLC_SelectionMaterial::deleteShader()
+void GLC_SelectionMaterial::deleteShader(const QGLContext* pContext)
 {
-	if (NULL != m_pSelectionShader)
-	{
-		m_pSelectionShader->deleteShader();
-		delete m_pSelectionShader;
-		m_pSelectionShader= NULL;
-	}
+	Q_ASSERT(m_SelectionShaderHash.contains(pContext));
+	GLC_Shader* pShader= m_SelectionShaderHash.value(pContext);
+	pShader->deleteShader();
+	delete pShader;
+	m_SelectionShaderHash.remove(pContext);
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_selectionmaterial.h b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_selectionmaterial.h
index 56a929541..01fd89f4d 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_selectionmaterial.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_selectionmaterial.h
@@ -26,11 +26,14 @@
 
 #include <QColor>
 #include <QtOpenGL>
+#include <QHash>
+
 #include "../glc_ext.h"
 #include "glc_shader.h"
 
 #include "../glc_config.h"
 
+class QGLContext;
 class GLC_Material;
 
 //////////////////////////////////////////////////////////////////////
@@ -67,25 +70,32 @@ public:
 	//! Execute OpenGL Material
 	static void glExecute();
 	//! Init shader
-	static void initShader();
+	static void initShader(const QGLContext* pContext);
 	//! delete shader
-	static void deleteShader();
+	static void deleteShader(const QGLContext* pContext);
 	//! Set shader
-	static void setShaders(QFile& vertex, QFile& fragment);
+	static void setShaders(QFile& vertex, QFile& fragment, const QGLContext* pContext);
 	//! Use shader
-	inline static void useShader() {m_pSelectionShader->use();}
+	static void useShader();
 	//! Unused shader
-	inline static void unUseShader() {m_pSelectionShader->unuse();}
+	static void unUseShader();
 
 //@}
 
+//////////////////////////////////////////////////////////////////////
+// Private services fonction
+//////////////////////////////////////////////////////////////////////
+private:
+	//! Return the sharing context of the given context
+	static QGLContext* sharingContext(const QGLContext* pContext);
+
 //////////////////////////////////////////////////////////////////////
 // Private members
 //////////////////////////////////////////////////////////////////////
 
 private:
 		//! Selection Shader
-		static GLC_Shader* m_pSelectionShader;
+		static QHash<const QGLContext*, GLC_Shader*> m_SelectionShaderHash;
 
 		//! Selection material id
 		static GLC_uint m_SelectionMaterialId;
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_shader.cpp b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_shader.cpp
index e91352efa..437a18886 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_shader.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_shader.cpp
@@ -27,6 +27,8 @@
 #include <QMutexLocker>
 #include "../glc_exception.h"
 #include "../glc_state.h"
+#include "../glc_context.h"
+#include "glc_light.h"
 
 // Static member initialization
 QStack<GLC_uint> GLC_Shader::m_ShadingGroupStack;
@@ -39,7 +41,26 @@ GLC_Shader::GLC_Shader()
 , m_ProgramShader()
 , m_ProgramShaderId(glc::GLC_GenShaderGroupID())
 , m_Name("Empty Shader")
+, m_PositionAttributeId(-1)
+, m_TextcoordAttributeId(-1)
+, m_ColorAttributeId(-1)
+, m_NormalAttributeId(-1)
+, m_ModelViewLocationId(-1)
+, m_MvpLocationId(-1)
+, m_InvModelViewLocationId(-1)
+, m_EnableLightingId(-1)
+, m_LightsEnableStateId(-1)
+, m_LightsPositionId()
+, m_LightsAmbientColorId()
+, m_LightsDiffuseColorId()
+, m_LightsSpecularColorId()
+, m_LightsSpotDirectionId()
+, m_LightsAttenuationFactorsId()
+, m_LightsSpotExponentId()
+, m_LightsSpotCutoffAngleId()
+, m_LightsComputeDistanceAttenuationId()
 {
+	initLightsUniformId();
 	m_ShaderProgramHash.insert(m_ProgramShaderId, this);
 }
 
@@ -49,7 +70,26 @@ GLC_Shader::GLC_Shader(QFile& vertex, QFile& fragment)
 , m_ProgramShader()
 , m_ProgramShaderId(glc::GLC_GenShaderGroupID())
 , m_Name("Empty Shader")
+, m_PositionAttributeId(-1)
+, m_TextcoordAttributeId(-1)
+, m_ColorAttributeId(-1)
+, m_NormalAttributeId(-1)
+, m_ModelViewLocationId(-1)
+, m_MvpLocationId(-1)
+, m_InvModelViewLocationId(-1)
+, m_EnableLightingId(-1)
+, m_LightsEnableStateId(-1)
+, m_LightsPositionId()
+, m_LightsAmbientColorId()
+, m_LightsDiffuseColorId()
+, m_LightsSpecularColorId()
+, m_LightsSpotDirectionId()
+, m_LightsAttenuationFactorsId()
+, m_LightsSpotExponentId()
+, m_LightsSpotCutoffAngleId()
+, m_LightsComputeDistanceAttenuationId()
 {
+	initLightsUniformId();
 	m_ShaderProgramHash.insert(m_ProgramShaderId, this);
 	setVertexAndFragmentShader(vertex, fragment);
 }
@@ -60,7 +100,26 @@ GLC_Shader::GLC_Shader(const GLC_Shader& shader)
 , m_ProgramShader()
 , m_ProgramShaderId(glc::GLC_GenShaderGroupID())
 , m_Name(shader.m_Name)
+, m_PositionAttributeId(-1)
+, m_TextcoordAttributeId(-1)
+, m_ColorAttributeId(-1)
+, m_NormalAttributeId(-1)
+, m_ModelViewLocationId(-1)
+, m_MvpLocationId(-1)
+, m_InvModelViewLocationId(-1)
+, m_EnableLightingId(-1)
+, m_LightsEnableStateId(-1)
+, m_LightsPositionId()
+, m_LightsAmbientColorId()
+, m_LightsDiffuseColorId()
+, m_LightsSpecularColorId()
+, m_LightsSpotDirectionId()
+, m_LightsAttenuationFactorsId()
+, m_LightsSpotExponentId()
+, m_LightsSpotCutoffAngleId()
+, m_LightsComputeDistanceAttenuationId()
 {
+	initLightsUniformId();
 	m_ShaderProgramHash.insert(m_ProgramShaderId, this);
 
 	if (shader.m_VertexShader.isCompiled())
@@ -130,11 +189,12 @@ void GLC_Shader::use()
 	{
 		m_CurrentShadingGroupId= m_ProgramShaderId;
 		m_ShaderProgramHash.value(m_CurrentShadingGroupId)->m_ProgramShader.bind();
+		GLC_Context::current()->updateUniformVariables();
 	}
 
 }
 
-bool GLC_Shader::use(GLuint shaderId)
+bool GLC_Shader::use(GLC_uint shaderId)
 {
 	Q_ASSERT(0 != shaderId);
 	if (GLC_State::isInSelectionMode()) return false;
@@ -147,7 +207,9 @@ bool GLC_Shader::use(GLuint shaderId)
 		{
 			m_CurrentShadingGroupId= shaderId;
 			m_ShaderProgramHash.value(m_CurrentShadingGroupId)->m_ProgramShader.bind();
+			GLC_Context::current()->updateUniformVariables();
 		}
+
 		return true;
 	}
 	else
@@ -178,6 +240,7 @@ void GLC_Shader::unuse()
 
 void GLC_Shader::createAndCompileProgrammShader()
 {
+	qDebug() << "GLC_Shader::createAndCompileProgrammShader()";
 	m_ProgramShader.addShader(&m_VertexShader);
 	m_ProgramShader.addShader(&m_FragmentShader);
 
@@ -187,6 +250,52 @@ void GLC_Shader::createAndCompileProgrammShader()
 		GLC_Exception exception(message);
 		throw(exception);
 	}
+	else
+	{
+		m_PositionAttributeId= m_ProgramShader.attributeLocation("a_position");
+		//qDebug() << "m_PositionAttributeId " << m_PositionAttributeId;
+		m_TextcoordAttributeId= m_ProgramShader.attributeLocation("a_textcoord0");
+		//qDebug() << "m_TextcoordAttributeId " << m_TextcoordAttributeId;
+		m_ColorAttributeId= m_ProgramShader.attributeLocation("a_color");
+		//qDebug() << "m_ColorAttributeId " << m_ColorAttributeId;
+		m_NormalAttributeId= m_ProgramShader.attributeLocation("a_normal");
+		//qDebug() << "m_NormalAttributeId " << m_NormalAttributeId;
+
+		m_ModelViewLocationId= m_ProgramShader.uniformLocation("modelview_matrix");
+		//qDebug() << "m_ModelViewLocationId " << m_ModelViewLocationId;
+		m_MvpLocationId= m_ProgramShader.uniformLocation("mvp_matrix");
+		//qDebug() << "m_MvpLocationId " << m_MvpLocationId;
+		m_InvModelViewLocationId= m_ProgramShader.uniformLocation("inv_modelview_matrix");
+		//qDebug() << "m_InvModelViewLocationId " << m_InvModelViewLocationId;
+		m_EnableLightingId= m_ProgramShader.uniformLocation("enable_lighting");
+		//qDebug() << "m_EnableLightingId " << m_EnableLightingId;
+		m_LightsEnableStateId= m_ProgramShader.uniformLocation("light_enable_state");
+		//qDebug() << "m_LightsEnableStateId " << m_LightsEnableStateId;
+		const int size= GLC_Light::maxLightCount();
+		for (int i= (GL_LIGHT0); i < (size + GL_LIGHT0); ++i)
+		{
+			m_LightsPositionId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].position");
+			//qDebug() << "Position id " << m_LightsPositionId.value(i);
+			m_LightsAmbientColorId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].ambient_color");
+			//qDebug() << "m_LightsAmbientColorId " << m_LightsAmbientColorId.value(i);
+			m_LightsDiffuseColorId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].diffuse_color");
+			//qDebug() << "m_LightsDiffuseColorId " << m_LightsDiffuseColorId.value(i);
+			m_LightsSpecularColorId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].specular_color");
+			//qDebug() << "m_LightsSpecularColorId " << m_LightsSpecularColorId.value(i);
+			m_LightsSpotDirectionId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].spot_direction");
+			//qDebug() << "m_LightsSpotDirectionId " << m_LightsSpotDirectionId.value(i);
+			m_LightsAttenuationFactorsId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].attenuation_factors");
+			//qDebug() << "m_LightsAttenuationFactorsId " << m_LightsAttenuationFactorsId.value(i);
+			m_LightsSpotExponentId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].spot_exponent");
+			//qDebug() << "m_LightsSpotExponentId " << m_LightsSpotExponentId.value(i);
+			m_LightsSpotCutoffAngleId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].spot_cutoff_angle");
+			//qDebug() << "m_LightsSpotCutoffAngleId " << m_LightsSpotCutoffAngleId.value(i);
+			m_LightsComputeDistanceAttenuationId[i]= m_ProgramShader.uniformLocation("light_state[" + QString::number(i) + "].compute_distance_attenuation");
+			//qDebug() << "m_LightsComputeDistanceAttenuationId " << m_LightsComputeDistanceAttenuationId.value(i);
+
+
+		}
+	}
 }
 
 void GLC_Shader::deleteShader()
@@ -255,3 +364,29 @@ void GLC_Shader::replaceShader(const GLC_Shader& sourceShader)
 
 }
 
+void GLC_Shader::initLightsUniformId()
+{
+	m_LightsPositionId.clear();
+	m_LightsAmbientColorId.clear();
+	m_LightsDiffuseColorId.clear();
+	m_LightsSpecularColorId.clear();
+	m_LightsSpotDirectionId.clear();
+	m_LightsAttenuationFactorsId.clear();
+	m_LightsSpotExponentId.clear();
+	m_LightsSpotCutoffAngleId.clear();
+	m_LightsComputeDistanceAttenuationId.clear();
+
+	for (int i= 0; i < GLC_Light::maxLightCount(); ++i)
+	{
+		m_LightsPositionId.insert(GL_LIGHT0 + i, -1);
+		m_LightsAmbientColorId.insert(GL_LIGHT0 + i, -1);
+		m_LightsDiffuseColorId.insert(GL_LIGHT0 + i, -1);
+		m_LightsSpecularColorId.insert(GL_LIGHT0 + i, -1);
+		m_LightsSpotDirectionId.insert(GL_LIGHT0 + i, -1);
+		m_LightsAttenuationFactorsId.insert(GL_LIGHT0 + i, -1);
+		m_LightsSpotExponentId.insert(GL_LIGHT0 + i, -1);
+		m_LightsSpotCutoffAngleId.insert(GL_LIGHT0 + i, -1);
+		m_LightsComputeDistanceAttenuationId.insert(GL_LIGHT0 + i, -1);
+	}
+}
+
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_shader.h b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_shader.h
index fac9dc79a..a08cc550c 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_shader.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_shader.h
@@ -32,6 +32,7 @@
 #include <QFile>
 #include <QMutex>
 #include <QString>
+#include <QMap>
 
 #include "../glc_config.h"
 
@@ -89,6 +90,22 @@ public:
 	inline QGLShaderProgram* programShaderHandle()
 	{return &m_ProgramShader;}
 
+	//! Return the position attribute id
+	inline int positionAttributeId() const
+	{return m_PositionAttributeId;}
+
+	//! Return the texture coordinate attribute id
+	inline int textureAttributeId() const
+	{return m_TextcoordAttributeId;}
+
+	//! Return the color attribute id
+	inline int colorAttributeId() const
+	{return m_ColorAttributeId;}
+
+	//! Return the normal attribute id
+	inline int normalAttributeId() const
+	{return m_NormalAttributeId;}
+
 	//! Return the number of shader
 	static int shaderCount();
 
@@ -130,6 +147,62 @@ public:
 	inline void setName(const QString& name)
 	{m_Name= name;}
 
+	//! Return the modelView location id
+	inline int modelViewLocationId() const
+	{return m_ModelViewLocationId;}
+
+	//! Return the modelView Projection matrix id
+	inline int mvpLocationId() const
+	{return m_MvpLocationId;}
+
+	//! Return the inverse modelView location id
+	inline int invModelViewLocationId() const
+	{return m_InvModelViewLocationId;}
+
+	//! Return the enable lighting location id
+	inline int enableLightingId() const
+	{return m_EnableLightingId;}
+
+	//! Return the lights enable state id
+	inline int lightsEnableStateId() const
+	{return m_LightsEnableStateId;}
+
+	//! Return the light position id of the given light id
+	inline int lightPositionId(GLenum lightId) const
+	{return m_LightsPositionId.value(lightId);}
+
+	//! Return the light ambient color id of the given light id
+	inline int lightAmbientColorId(GLenum lightId) const
+	{return m_LightsAmbientColorId.value(lightId);}
+
+	//! Return the light diffuse color id of the given light id
+	inline int lightDiffuseColorId(GLenum lightId) const
+	{return m_LightsDiffuseColorId.value(lightId);}
+
+	//! Return the light specular color id of the given light id
+	inline int lightSpecularColorId(GLenum lightId) const
+	{return m_LightsSpecularColorId.value(lightId);}
+
+	//! Return the light spot direction id of the given light id
+	inline int lightSpotDirectionId(GLenum lightId) const
+	{return m_LightsSpotDirectionId.value(lightId);}
+
+	//! Return the light attenuation factors id of the given light id
+	inline int lightAttebuationFactorsId(GLenum lightId) const
+	{return m_LightsAttenuationFactorsId.value(lightId);}
+
+	//! Return the light spot exponent id of the given light id
+	inline int lightSpotExponentId(GLenum lightId) const
+	{return m_LightsSpotExponentId.value(lightId);}
+
+	//! Return the light spot cutoff id of the given light id
+	inline int lightSpotCutoffId(GLenum lightId) const
+	{return m_LightsSpotCutoffAngleId.value(lightId);}
+
+	//! Return the light compute distance attenuation id of the given light id
+	inline int lightComputeDistanceAttenuationId(GLenum lightId) const
+	{return m_LightsComputeDistanceAttenuationId.value(lightId);}
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -143,7 +216,7 @@ public:
 
 	//! Use specified program shader
 	/*! Return true if the given shading group id is usable*/
-	static bool use(GLuint ShadingGroupId);
+	static bool use(GLC_uint ShadingGroupId);
 
 	//! unuse programm shader
 	static void unuse();
@@ -156,6 +229,12 @@ public:
 	void deleteShader();
 //@}
 
+//////////////////////////////////////////////////////////////////////
+// private services function
+//////////////////////////////////////////////////////////////////////
+private:
+	//! Init light uniform id
+	void initLightsUniformId();
 //////////////////////////////////////////////////////////////////////
 // private members
 //////////////////////////////////////////////////////////////////////
@@ -184,6 +263,60 @@ private:
 	//! The Shader's name
 	QString m_Name;
 
+	//! The position attribute id
+	int m_PositionAttributeId;
+
+	//! The Texture coordinate attribute id
+	int m_TextcoordAttributeId;
+
+	//! The color attribute id
+	int m_ColorAttributeId;
+
+	//! The Normal attribute id
+	int m_NormalAttributeId;
+
+	//! The modelView location matrix id
+	int m_ModelViewLocationId;
+
+	//! The modelView Projection matrix id
+	int m_MvpLocationId;
+
+	//! The inverse modelView location id
+	int m_InvModelViewLocationId;
+
+	//! The enable lighting id
+	int m_EnableLightingId;
+
+	//! Lights enable states id
+	int m_LightsEnableStateId;
+
+	//! Lights positions id
+	QMap<GLenum, int> m_LightsPositionId;
+
+	//! Lights ambient color id
+	QMap<GLenum, int> m_LightsAmbientColorId;
+
+	//! Lights diffuse color id
+	QMap<GLenum, int> m_LightsDiffuseColorId;
+
+	//! Lights specular color id
+	QMap<GLenum, int> m_LightsSpecularColorId;
+
+	//! Lights spot direction id
+	QMap<GLenum, int> m_LightsSpotDirectionId;
+
+	//! Lights attenuation factors id
+	QMap<GLenum, int> m_LightsAttenuationFactorsId;
+
+	//! Lights spot exponent id
+	QMap<GLenum, int> m_LightsSpotExponentId;
+
+	//! Lights spot cutoff angle id
+	QMap<GLenum, int> m_LightsSpotCutoffAngleId;
+
+	//! Lights compute distance attenuation
+	QMap<GLenum, int> m_LightsComputeDistanceAttenuationId;
+
 };
 
 #endif /*GLC_SHADER_H_*/
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_texture.cpp b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_texture.cpp
index ea1b5a8d8..be525d55e 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_texture.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_texture.cpp
@@ -46,8 +46,8 @@ QHash<GLuint, int> GLC_Texture::m_TextureIdUsage;
 //////////////////////////////////////////////////////////////////////
 
 //! Default constructor
-GLC_Texture::GLC_Texture(const QGLContext *pContext)
-: m_pQGLContext(const_cast<QGLContext*>(pContext))
+GLC_Texture::GLC_Texture()
+: m_pQGLContext(NULL)
 , m_FileName()
 , m_GlTextureID(0)
 , m_textureImage()
@@ -58,8 +58,8 @@ GLC_Texture::GLC_Texture(const QGLContext *pContext)
 }
 
 // Constructor with fileName
-GLC_Texture::GLC_Texture(const QGLContext *pContext, const QString &Filename)
-: m_pQGLContext(const_cast<QGLContext*>(pContext))
+GLC_Texture::GLC_Texture(const QString &Filename)
+: m_pQGLContext(NULL)
 , m_FileName(Filename)
 , m_GlTextureID(0)
 , m_textureImage(loadFromFile(m_FileName))
@@ -76,8 +76,8 @@ GLC_Texture::GLC_Texture(const QGLContext *pContext, const QString &Filename)
 	}
 }
 // Constructor with QFile
-GLC_Texture::GLC_Texture(const QGLContext *pContext, const QFile &file)
-: m_pQGLContext(const_cast<QGLContext*>(pContext))
+GLC_Texture::GLC_Texture(const QFile &file)
+: m_pQGLContext(NULL)
 , m_FileName(file.fileName())
 , m_GlTextureID(0)
 , m_textureImage()
@@ -96,8 +96,8 @@ GLC_Texture::GLC_Texture(const QGLContext *pContext, const QFile &file)
 }
 
 // Constructor with QImage
-GLC_Texture::GLC_Texture(const QGLContext* pContext, const QImage& image, const QString& fileName)
-: m_pQGLContext(const_cast<QGLContext*>(pContext))
+GLC_Texture::GLC_Texture(const QImage& image, const QString& fileName)
+: m_pQGLContext(NULL)
 , m_FileName(fileName)
 , m_GlTextureID(0)
 , m_textureImage(image)
@@ -191,14 +191,19 @@ void GLC_Texture::setMaxTextureSize(const QSize& size)
 // Private OpenGL functions
 //////////////////////////////////////////////////////////////////////
 // Load the texture
-void GLC_Texture::glLoadTexture(void)
+void GLC_Texture::glLoadTexture(QGLContext* pContext)
 {
 	if (m_GlTextureID == 0)
 	{
-		if (NULL == m_pQGLContext)
+		if (NULL == pContext)
 		{
 			m_pQGLContext= const_cast<QGLContext*>(QGLContext::currentContext());
 		}
+		else
+		{
+			m_pQGLContext= pContext;
+		}
+
 		// Test image size
 		if ((m_textureImage.height() > m_MaxTextureSize.height())
 				|| (m_textureImage.width() > m_MaxTextureSize.width()))
@@ -329,7 +334,7 @@ QDataStream &operator>>(QDataStream &stream, GLC_Texture &texture)
 {
 	QString fileName;
 	stream >> fileName;
-	texture= GLC_Texture(texture.context(), fileName);
+	texture= GLC_Texture(fileName);
 
 	return stream;
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_texture.h b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_texture.h
index 84ffa3d45..86d1c52de 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/shading/glc_texture.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/glc_texture.h
@@ -47,16 +47,16 @@ class GLC_LIB_EXPORT GLC_Texture
 
 public:
 	//! Default constructor
-	GLC_Texture(const QGLContext*);
+	GLC_Texture();
 
 	//! Constructor with fileName
-	GLC_Texture(const QGLContext*, const QString&);
+	GLC_Texture(const QString&);
 
 	//! Constructor with QFile
-	GLC_Texture(const QGLContext*, const QFile&);
+	GLC_Texture(const QFile&);
 
 	//! Constructor with QImage
-	GLC_Texture(const QGLContext*, const QImage&, const QString& fileName= QString());
+	GLC_Texture(const QImage&, const QString& fileName= QString());
 
 	//! Copy constructor
 	GLC_Texture(const GLC_Texture& TextureToCopy);
@@ -126,7 +126,7 @@ public:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Load the texture
-	void glLoadTexture(void);
+	void glLoadTexture(QGLContext* pContext= NULL);
 	//! Bind texture in 2D mode
 	void glcBindTexture(void);
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/shaders/default.frag b/ground/openpilotgcs/src/libs/glc_lib/shading/shaders/default.frag
new file mode 100644
index 000000000..e69de29bb
diff --git a/ground/openpilotgcs/src/libs/glc_lib/shading/shaders/default.vert b/ground/openpilotgcs/src/libs/glc_lib/shading/shaders/default.vert
new file mode 100644
index 000000000..30044d866
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/shading/shaders/default.vert
@@ -0,0 +1,12 @@
+uniform mat4 modelview_matrix;
+uniform mat4 mvp_matrix;
+
+attribute vec4 a_position;
+attribute vec4 a_textcoord0;
+attribute vec4 a_color;
+attribute vec3 a_normal;
+
+void main()
+{
+	gl_Position= mvp_matrix * a_position;	
+}
\ No newline at end of file
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_camera.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_camera.cpp
index 937b3c3ce..c830a83c6 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_camera.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_camera.cpp
@@ -24,20 +24,7 @@
 //! \file glc_camera.cpp Implementation of the GLC_Camera class.
 
 #include "glc_camera.h"
-
-#if defined(Q_OS_MAC)
-#include "gl.h"
-#include "glu.h"
-#endif
-
-#if defined(Q_OS_WIN32)
-#include "GL/gl.h"
-#include "GL/glu.h"
-#endif
-
-#if defined(Q_OS_LINUX)
-#include "GL/glu.h"
-#endif
+#include "../glc_context.h"
 
 #include <QtDebug>
 
@@ -276,7 +263,7 @@ GLC_Camera& GLC_Camera::setCam(GLC_Point3d Eye, GLC_Point3d Target, GLC_Vector3d
 	//Q_ASSERT((Angle > EPSILON) && ((PI - Angle) > EPSILON));
 
 	if ( !qFuzzyCompare(Angle - (PI / 2), 0.0))
-	{	// Angle not equal to 90�
+	{	// Angle not equal to 90
 		const GLC_Vector3d AxeRot(VectCam ^ Up);
 		GLC_Matrix4x4 MatRot(AxeRot, PI / 2);
 		Up= MatRot * VectCam;
@@ -445,9 +432,7 @@ GLC_Camera GLC_Camera::isoView() const
 //////////////////////////////////////////////////////////////////////
 void GLC_Camera::glExecute()
 {
-	gluLookAt(m_Eye.x(), m_Eye.y(), m_Eye.z(),
-		m_Target.x(), m_Target.y(), m_Target.z(),
-		m_VectUp.x(), m_VectUp.y(), m_VectUp.z());
+	GLC_Context::current()->glcMultMatrix(modelViewMatrix());
 }
 
 //////////////////////////////////////////////////////////////////////
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_flymover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_flymover.cpp
index 0965c09ed..abda923bc 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_flymover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_flymover.cpp
@@ -68,10 +68,10 @@ GLC_Mover* GLC_FlyMover::clone() const
 //Set Functions
 //////////////////////////////////////////////////////////////////////
 
-void GLC_FlyMover::init(QMouseEvent * e)
+void GLC_FlyMover::init(const GLC_UserInput& userInput)
 {
-	m_PreviousVector= mapForFlying(static_cast<double>(e->x()), static_cast<double>(e->y()));
-	GLC_Point3d point= m_pViewport->unProject(e->x(), e->y());
+	m_PreviousVector= mapForFlying(static_cast<double>(userInput.x()), static_cast<double>(userInput.y()));
+	GLC_Point3d point= m_pViewport->unProject(userInput.x(), userInput.y());
 	const double distance= (point - m_pViewport->cameraHandle()->eye()).length();
 	m_pViewport->cameraHandle()->setDistTargetEye(distance);
 	// 5 secondes to travel
@@ -83,10 +83,10 @@ void GLC_FlyMover::init(QMouseEvent * e)
 	m_TimerId= QObject::startTimer(m_TimerInterval);
 }
 
-bool GLC_FlyMover::move(QMouseEvent * e)
+bool GLC_FlyMover::move(const GLC_UserInput& userInput)
 {
-	m_PreviousVector= mapForFlying(static_cast<double>(e->x()), static_cast<double>(e->y()));
-	GLC_Point3d point= m_pViewport->unProject(e->x(), e->y());
+	m_PreviousVector= mapForFlying(static_cast<double>(userInput.x()), static_cast<double>(userInput.y()));
+	GLC_Point3d point= m_pViewport->unProject(userInput.x(), userInput.y());
 	const double distance= (point - m_pViewport->cameraHandle()->eye()).length();
 	m_pViewport->cameraHandle()->setDistTargetEye(distance);
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_flymover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_flymover.h
index 8ed298d51..cd8f569d5 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_flymover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_flymover.h
@@ -71,10 +71,10 @@ public:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Initialized the mover
-	virtual void init(QMouseEvent * e);
+	virtual void init(const GLC_UserInput& userInput);
 
 	//! Move the camera
-	virtual bool move(QMouseEvent * e);
+	virtual bool move(const GLC_UserInput& userInput);
 
 	//! Ends this mover
 	virtual void ends();
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_imageplane.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_imageplane.cpp
index 0e8077528..0f0e6eeca 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_imageplane.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_imageplane.cpp
@@ -25,26 +25,27 @@
 #include "glc_viewport.h"
 #include "../glc_openglexception.h"
 #include "../glc_factory.h"
+#include "../glc_context.h"
 #include <QtDebug>
 
 //////////////////////////////////////////////////////////////////////
 // Constructor Destructor
 //////////////////////////////////////////////////////////////////////
 
-GLC_ImagePlane::GLC_ImagePlane(const QGLContext *pContext, const QString& ImageName)
-: m_Material()
+GLC_ImagePlane::GLC_ImagePlane(const QString& ImageName)
+: m_Representation(GLC_Factory::instance()->createRectangle(2.0, 2.0))
 {
-	GLC_Texture* pImgTexture= GLC_Factory::instance(pContext)->createTexture(ImageName);
+	GLC_Texture* pImgTexture= GLC_Factory::instance()->createTexture(ImageName);
 	pImgTexture->setMaxTextureSize(pImgTexture->imageOfTexture().size());
-	m_Material.setTexture(pImgTexture);
+	m_Representation.geomAt(0)->addMaterial(new GLC_Material(pImgTexture));
 }
 
-GLC_ImagePlane::GLC_ImagePlane(const QGLContext *pContext, const QImage& image)
-: m_Material()
+GLC_ImagePlane::GLC_ImagePlane(const QImage& image)
+: m_Representation(GLC_Factory::instance()->createRectangle(2.0, 2.0))
 {
-	GLC_Texture* pImgTexture= GLC_Factory::instance(pContext)->createTexture(image);
+	GLC_Texture* pImgTexture= GLC_Factory::instance()->createTexture(image);
 	pImgTexture->setMaxTextureSize(image.size());
-	m_Material.setTexture(pImgTexture);
+	m_Representation.geomAt(0)->addMaterial(new GLC_Material(pImgTexture));
 }
 
 GLC_ImagePlane::~GLC_ImagePlane()
@@ -58,34 +59,22 @@ GLC_ImagePlane::~GLC_ImagePlane()
 
 void GLC_ImagePlane::render()
 {
-	m_Material.glExecute();
-	// Display info area
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadIdentity();
-	glOrtho(-1,1,-1,1,-1,1);
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadIdentity();
+	GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
+	GLC_Context::current()->glcPushMatrix();
+	GLC_Context::current()->glcLoadIdentity();
+	GLC_Context::current()->glcOrtho(-1,1,-1,1,-1,1);
+	GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);
 
 	glDisable(GL_BLEND);
 	glDisable(GL_DEPTH_TEST);
 	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
-	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-	glBegin(GL_QUADS);
 
-		glNormal3d(0.0, 0.0, 1.0);	// Z
-		glTexCoord2f(0.0f, 0.0f); glVertex3d(-1.0, -1.0, 0.0);
-		glTexCoord2f(1.0f, 0.0f); glVertex3d(1.0, -1.0, 0.0);
-		glTexCoord2f(1.0f, 1.0f); glVertex3d(1.0, 1.0, 0.0);
-		glTexCoord2f(0.0f, 1.0f); glVertex3d(-1.0, 1.0, 0.0);
+	m_Representation.render();
 
-	glEnd();
 	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 	glEnable(GL_DEPTH_TEST);
 
-	glPopMatrix();
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
+	GLC_Context::current()->glcPopMatrix();
+	GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_imageplane.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_imageplane.h
index db5411e4d..51ce957a2 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_imageplane.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_imageplane.h
@@ -26,6 +26,7 @@
 #define GLC_IMAGEPLANE_H_
 
 #include "../shading/glc_material.h"
+#include "../sceneGraph/glc_3dviewinstance.h"
 
 #include "../glc_config.h"
 
@@ -44,10 +45,10 @@ class GLC_LIB_EXPORT GLC_ImagePlane
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Construct image plane from the given image file name and QGLContext
-	GLC_ImagePlane(const QGLContext *pContext, const QString& ImageName);
+	GLC_ImagePlane(const QString& ImageName);
 
 	//! Construct image plane from the given image and QGLContext
-	GLC_ImagePlane(const QGLContext *pContext, const QImage& image);
+	GLC_ImagePlane(const QImage& image);
 
 	~GLC_ImagePlane();
 //@}
@@ -67,8 +68,8 @@ public:
 
 private:
 
-	//! The image plane material
-	GLC_Material m_Material;
+	//! The image representation
+	GLC_3DViewInstance m_Representation;
 
 };
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_mover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_mover.h
index 3b81f20e1..047b2d8a2 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_mover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_mover.h
@@ -27,13 +27,13 @@
 
 #include "glc_repmover.h"
 #include "../maths/glc_vector3d.h"
+#include "glc_userinput.h"
 
 #include <QObject>
 #include <QList>
 
 #include "../glc_config.h"
 
-class QMouseEvent;
 class GLC_Viewport;
 
 //////////////////////////////////////////////////////////////////////
@@ -70,10 +70,10 @@ public:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Initialized the mover
-	virtual void init(QMouseEvent * e)= 0;
+	virtual void init(const GLC_UserInput& userInput)= 0;
 
 	//! Move the camera
-	virtual bool move(QMouseEvent * e)= 0;
+	virtual bool move(const GLC_UserInput& userInput)= 0;
 
 	//! Ends this mover
 	virtual void ends(){}
@@ -111,17 +111,12 @@ private:
 	//! Clear mover representation
 	void clearMoverRepresentation();
 
-//////////////////////////////////////////////////////////////////////
-// Private Members
-//////////////////////////////////////////////////////////////////////
-private:
-	//! The mover representations list
-	QList<GLC_RepMover*> m_RepMoverList;
-
 //////////////////////////////////////////////////////////////////////
 // Protected Members
 //////////////////////////////////////////////////////////////////////
 protected:
+	//! The mover representations list
+	QList<GLC_RepMover*> m_RepMoverList;
 
 	//! The previous mover value
 	GLC_Vector3d m_PreviousVector;
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_movercontroller.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_movercontroller.cpp
index b2c58db30..e1b684cd4 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_movercontroller.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_movercontroller.cpp
@@ -111,12 +111,12 @@ void GLC_MoverController::removeMover(const int id)
 	}
 }
 
-void GLC_MoverController::setActiveMover(const int id, QMouseEvent * e)
+void GLC_MoverController::setActiveMover(const int id, const GLC_UserInput& userInput)
 {
 	Q_ASSERT(m_MoverHash.contains(id));
 	m_ActiveMoverId= id;
 	connect(m_MoverHash.value(m_ActiveMoverId), SIGNAL(updated()), this, SIGNAL(repaintNeeded()));
-	m_MoverHash.value(m_ActiveMoverId)->init(e);
+	m_MoverHash.value(m_ActiveMoverId)->init(userInput);
 }
 
 void GLC_MoverController::setNoMover()
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_movercontroller.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_movercontroller.h
index af28d0cdd..08f8d4a28 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_movercontroller.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_movercontroller.h
@@ -31,9 +31,9 @@
 #include <QtDebug>
 
 #include "../glc_config.h"
+#include "glc_userinput.h"
 
 class QGLWidget;
-class QMouseEvent;
 
 //////////////////////////////////////////////////////////////////////
 //! \class GLC_MoverController
@@ -54,7 +54,8 @@ public:
 		TrackBall= 3,
 		Target= 4,
 		TurnTable= 5,
-		Fly= 6
+		Fly= 6,
+		TSR= 7
 	};
 
 public:
@@ -85,6 +86,10 @@ public:
 	inline GLC_Mover* activeMover() const
 	{return m_MoverHash.value(m_ActiveMoverId);}
 
+	//! Return the mover of the given id
+	inline GLC_Mover* getMover(const int id) const
+	{return m_MoverHash.value(id);}
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -102,16 +107,16 @@ public:
 	void removeMover(const int);
 
 	//! Set the specified mover as active
-	void setActiveMover(const int id, QMouseEvent * e);
+	void setActiveMover(const int id, const GLC_UserInput& userInput);
 
 	//! Set no mover as active
 	void setNoMover();
 
 	//! Move with the active mover
-	inline bool move(QMouseEvent * e)
+	inline bool move(const GLC_UserInput& userInput)
 	{
 		Q_ASSERT(0 != m_ActiveMoverId);
-		return m_MoverHash.value(m_ActiveMoverId)->move(e);
+		return m_MoverHash.value(m_ActiveMoverId)->move(userInput);
 	}
 
 //@}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_panmover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_panmover.cpp
index ad6964d0c..40c0e6d26 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_panmover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_panmover.cpp
@@ -62,15 +62,15 @@ GLC_Mover* GLC_PanMover::clone() const
 //////////////////////////////////////////////////////////////////////
 
 // Initialized the mover
-void GLC_PanMover::init(QMouseEvent * e)
+void GLC_PanMover::init(const GLC_UserInput& userInput)
 {
-	m_PreviousVector= m_pViewport->mapPosMouse(static_cast<double>(e->x()), static_cast<double>(e->y()));
+	m_PreviousVector= m_pViewport->mapPosMouse(static_cast<double>(userInput.x()), static_cast<double>(userInput.y()));
 }
 
 // Move the camera
-bool GLC_PanMover::move(QMouseEvent * e)
+bool GLC_PanMover::move(const GLC_UserInput& userInput)
 {
-	const GLC_Vector3d VectCur(m_pViewport->mapPosMouse(static_cast<double>(e->x()), static_cast<double>(e->y())));
+	const GLC_Vector3d VectCur(m_pViewport->mapPosMouse(static_cast<double>(userInput.x()), static_cast<double>(userInput.y())));
 	const GLC_Vector3d VectPan= VectCur - m_PreviousVector;	// moving Vector
 
 	// Pan the camera
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_panmover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_panmover.h
index 0b2cd1b3d..c7204f00b 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_panmover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_panmover.h
@@ -60,10 +60,10 @@ public:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Initialized the mover
-	virtual void init(QMouseEvent * e);
+	virtual void init(const GLC_UserInput& userInput);
 
 	//! Move the camera
-	virtual bool move(QMouseEvent * e);
+	virtual bool move(const GLC_UserInput& userInput);
 //@}
 
 };
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repcrossmover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repcrossmover.cpp
index ae835f6d3..c10d88f68 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repcrossmover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repcrossmover.cpp
@@ -22,6 +22,7 @@
 
 #include "glc_repcrossmover.h"
 #include "glc_viewport.h"
+#include "../geometry/glc_polylines.h"
 
 // Default constructor
 GLC_RepCrossMover::GLC_RepCrossMover(GLC_Viewport* pViewport)
@@ -59,6 +60,26 @@ GLC_RepMover* GLC_RepCrossMover::clone() const
 // Virtual interface for OpenGL Geometry set up.
 void GLC_RepCrossMover::glDraw()
 {
+	GLC_3DViewInstance crossInstance(createCrossInstance());
+
+	glDisable(GL_BLEND);
+	m_RenderProperties.setRenderingFlag(glc::WireRenderFlag);
+	crossInstance.render(glc::WireRenderFlag);
+
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	m_RenderProperties.setRenderingFlag(glc::TransparentRenderFlag);
+	// Display arcs
+	crossInstance.render(glc::TransparentRenderFlag);
+}
+
+//////////////////////////////////////////////////////////////////////
+// Private services Functions
+//////////////////////////////////////////////////////////////////////
+GLC_3DViewInstance GLC_RepCrossMover::createCrossInstance()
+{
+	GLC_Polylines* pCross= new GLC_Polylines();
+
 	int nLgAxe;
 	const int winHSize= m_pViewport->viewHSize();
 	const int winVSize= m_pViewport->viewVSize();
@@ -78,41 +99,48 @@ void GLC_RepCrossMover::glDraw()
 	// Axis length in OpenGL unit = length(Pixel) * (dimend GL / dimens Pixel)
 	const double dLgAxe= ((double)nLgAxe * ChampsVision / (double)winVSize) / 7;
 	const double dDecAxe= dLgAxe / 3;
-	glPushMatrix();
 
-	glTranslated(m_pViewport->cameraHandle()->target().x(), m_pViewport->cameraHandle()->target().y(),
-			m_pViewport->cameraHandle()->target().z() );
+	//X axis
+	{
+		GLC_Point3d p1(-dLgAxe, 0, 0);
+		GLC_Point3d p2(-dDecAxe, 0, 0);
+		GLC_Point3d p3(dDecAxe, 0, 0);
+		GLC_Point3d p4(dLgAxe, 0, 0);
+		QList<GLC_Point3d> points;
+		points << p1 << p2 << p3 << p4;
+		pCross->addPolyline(points);
+	}
 
-	// Graphic properties
-	glDisable(GL_TEXTURE_2D);
-	glDisable(GL_LIGHTING);
-	glColor4d(m_MainColor.redF(), m_MainColor.greenF(), m_MainColor.blueF(), m_MainColor.alphaF());
-	glLineWidth(1.0);
+	//Y axis
+	{
+		GLC_Point3d p1(0, -dLgAxe, 0);
+		GLC_Point3d p2(0, -dDecAxe, 0);
+		GLC_Point3d p3(0, dDecAxe, 0);
+		GLC_Point3d p4(0, dLgAxe, 0);
+		QList<GLC_Point3d> points;
+		points << p1 << p2 << p3 << p4;
+		pCross->addPolyline(points);
+	}
 
-	// Display camera's target lines
-	glBegin(GL_LINES);
-		//X axis
-		glVertex3d(-dLgAxe, 0, 0);
-		glVertex3d(-dDecAxe, 0, 0);
-		glVertex3d(dDecAxe, 0, 0);
-		glVertex3d(dLgAxe, 0, 0);
+	//Z axis
+	{
+		GLC_Point3d p1(0, 0, -dLgAxe);
+		GLC_Point3d p2(0, 0, -dDecAxe);
+		GLC_Point3d p3(0, 0, dDecAxe);
+		GLC_Point3d p4(0, 0, dLgAxe);
+		QList<GLC_Point3d> points;
+		points << p1 << p2 << p3 << p4;
+		pCross->addPolyline(points);
+	}
 
-		//Y axis
-		glVertex3d(0, -dLgAxe, 0);
-		glVertex3d(0, -dDecAxe, 0);
-		glVertex3d(0, dDecAxe, 0);
-		glVertex3d(0, dLgAxe, 0);
+	pCross->setWireColor(m_MainColor);
+	GLC_3DViewInstance crossInstance(pCross);
 
-		//Z axis
-		glVertex3d(0, 0, -dLgAxe);
-		glVertex3d(0, 0, -dDecAxe);
-		glVertex3d(0, 0, dDecAxe);
-		glVertex3d(0, 0, dLgAxe);
+	GLC_Matrix4x4 translation;
+	translation.setMatTranslate(m_pViewport->cameraHandle()->target());
 
-	glEnd();
-
-	glPopMatrix();
+	crossInstance.setMatrix(translation);
 
+	return crossInstance;
 }
 
-
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repcrossmover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repcrossmover.h
index 6f3c74b1d..8f570919f 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repcrossmover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repcrossmover.h
@@ -25,6 +25,8 @@
 
 #include "glc_repmover.h"
 
+#include "../sceneGraph/glc_3dviewinstance.h"
+
 #include "../glc_config.h"
 
 //////////////////////////////////////////////////////////////////////
@@ -61,6 +63,13 @@ public:
 
 //@}
 
+//////////////////////////////////////////////////////////////////////
+// Private services Functions
+//////////////////////////////////////////////////////////////////////
+private:
+	//! Create and return the cross instance
+	GLC_3DViewInstance createCrossInstance();
+
 };
 
 #endif /* GLC_REPCROSSMOVER_H_ */
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repflymover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repflymover.cpp
index f68abcb25..bf5bc3001 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repflymover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_repflymover.cpp
@@ -25,6 +25,8 @@
 #include "glc_repflymover.h"
 #include "glc_viewport.h"
 #include "../geometry/glc_polylines.h"
+#include "../glc_context.h"
+
 #include <QFontMetrics>
 
 GLC_RepFlyMover::GLC_RepFlyMover(GLC_Viewport* pViewport)
@@ -107,16 +109,16 @@ void GLC_RepFlyMover::glDraw()
 	const double vRatio= static_cast<double>(m_pViewport->viewVSize()) / calibre;
 
 	glDisable(GL_TEXTURE_2D);
-	glDisable(GL_LIGHTING);
+	GLC_Context::current()->glcEnableLighting(false);
 	glDisable(GL_DEPTH_TEST);
 
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadIdentity();
-	glOrtho(hRatio * -1.0 ,hRatio * 1.0 ,vRatio * -1.0 ,vRatio * 1.0 ,-1.0 ,1.0);
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadIdentity();
+	GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
+	GLC_Context::current()->glcPushMatrix();
+	GLC_Context::current()->glcLoadIdentity();
+	GLC_Context::current()->glcOrtho(hRatio * -1.0 ,hRatio * 1.0 ,vRatio * -1.0 ,vRatio * 1.0 ,-1.0 ,1.0);
+	GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);
+	GLC_Context::current()->glcPushMatrix();
+	GLC_Context::current()->glcLoadIdentity();
 
 	m_CenterCircle.render(glc::WireRenderFlag);
 	m_Hud.render(glc::WireRenderFlag);
@@ -138,10 +140,10 @@ void GLC_RepFlyMover::glDraw()
 	double posy= 2.0 * static_cast<double>(txtHeight) / calibre;
 	m_pViewport->qGLWidgetHandle()->renderText(- m_HudOffset.getX(), m_HudOffset.getY() - posy, 0.0, velocity, myFont);
 
-	glPopMatrix();
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
+	GLC_Context::current()->glcPopMatrix();
+	GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
+	GLC_Context::current()->glcPopMatrix();
+	GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);
 
 	glEnable(GL_DEPTH_TEST);
 }
@@ -152,7 +154,7 @@ void GLC_RepFlyMover::createRepresentation()
 	GLC_Circle* pCircle= new GLC_Circle(m_Radius);
 	pCircle->setWireColor(GLC_RepMover::m_MainColor);
 	pCircle->setLineWidth(GLC_RepMover::m_Thickness);
-	m_CenterCircle.setGeometry(pCircle);
+	m_CenterCircle.addGeometry(pCircle);
 
 	GLC_Polylines* pPolylines= new GLC_Polylines();
 	GLfloatVector  points;
@@ -167,7 +169,7 @@ void GLC_RepFlyMover::createRepresentation()
 	pPolylines->addPolyline(points);
 	pPolylines->setWireColor(GLC_RepMover::m_MainColor);
 	pPolylines->setLineWidth(GLC_RepMover::m_Thickness);
-	m_Hud.setGeometry(pPolylines);
+	m_Hud.addGeometry(pPolylines);
 
 	// Plane creation
 	pPolylines= new GLC_Polylines();
@@ -181,5 +183,5 @@ void GLC_RepFlyMover::createRepresentation()
 	pPolylines->addPolyline(points);
 	pPolylines->setWireColor(GLC_RepMover::m_MainColor);
 	pPolylines->setLineWidth(GLC_RepMover::m_Thickness);
-	m_Plane.setGeometry(pPolylines);
+	m_Plane.addGeometry(pPolylines);
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_reptrackballmover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_reptrackballmover.cpp
index 2a260cdbb..aac0d9ece 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_reptrackballmover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_reptrackballmover.cpp
@@ -25,6 +25,7 @@
 #include "glc_reptrackballmover.h"
 #include "glc_viewport.h"
 #include "../glc_factory.h"
+#include "../glc_context.h"
 #include <QGLContext>
 
 using namespace glc;
@@ -155,23 +156,18 @@ void GLC_RepTrackBallMover::glDraw()
 	computeRadius();
 	const double aspectRatio= static_cast<double>(m_pViewport->viewHSize())/static_cast<double>(m_pViewport->viewVSize());
 
-	// Save current state
-	GLboolean depthTest, blend;
-	glGetBooleanv(GL_DEPTH_TEST, &depthTest);
-	glGetBooleanv(GL_BLEND, &blend);
-
 	// orbit circle must be shown
-	if (depthTest) glDisable(GL_DEPTH_TEST);
+	glDisable(GL_DEPTH_TEST);
 
-	glMatrixMode(GL_PROJECTION);
-	glPushMatrix();
-	glLoadIdentity();
-	glOrtho(aspectRatio * -1.0 ,aspectRatio * 1.0 ,-1.0 ,1.0 ,-1.0 ,1.0);
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
-	glLoadIdentity();
+	GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
+	GLC_Context::current()->glcPushMatrix();
+	GLC_Context::current()->glcLoadIdentity();
+	GLC_Context::current()->glcOrtho(aspectRatio * -1.0 ,aspectRatio * 1.0 ,-1.0 ,1.0 ,-1.0 ,1.0);
+	GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);
+	GLC_Context::current()->glcPushMatrix();
+	GLC_Context::current()->glcLoadIdentity();
 
-	if (blend) glDisable(GL_BLEND);
+	glDisable(GL_BLEND);
 	m_RenderProperties.setRenderingFlag(glc::WireRenderFlag);
 	// Display arcs
 	m_Arc1.render(glc::WireRenderFlag);
@@ -188,13 +184,10 @@ void GLC_RepTrackBallMover::glDraw()
 	// Display base class (Main circle)
 	m_MainCircle.render(m_RenderProperties);
 
-	glPopMatrix();
-	glMatrixMode(GL_PROJECTION);
-	glPopMatrix();
-	glMatrixMode(GL_MODELVIEW);
-
-	if (depthTest) glEnable(GL_DEPTH_TEST);
-	if (!blend)  glEnable(GL_BLEND);
+	GLC_Context::current()->glcPopMatrix();
+	GLC_Context::current()->glcMatrixMode(GL_PROJECTION);
+	GLC_Context::current()->glcPopMatrix();
+	GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);
 
 }
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_reptrackballmover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_reptrackballmover.h
index fc6c22446..72271e55e 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_reptrackballmover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_reptrackballmover.h
@@ -70,6 +70,10 @@ public:
 	//! Set representation main color
 	virtual void setMainColor(const QColor& color);
 
+	//! Set representation screen ration
+	inline void setRatio(double ratio)
+	{m_Ratio= ratio;}
+
 //@}
 
 //////////////////////////////////////////////////////////////////////
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_settargetmover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_settargetmover.cpp
index 7d10c8c94..fce588103 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_settargetmover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_settargetmover.cpp
@@ -60,23 +60,23 @@ GLC_Mover* GLC_SetTargetMover::clone() const
 //////////////////////////////////////////////////////////////////////
 
 // Initialized the mover
-void GLC_SetTargetMover::init(QMouseEvent * e)
+void GLC_SetTargetMover::init(const GLC_UserInput& userInput)
 {
 	// Z Buffer component of selected point between 0 and 1
 	GLfloat Depth;
 	// read selected point
-	glReadPixels(e->x(), m_pViewport->viewVSize() - e->y() , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &Depth);
+	glReadPixels(userInput.x(), m_pViewport->viewVSize() - userInput.y() , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &Depth);
 
 	// Test if there is geometry under picking point
 	if (!qFuzzyCompare(Depth, 1.0f))
 	{	// Geometry find -> Update camera's target position
-		const GLC_Point3d target(m_pViewport->unProject(e->x(), e->y()));
+		const GLC_Point3d target(m_pViewport->unProject(userInput.x(), userInput.y()));
 		m_pViewport->cameraHandle()->setTargetCam(target);
 	}
 	else
-	{	// Geometrie not find -> panning
+	{	// Geometry not find -> panning
 
-		const GLC_Point3d curPos(m_pViewport->mapPosMouse(e->x(), e->y()));
+		const GLC_Point3d curPos(m_pViewport->mapPosMouse(userInput.x(), userInput.y()));
 		const GLC_Point3d prevPos(m_pViewport->mapPosMouse(m_pViewport->viewHSize() / 2, m_pViewport->viewVSize() / 2));
 		const GLC_Vector3d VectPan(curPos - prevPos);	// panning vector
 		// pan camera
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_settargetmover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_settargetmover.h
index b18c3b1a6..5d0ae637a 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_settargetmover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_settargetmover.h
@@ -58,10 +58,10 @@ public:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Initialized the mover
-	virtual void init(QMouseEvent * e);
+	virtual void init(const GLC_UserInput& userInput);
 
 	//! Move the camera
-	virtual bool move(QMouseEvent *){return true;}
+	virtual bool move(const GLC_UserInput&){return true;}
 //@}
 
 };
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_trackballmover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_trackballmover.cpp
index f54f25df4..766e32385 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_trackballmover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_trackballmover.cpp
@@ -23,6 +23,7 @@
 
 #include "glc_trackballmover.h"
 #include "glc_viewport.h"
+#include "glc_reptrackballmover.h"
 
 // Default constructor
 GLC_TrackBallMover::GLC_TrackBallMover(GLC_Viewport* pViewport, const QList<GLC_RepMover*>& repsList)
@@ -61,9 +62,9 @@ GLC_Mover* GLC_TrackBallMover::clone() const
 //////////////////////////////////////////////////////////////////////
 
 // Initialized the mover
-void GLC_TrackBallMover::init(QMouseEvent * e)
+void GLC_TrackBallMover::init(const GLC_UserInput& userInput)
 {
-	GLC_Mover::m_PreviousVector.setVect(mapForTracking(static_cast<double>(e->x()), static_cast<double>(e->y())));
+	GLC_Mover::m_PreviousVector.setVect(mapForTracking(static_cast<double>(userInput.x()), static_cast<double>(userInput.y())));
 
 	const double Angle= acos(glc::Z_AXIS * GLC_Mover::m_PreviousVector);
 	const GLC_Vector3d AxeRot(glc::Z_AXIS ^ GLC_Mover::m_PreviousVector);
@@ -77,9 +78,9 @@ void GLC_TrackBallMover::init(QMouseEvent * e)
 }
 
 // Move the camera
-bool GLC_TrackBallMover::move(QMouseEvent * e)
+bool GLC_TrackBallMover::move(const GLC_UserInput& userInput)
 {
-	const GLC_Vector3d VectCurOrbit(mapForTracking(static_cast<double>(e->x()), static_cast<double>(e->y())));
+	const GLC_Vector3d VectCurOrbit(mapForTracking(static_cast<double>(userInput.x()), static_cast<double>(userInput.y())));
 
 	// Update camera position (orbit)
 	GLC_Mover::m_pViewport->cameraHandle()->orbit(GLC_Mover::m_PreviousVector, VectCurOrbit);
@@ -96,6 +97,19 @@ bool GLC_TrackBallMover::move(QMouseEvent * e)
 	return true;
 }
 
+void GLC_TrackBallMover::setRatio(double ratio)
+{
+	m_Ratio= ratio;
+	const int repCount= m_RepMoverList.count();
+	for (int i= 0; i < repCount; ++i)
+	{
+		GLC_RepTrackBallMover* pRep= dynamic_cast<GLC_RepTrackBallMover*>(m_RepMoverList.at(i));
+		if (NULL != pRep)
+		{
+			pRep->setRatio(ratio);
+		}
+	}
+}
 /////////////////////////////////////////////////////////////////////
 // Private services Functions
 //////////////////////////////////////////////////////////////////////
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_trackballmover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_trackballmover.h
index 14f03a6e7..7a11b4ba0 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_trackballmover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_trackballmover.h
@@ -64,10 +64,13 @@ public:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Initialized the mover
-	virtual void init(QMouseEvent * e);
+	virtual void init(const GLC_UserInput& userInput);
 
 	//! Move the camera
-	virtual bool move(QMouseEvent * e);
+	virtual bool move(const GLC_UserInput& userInput);
+
+	//! Set this mover screen ratio
+	void setRatio(double ratio);
 
 //@}
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_tsrmover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_tsrmover.cpp
new file mode 100644
index 000000000..80f9bf608
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_tsrmover.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************************/
+
+//! \file glc_tsrmover.cpp Implementation of the GLC_TsrMover class.
+
+#include "glc_tsrmover.h"
+#include "glc_viewport.h"
+
+#include "../geometry/glc_point.h"
+
+// Default constructor
+GLC_TsrMover::GLC_TsrMover(GLC_Viewport* pViewport, const QList<GLC_RepMover*>& repsList)
+: GLC_Mover(pViewport, repsList)
+{
+
+}
+
+// Copy constructor
+GLC_TsrMover::GLC_TsrMover(const GLC_TsrMover& tsrMover)
+: GLC_Mover(tsrMover)
+{
+
+}
+
+
+GLC_TsrMover::~GLC_TsrMover()
+{
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// Get Functions
+//////////////////////////////////////////////////////////////////////
+
+// Return a clone of the mover
+GLC_Mover* GLC_TsrMover::clone() const
+{
+	return new GLC_TsrMover(*this);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Set Functions
+//////////////////////////////////////////////////////////////////////
+
+// Initialized the mover
+void GLC_TsrMover::init(const GLC_UserInput& userInput)
+{
+	m_PreviousVector= GLC_Point3d(userInput.normalyzeXTouchCenter(), userInput.normalyzeYTouchCenter(), 0.0);
+}
+
+// Move the camera
+bool GLC_TsrMover::move(const GLC_UserInput& userInput)
+{
+	if (!(userInput.normalyzeXTouchCenter() < 0.0) && !(userInput.normalyzeYTouchCenter() < 0.0))
+	{
+		m_PreviousVector= GLC_Point3d(userInput.normalyzeXTouchCenter(), userInput.normalyzeYTouchCenter(), 0.0);
+	}
+	else
+	{
+		qDebug() << "Pas cool";
+		if (!userInput.translation().isNull())
+		{
+			m_PreviousVector= GLC_Vector3d(userInput.translation().getX(), userInput.translation().getY(), 0.0) + m_PreviousVector;			
+		}
+	}
+	
+	const double x= m_PreviousVector.x();
+	const double y= m_PreviousVector.y();
+	//GLC_Point3d center2= m_pViewport->unProject(x * m_pViewport->viewHSize(), y * m_pViewport->viewVSize());
+	
+	//qDebug() << "touch center= " << x << " , " << y;
+
+	
+	if (!qFuzzyCompare(userInput.scaleFactor(), 0))
+	{
+		GLC_Point dummy(m_pViewport->cameraHandle()->target());
+		m_pViewport->setDistMinAndMax(dummy.boundingBox());
+
+		GLC_Point2d nPos= m_pViewport->mapNormalyzeToOpenGLScreen(x, y);
+		GLC_Point3d nPos3D(nPos.getX(), nPos.getY(), 1.0);
+		GLC_Point3d projected= m_pViewport->compositionMatrix().inverted() * nPos3D;
+
+		m_pViewport->cameraHandle()->zoom(userInput.scaleFactor());
+
+		m_pViewport->setDistMinAndMax(dummy.boundingBox());
+		GLC_Point3d projected2= m_pViewport->compositionMatrix().inverted() * nPos3D;
+		GLC_Vector3d delta= projected - projected2;
+		m_pViewport->cameraHandle()->translate(delta);
+	}
+
+	if (!qFuzzyCompare(userInput.rotationAngle(), 0))
+	{
+		GLC_Point dummy(m_pViewport->cameraHandle()->target());
+		m_pViewport->setDistMinAndMax(dummy.boundingBox());
+
+		GLC_Point2d nPos= m_pViewport->mapNormalyzeToOpenGLScreen(x, y);
+		GLC_Point3d nPos3D(nPos.getX(), nPos.getY(), 1.0);
+		GLC_Point3d center= m_pViewport->compositionMatrix().inverted() * nPos3D;
+
+		GLC_Vector3d axis= m_pViewport->cameraHandle()->forward();
+
+		m_pViewport->cameraHandle()->rotateAround(axis, userInput.rotationAngle(), center);
+	}
+
+	if (!userInput.translation().isNull())
+	{
+		double transX= userInput.translation().getX() * m_pViewport->viewHSize();
+		double transY= userInput.translation().getY() * m_pViewport->viewVSize();
+
+		GLC_Vector3d mappedTranslation(-transX, -transY, 0.0);
+		// Compute the length of camera's field of view
+		const double ChampsVision = m_pViewport->cameraHandle()->distEyeTarget() *  m_pViewport->viewTangent();
+
+		// the side of camera's square is mapped on Vertical length of window
+		// Ratio OpenGL/Pixel = dimend GL / dimens Pixel
+		const double Ratio= ChampsVision / static_cast<double>(m_pViewport->viewVSize());
+
+		mappedTranslation= mappedTranslation * Ratio;
+		m_pViewport->cameraHandle()->pan(mappedTranslation);
+	}
+
+	return true;
+}
+
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_openglstate.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_tsrmover.h
similarity index 66%
rename from ground/openpilotgcs/src/libs/glc_lib/glc_openglstate.h
rename to ground/openpilotgcs/src/libs/glc_lib/viewport/glc_tsrmover.h
index 792318553..f18604b97 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_openglstate.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_tsrmover.h
@@ -19,34 +19,39 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
  *****************************************************************************/
-//! \file glc_openglstate.h interface for the GLC_OpenGLState class.
 
-#ifndef GLC_OPENGLSTATE_H_
-#define GLC_OPENGLSTATE_H_
+//! \file glc_tsrmover Interface for the GLC_TsrMover class.
+
+#ifndef GLC_TSRMOVER_H_
+#define GLC_TSRMOVER_H_
+
+#include "glc_mover.h"
+
+#include "../glc_config.h"
 
 //////////////////////////////////////////////////////////////////////
-//! \class GLC_OpenGLState
-/*! \brief GLC_OpenGLState is use to store and retrieve differential opengl state*/
+//! \class GLC_TsrMover
+/*! \brief GLC_TsrMover : Translationn scaling and rotation interactive manipulation */
 //////////////////////////////////////////////////////////////////////
-class GLC_OpenGLState
+class GLC_LIB_EXPORT GLC_TsrMover : public GLC_Mover
 {
 public:
-//////////////////////////////////////////////////////////////////////
-/*! @name Constructor / Destructor */
-//@{
-//////////////////////////////////////////////////////////////////////
+	//! Default constructor
+	GLC_TsrMover(GLC_Viewport*, const QList<GLC_RepMover*>& repsList= QList<GLC_RepMover*>());
 
-	GLC_OpenGLState();
-	virtual ~GLC_OpenGLState();
+	//! Copy constructor
+	GLC_TsrMover(const GLC_TsrMover&);
 
-//@}
+	//! Destructor
+	virtual ~GLC_TsrMover();
 
 //////////////////////////////////////////////////////////////////////
 /*! \name Get Functions*/
 //@{
 //////////////////////////////////////////////////////////////////////
 public:
-
+	//! Return a clone of the mover
+	virtual GLC_Mover* clone() const;
 //@}
 
 //////////////////////////////////////////////////////////////////////
@@ -54,15 +59,11 @@ public:
 //@{
 //////////////////////////////////////////////////////////////////////
 public:
-	//!
+	//! Initialized the mover
+	virtual void init(const GLC_UserInput& userInput);
 
+	//! Move the camera
+	virtual bool move(const GLC_UserInput& userInput);
 //@}
-
-//////////////////////////////////////////////////////////////////////
-// Private members
-//////////////////////////////////////////////////////////////////////
-private:
-
 };
-
-#endif /* GLC_OPENGLSTATE_H_ */
+#endif /* GLC_TSRMOVER_H_ */
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_turntablemover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_turntablemover.cpp
index 69b873dd0..4d56ade13 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_turntablemover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_turntablemover.cpp
@@ -62,9 +62,9 @@ GLC_Mover* GLC_TurnTableMover::clone() const
 //////////////////////////////////////////////////////////////////////
 
 // Initialized the mover
-void GLC_TurnTableMover::init(QMouseEvent * e)
+void GLC_TurnTableMover::init(const GLC_UserInput& userInput)
 {
-	GLC_Mover::m_PreviousVector.setVect(static_cast<double>(e->x()), static_cast<double>(e->y()),0.0);
+	GLC_Mover::m_PreviousVector.setVect(static_cast<double>(userInput.x()), static_cast<double>(userInput.y()),0.0);
 	GLC_Camera* pCamera= GLC_Mover::m_pViewport->cameraHandle();
 	// Calculate angle sign
 	m_Sign= pCamera->defaultUpVector() * pCamera->upVector();
@@ -81,7 +81,7 @@ void GLC_TurnTableMover::init(QMouseEvent * e)
 }
 
 
-bool GLC_TurnTableMover::move(QMouseEvent * e)
+bool GLC_TurnTableMover::move(const GLC_UserInput& userInput)
 {
 	GLC_Camera* pCamera= GLC_Mover::m_pViewport->cameraHandle();
 	// Turn table rotation
@@ -89,8 +89,8 @@ bool GLC_TurnTableMover::move(QMouseEvent * e)
 	const double width= static_cast<double> ( GLC_Mover::m_pViewport->viewVSize() );
 	const double height= static_cast<double> ( GLC_Mover::m_pViewport->viewHSize() );
 
-	const double alpha = -((static_cast<double>(e->x()) - GLC_Mover::m_PreviousVector.x()) / width) * rotSpeed;
-	const double beta = ((static_cast<double>(e->y()) - GLC_Mover::m_PreviousVector.y()) / height) * rotSpeed;
+	const double alpha = -((static_cast<double>(userInput.x()) - GLC_Mover::m_PreviousVector.x()) / width) * rotSpeed;
+	const double beta = ((static_cast<double>(userInput.y()) - GLC_Mover::m_PreviousVector.y()) / height) * rotSpeed;
 
 	// Rotation around the screen vertical axis
 	pCamera->rotateAroundTarget(pCamera->defaultUpVector(), alpha * m_Sign);
@@ -103,7 +103,7 @@ bool GLC_TurnTableMover::move(QMouseEvent * e)
 		pCamera->rotateAroundTarget(rightVector, beta);
 	}
 
-	m_PreviousVector.setVect(static_cast<double>(e->x()), static_cast<double>(e->y()), 0.0);
+	m_PreviousVector.setVect(static_cast<double>(userInput.x()), static_cast<double>(userInput.y()), 0.0);
 
 	return true;
 }
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_turntablemover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_turntablemover.h
index c6bfb4d51..7eb44621a 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_turntablemover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_turntablemover.h
@@ -59,10 +59,10 @@ public:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Initialized the mover
-	virtual void init(QMouseEvent * e);
+	virtual void init(const GLC_UserInput& userInput);
 
 	//! Move the camera
-	virtual bool move(QMouseEvent * e);
+	virtual bool move(const GLC_UserInput& userInput);
 
 //@}
 
diff --git a/ground/openpilotgcs/src/libs/glc_lib/glc_openglstatemanager.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_userinput.cpp
similarity index 53%
rename from ground/openpilotgcs/src/libs/glc_lib/glc_openglstatemanager.cpp
rename to ground/openpilotgcs/src/libs/glc_lib/viewport/glc_userinput.cpp
index fc68e5bb4..1788efbd4 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/glc_openglstatemanager.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_userinput.cpp
@@ -19,16 +19,49 @@
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
  *****************************************************************************/
-//! \file glc_openglstatemanager.cpp implementation of the GLC_OpenGLStateManager class.
 
-#include "glc_openglstatemanager.h"
+//! \file glc_mover.cpp Implementation of the GLC_Mover class.
 
-GLC_OpenGLStateManager::GLC_OpenGLStateManager()
+#include "glc_userinput.h"
+
+GLC_UserInput::GLC_UserInput(int x, int y)
+: m_X(x)
+, m_Y(y)
+, m_NormalyzeX(0.0)
+, m_NormalyzeY(0.0)
+, m_Translation()
+, m_Rotation(0.0)
+, m_ScaleFactor(1.0)
+, m_TransformationIsSet(false)
 {
 
 }
 
-GLC_OpenGLStateManager::~GLC_OpenGLStateManager()
+GLC_UserInput::~GLC_UserInput()
 {
 
 }
+
+//////////////////////////////////////////////////////////////////////
+// Set Functions
+//////////////////////////////////////////////////////////////////////
+void GLC_UserInput::setPosition(int x, int y)
+{
+	m_X= x;
+	m_Y= y;
+}
+
+void GLC_UserInput::setNormalyzeTouchCenterPosition(double x, double y)
+{
+	m_NormalyzeX= x;
+	m_NormalyzeY= y;
+}
+
+void GLC_UserInput::setTransformation(const GLC_Vector2d& translation, double rotation, double scaleFactor)
+{
+	m_Translation= translation;
+	m_Rotation= rotation;
+	m_ScaleFactor= scaleFactor;
+
+	m_TransformationIsSet= true;
+}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_userinput.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_userinput.h
new file mode 100644
index 000000000..63fa8526a
--- /dev/null
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_userinput.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+
+ This file is part of the GLC-lib library.
+ Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
+ http://glc-lib.sourceforge.net
+
+ GLC-lib is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ GLC-lib is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with GLC-lib; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+ *****************************************************************************/
+
+//! \file glc_userinput.h Interface for the GLC_UserInput class.
+
+#ifndef GLC_USERINPUT_H_
+#define GLC_USERINPUT_H_
+
+#include "../maths/glc_vector2d.h"
+
+#include "../glc_config.h"
+
+class GLC_LIB_EXPORT GLC_UserInput
+{
+public:
+	GLC_UserInput(int x= 0, int y= 0);
+	virtual ~GLC_UserInput();
+
+
+//////////////////////////////////////////////////////////////////////
+/*! \name Get Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+public:
+	//! return the x position
+	inline int x() const
+	{return m_X;}
+
+	//! Return the y position
+	inline int y() const
+	{return m_Y;}
+
+	//! Return normalyze x touch center
+	inline double normalyzeXTouchCenter() const
+	{return m_NormalyzeX;}
+
+	//! Return normalyze x touch center
+	inline double normalyzeYTouchCenter() const
+	{return m_NormalyzeX;}
+
+	//! Return the translation
+	inline GLC_Vector2d translation() const
+	{return m_Translation;}
+
+	//! Return the rotation angle
+	inline double rotationAngle() const
+	{return m_Rotation;}
+
+	//! Return the scale factor
+	inline double scaleFactor() const
+	{return m_ScaleFactor;}
+
+	//! Return true if the transformation has been set
+	inline bool transformationIsSet() const
+	{return m_TransformationIsSet;}
+//@}
+
+//////////////////////////////////////////////////////////////////////
+/*! \name Set Functions*/
+//@{
+//////////////////////////////////////////////////////////////////////
+public:
+	//! Set the position
+	void setPosition(int x, int y);
+
+	//! Set the normalyze position of the center of touch
+	void setNormalyzeTouchCenterPosition(double x, double y);
+
+	//! Set the transformation
+	void setTransformation(const GLC_Vector2d& translation, double rotation= 0.0, double scaleFactor= 1.0);
+
+	//! Set translation
+	inline void setTranslation(const GLC_Vector2d& translation)
+	{m_Translation= translation;}
+
+	//! Set rotation
+	inline void setRotation(double rotation)
+	{m_Rotation= rotation;}
+
+	//! Set scaling
+	inline void setScaleFactor(double scaleFactor)
+	{m_ScaleFactor= scaleFactor;}
+//@}
+
+//////////////////////////////////////////////////////////////////////
+// Private Members
+//////////////////////////////////////////////////////////////////////
+private:
+	//! the x position of the user input
+	int m_X;
+
+	//! The y position of the user input
+	int m_Y;
+
+	//Normalize position of center of touchs
+	double m_NormalyzeX;
+	double m_NormalyzeY;
+
+	// Transformation data
+	//! Translation vector
+	GLC_Vector2d m_Translation;
+
+	//! Rotation angle
+	double m_Rotation;
+
+	//! Scale factor
+	double m_ScaleFactor;
+
+	//! Flag to know if a transformation has been set
+	bool m_TransformationIsSet;
+
+};
+
+#endif /* GLC_USERINPUT_H_ */
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_viewport.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_viewport.cpp
index 08e1ae25d..0f2785fb3 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_viewport.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_viewport.cpp
@@ -22,7 +22,9 @@
 
 //! \file glc_viewport.cpp implementation of the GLC_Viewport class.
 
+#include <QtOpenGL>
 
+#include "../glu/glc_glu.h"
 #include "glc_viewport.h"
 #include "../glc_openglexception.h"
 #include "../glc_ext.h"
@@ -85,6 +87,38 @@ GLC_Viewport::~GLC_Viewport()
 //////////////////////////////////////////////////////////////////////
 // Get Functions
 //////////////////////////////////////////////////////////////////////
+GLC_Point2d  GLC_Viewport::normalyseMousePosition(int x, int y)
+{
+	double nX= 0.0;
+	double nY= 0.0;
+	if (m_WindowHSize != 0)
+	{
+		nX= static_cast<double>(x) / static_cast<double>(m_WindowHSize);
+	}
+
+	if (m_WindowVSize != 0)
+	{
+		nY= static_cast<double>(y) / static_cast<double>(m_WindowVSize);
+	}
+
+	return GLC_Point2d(nX, nY);
+}
+
+GLC_Point2d GLC_Viewport::mapToOpenGLScreen(int x, int y)
+{
+	GLC_Point2d nPos= normalyseMousePosition(x, y);
+
+	return mapNormalyzeToOpenGLScreen(nPos.getX(), nPos.getY());
+}
+
+GLC_Point2d GLC_Viewport::mapNormalyzeToOpenGLScreen(double x, double y)
+{
+	GLC_Point2d pos(x, y);
+	pos= pos * 2.0;
+	pos.setY(pos.getY() * -1.0);
+	pos= pos + GLC_Point2d(-1.0, 1.0);
+	return pos;
+}
 
 GLC_Vector3d GLC_Viewport::mapPosMouse( GLdouble Posx, GLdouble Posy) const
 {
@@ -106,13 +140,19 @@ GLC_Vector3d GLC_Viewport::mapPosMouse( GLdouble Posx, GLdouble Posy) const
 	return VectMouse;
 }
 
+GLC_Vector3d GLC_Viewport::mapNormalyzePosMouse(double Posx, double Posy) const
+{
+	double screenX= Posx * static_cast<double>(m_WindowHSize);
+	double screenY= Posy * static_cast<double>(m_WindowVSize);
+	return mapPosMouse(screenX, screenY);
+}
+
 //////////////////////////////////////////////////////////////////////
 // Public OpenGL Functions
 //////////////////////////////////////////////////////////////////////
 
 void GLC_Viewport::initGl()
 {
-	// OpenGL initialisation from NEHE production
 	m_pQGLWidget->qglClearColor(m_BackgroundColor);       // Background
 	glClearDepth(1.0f);                                   // Depth Buffer Setup
 	glShadeModel(GL_SMOOTH);                              // Enable Smooth Shading
@@ -120,24 +160,20 @@ void GLC_Viewport::initGl()
 	glDepthFunc(GL_LEQUAL);                               // The Type Of Depth Testing To Do
 	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Really Nice Perspective Calculation
 	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
-	// Init GLC_State
-	GLC_State::init();
+	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	glPolygonOffset (1.0f, 1.0f);
 }
 
 void GLC_Viewport::glExecuteCam(void)
 {
-	m_pViewCam->glExecute();
 	renderImagePlane();
+	m_pViewCam->glExecute();
 }
 
 void GLC_Viewport::updateProjectionMat(void)
 {
-	// Make opengl context attached the current One
-	m_pQGLWidget->makeCurrent();
-
-	glMatrixMode(GL_PROJECTION);						// select The Projection Matrix
-	glLoadIdentity();									// Reset The Projection Matrix
+	GLC_Context::current()->glcMatrixMode(GL_PROJECTION);						// select The Projection Matrix
+	GLC_Context::current()->glcLoadIdentity();									// Reset The Projection Matrix
 
 	if (m_UseParallelProjection)
 	{
@@ -148,18 +184,21 @@ void GLC_Viewport::updateProjectionMat(void)
 		const double right=  -left;
 		const double bottom= - height * 0.5;
 		const double top= -bottom;
-		glOrtho(left, right, bottom, top, m_dDistanceMini, m_DistanceMax);
+		GLC_Context::current()->glcOrtho(left, right, bottom, top, m_dDistanceMini, m_DistanceMax);
 	}
 	else
 	{
-		gluPerspective(m_ViewAngle, m_AspectRatio, m_dDistanceMini, m_DistanceMax);
+	    const double yMax= m_dDistanceMini * tan(m_ViewAngle * glc::PI / 360.0);
+	    const double yMin= -yMax;
+	    const double xMax= yMax * m_AspectRatio;
+	    const double xMin= -xMax;
+	    GLC_Context::current()->glcFrustum(xMin, xMax, yMin, yMax, m_dDistanceMini, m_DistanceMax);
 	}
 
 	// Save the projection matrix
-	glGetDoublev(GL_PROJECTION_MATRIX, m_ProjectionMatrix.setData());
+	m_ProjectionMatrix= GLC_Context::current()->projectionMatrix();
 
-	glMatrixMode(GL_MODELVIEW);							// select The Modelview Matrix
-	glLoadIdentity();									// Reset The Modelview Matrix
+	GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);							// select The Modelview Matrix
 }
 
 void GLC_Viewport::forceAspectRatio(double ratio)
@@ -223,7 +262,7 @@ GLC_Point3d GLC_Viewport::unProject(int x, int y) const
 
 	// OpenGL ccordinate of selected point
 	GLdouble pX, pY, pZ;
-	gluUnProject((GLdouble) x, (GLdouble) (m_WindowVSize - y) , Depth
+	glc::gluUnProject((GLdouble) x, (GLdouble) (m_WindowVSize - y) , Depth
 		, m_pViewCam->modelViewMatrix().getData(), m_ProjectionMatrix.getData(), Viewport, &pX, &pY, &pZ);
 
 	return GLC_Point3d(pX, pY, pZ);
@@ -250,7 +289,7 @@ QList<GLC_Point3d> GLC_Viewport::unproject(const QList<int>& list)const
 		const int y= m_WindowVSize - list.at(i + 1);
 		glReadPixels(x, y , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &Depth);
 
-		gluUnProject(static_cast<GLdouble>(x), static_cast<GLdouble>(y) , Depth , m_pViewCam->modelViewMatrix().getData()
+		glc::gluUnProject(static_cast<GLdouble>(x), static_cast<GLdouble>(y) , Depth , m_pViewCam->modelViewMatrix().getData()
 				, m_ProjectionMatrix.getData(), Viewport, &pX, &pY, &pZ);
 		unprojectedPoints.append(GLC_Point3d(pX, pY, pZ));
 	}
@@ -331,13 +370,13 @@ GLC_uint GLC_Viewport::selectBody(GLC_3DViewInstance* pInstance, int x, int y)
 	m_pQGLWidget->qglClearColor(Qt::black);
 	GLC_State::setSelectionMode(true);
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	glLoadIdentity();
+	GLC_Context::current()->glcLoadIdentity();
 
 	glExecuteCam();
 
 	// Draw the scene
 	glDisable(GL_BLEND);
-	glDisable(GL_LIGHTING);
+	GLC_Context::current()->glcEnableLighting(false);
 	glDisable(GL_TEXTURE_2D);
 
 	pInstance->renderForBodySelection();
@@ -360,13 +399,13 @@ QPair<int, GLC_uint> GLC_Viewport::selectPrimitive(GLC_3DViewInstance* pInstance
 	m_pQGLWidget->qglClearColor(Qt::black);
 	GLC_State::setSelectionMode(true);
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	glLoadIdentity();
+	GLC_Context::current()->glcLoadIdentity();
 
 	glExecuteCam();
 
 	// Draw the scene
 	glDisable(GL_BLEND);
-	glDisable(GL_LIGHTING);
+	GLC_Context::current()->glcEnableLighting(false);
 	glDisable(GL_TEXTURE_2D);
 
 	pInstance->renderForBodySelection();
@@ -508,13 +547,13 @@ void GLC_Viewport::updateMinimumRatioSize()
 void GLC_Viewport::loadBackGroundImage(const QString& ImageFile)
 {
 	delete m_pImagePlane;
-	m_pImagePlane= new GLC_ImagePlane(m_pQGLWidget->context(), ImageFile);
+	m_pImagePlane= new GLC_ImagePlane(ImageFile);
 }
 
 void GLC_Viewport::loadBackGroundImage(const QImage& image)
 {
 	delete m_pImagePlane;
-	m_pImagePlane= new GLC_ImagePlane(m_pQGLWidget->context(), image);
+	m_pImagePlane= new GLC_ImagePlane(image);
 }
 
 void GLC_Viewport::deleteBackGroundImage()
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_viewport.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_viewport.h
index 02bedf2af..33a86dea6 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_viewport.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_viewport.h
@@ -94,9 +94,21 @@ public:
 	inline double aspectRatio() const
 	{ return static_cast<double>(m_WindowHSize) / static_cast<double>(m_WindowVSize);}
 
+	//! Return the normalyse mouse position from screen coordinate
+	GLC_Point2d normalyseMousePosition(int x, int y);
+
+	//! Map screen position to OpenGL screen position
+	GLC_Point2d mapToOpenGLScreen(int x, int y);
+
+	//! Map normalyze screen position to OpenGL screen position
+	GLC_Point2d mapNormalyzeToOpenGLScreen(double x, double y);
+
 	//! Map Screen position to OpenGL position (On image Plane) according to this viewport
 	GLC_Vector3d mapPosMouse( GLdouble Posx, GLdouble Posy) const;
 
+	//! Map normalyse Screen position to OpenGL position (On image Plane) according to this viewport
+	GLC_Vector3d mapNormalyzePosMouse(double Posx, double Posy) const;
+
 	//! Get this viewport's camera's angle of view
 	inline double viewAngle() const
 	{ return m_ViewAngle;}
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_zoommover.cpp b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_zoommover.cpp
index 2a5db1c85..0c288687a 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_zoommover.cpp
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_zoommover.cpp
@@ -60,19 +60,19 @@ GLC_Mover* GLC_ZoomMover::clone() const
 //////////////////////////////////////////////////////////////////////
 
 // Initialized the mover
-void GLC_ZoomMover::init(QMouseEvent * e)
+void GLC_ZoomMover::init(const GLC_UserInput& userInput)
 {
 	// Change origine (view center) and cover between -1 and 1
 	const double vSize= static_cast<double>(m_pViewport->viewVSize());
-	m_PreviousVector.setY((vSize / 2.0 - e->y()) / ( vSize / 2.0));
+	m_PreviousVector.setY((vSize / 2.0 - userInput.y()) / ( vSize / 2.0));
 }
 
 // Move the camera
-bool GLC_ZoomMover::move(QMouseEvent * e)
+bool GLC_ZoomMover::move(const GLC_UserInput& userInput)
 {
 	// Change origine (View Center) and cover (from -1 to 1)
 	const double vSize= static_cast<double>(m_pViewport->viewVSize());
-	const double Posy= (vSize / 2.0 - e->y()) / ( vSize / 2.0);
+	const double Posy= (vSize / 2.0 - userInput.y()) / ( vSize / 2.0);
 
 	// Compute zoom factor between (1 / MAXZOOMFACTOR) and (MAXZOOMFACTOR)
 	double ZoomFactor= Posy - m_PreviousVector.y();
diff --git a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_zoommover.h b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_zoommover.h
index d93cc1e55..862e33267 100644
--- a/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_zoommover.h
+++ b/ground/openpilotgcs/src/libs/glc_lib/viewport/glc_zoommover.h
@@ -64,10 +64,10 @@ public:
 //////////////////////////////////////////////////////////////////////
 public:
 	//! Initialized the mover
-	virtual void init(QMouseEvent * e);
+	virtual void init(const GLC_UserInput& userInput);
 
 	//! Move the camera
-	virtual bool move(QMouseEvent * e);
+	virtual bool move(const GLC_UserInput& userInput);
 
 	//! Set the maximum zoom factor
 	inline void setMaxZoomFactor(const double factor)