diff -r 3060f77723b8 code/nel/include/nel/3d/driver.h
--- a/code/nel/include/nel/3d/driver.h	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/nel/include/nel/3d/driver.h	Sat Jan 15 21:17:15 2011 +0100
@@ -571,6 +571,11 @@
 	/// get the number of VBL wait when a swapBuffers() is issued. 0 means no synchronisation to the VBL
 	virtual uint			getSwapVBLInterval()=0;
 
+	/// Detach rendering context allowing a second thread to use the actual context.
+	virtual bool detachContext()=0;
+	/// Attach rendering context to current thread.
+	virtual bool attachContext()=0;
+
 
 	/// \name Profiling.
 	// @{
diff -r 3060f77723b8 code/nel/include/nel/3d/driver_user.h
--- a/code/nel/include/nel/3d/driver_user.h	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/nel/include/nel/3d/driver_user.h	Sat Jan 15 21:17:15 2011 +0100
@@ -474,6 +474,11 @@
 	virtual void			forceTextureResize(uint divisor);
 	virtual void			forceNativeFragmentPrograms(bool nativeOnly);
 	virtual bool			setMonitorColorProperties (const CMonitorColorProperties &properties);
+	/// Detach rendering context allowing a second thread to use the actual context.
+	virtual bool detachContext();
+	/// Attach rendering context to current thread.
+	virtual bool attachContext();
+
 	// @}
 
 	/// \name Shape Bank
diff -r 3060f77723b8 code/nel/include/nel/3d/u_driver.h
--- a/code/nel/include/nel/3d/u_driver.h	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/nel/include/nel/3d/u_driver.h	Sat Jan 15 21:17:15 2011 +0100
@@ -838,6 +838,12 @@
 		virtual bool pasteTextFromClipboard(ucstring &text) =0;
 	// @}
 
+	/// \name Multi thread management
+	// @{
+		virtual bool detachContext()=0;
+		virtual bool attachContext()=0;
+	// @}
+
 public:
 
 	/**
diff -r 3060f77723b8 code/nel/src/3d/driver/direct3d/driver_direct3d.cpp
--- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp	Sat Jan 15 21:17:15 2011 +0100
@@ -3889,6 +3889,15 @@
 	return _EventEmitter.pasteTextFromClipboard(text);
 }
 
+bool CDriverD3D::detachContext()
+{
+	return true;
+}
+
+bool CDriverD3D::attachContext()
+{
+	return true;
+}
 bool CDriverD3D::convertBitmapToIcon(const NLMISC::CBitmap &bitmap, HICON &icon, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY, bool cursor)
 {
 	CBitmap src = bitmap;
diff -r 3060f77723b8 code/nel/src/3d/driver/direct3d/driver_direct3d.h
--- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h	Sat Jan 15 21:17:15 2011 +0100
@@ -2491,6 +2491,9 @@
 	virtual bool copyTextToClipboard(const ucstring &text);
 	virtual bool pasteTextFromClipboard(ucstring &text);
 
+	virtual bool attachContext();
+	virtual bool detachContext();
+
 public:
 	#ifdef 	NL_DEBUG
 		std::set<CVBDrvInfosD3D *> _LockedBuffers;
diff -r 3060f77723b8 code/nel/src/3d/driver/opengl/driver_opengl.h
--- a/code/nel/src/3d/driver/opengl/driver_opengl.h	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/nel/src/3d/driver/opengl/driver_opengl.h	Sat Jan 15 21:17:15 2011 +0100
@@ -340,6 +340,10 @@
 	virtual bool			copyTextToClipboard(const ucstring &text);
 	virtual bool			pasteTextFromClipboard(ucstring &text);
 
+
+	virtual bool 			detachContext();
+	virtual bool 			attachContext();
+
 	virtual uint32			getAvailableVertexAGPMemory ();
 	virtual uint32			getAvailableVertexVRAMMemory ();
 
diff -r 3060f77723b8 code/nel/src/3d/driver/opengl/driver_opengl_window.cpp
--- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp	Sat Jan 15 21:17:15 2011 +0100
@@ -1113,7 +1113,44 @@
 
 	return true;
 }
-
+// --------------------------------------------------
+bool CDriverGL::detachContext()
+{
+	bool ret=true;
+#if defined(NL_OS_WINDOWS)
+	ret=wglMakeCurrent(_hDC, NULL);
+#elif defined(NL_OS_UNIX)
+	ret=glXMakeCurrent (_dpy, None, NULL);
+#elif defined(NL_OS_MAC)
+	//ret=aglSetCurrentContext
+#else
+	#error "You have to implement me !"
+#endif
+	if (!ret)
+	{
+		nlwarning("Can't detach context %0X for threadID #%X", glGetError(), IThread::getCurrentThread());
+	}
+	return ret;
+}
+// --------------------------------------------------
+bool CDriverGL::attachContext()
+{
+	bool ret=true;
+#if defined(NL_OS_WINDOWS)
+	ret=wglMakeCurrent(_hDC, _hRC);
+#elif defined(NL_OS_UNIX)
+	ret=glXMakeCurrent (_dpy, _win, _ctx);
+#elif defined(NL_OS_MAC)
+	//ret=aglSetCurrentContext
+#else
+	#error "You have to implement me !"
+#endif
+	if (!ret)
+	{
+		nlwarning("Can't attach context %0X threadID #%X", glGetError(),IThread::getCurrentThread() );
+	}
+	return ret;
+}
 // --------------------------------------------------
 bool CDriverGL::saveScreenMode()
 {
diff -r 3060f77723b8 code/nel/src/3d/driver_user2.cpp
--- a/code/nel/src/3d/driver_user2.cpp	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/nel/src/3d/driver_user2.cpp	Sat Jan 15 21:17:15 2011 +0100
@@ -260,6 +260,14 @@
 	_Driver->profileTextureUsage(result);
 }
 
+bool CDriverUser::detachContext()
+{
+	return _Driver->detachContext();
+}
 
+bool CDriverUser::attachContext()
+{
+	return _Driver->attachContext();
+}
 
 } // NL3D
diff -r 3060f77723b8 code/ryzom/client/src/cdb_branch.cpp
--- a/code/ryzom/client/src/cdb_branch.cpp	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/ryzom/client/src/cdb_branch.cpp	Sat Jan 15 21:17:15 2011 +0100
@@ -87,7 +87,7 @@
 // reset all static data
 void CCDBNodeBranch::reset()
 {
-	for ( uint b=0; b!=INVALID_CDB_BANK; ++b )
+	for ( uint b=0; b!=NB_CDB_BANKS; ++b )
 		_CDBBankToUnifiedIndexMapping[b].clear();
 	_UnifiedIndexToBank.clear();
 	_CDBLastUnifiedIndex = 0;
diff -r 3060f77723b8 code/ryzom/client/src/connection.cpp
--- a/code/ryzom/client/src/connection.cpp	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/ryzom/client/src/connection.cpp	Sat Jan 15 21:17:15 2011 +0100
@@ -1046,6 +1046,8 @@
 		// Update the DT T0 and T1 global variables
 		updateClientTime();
 		CInputHandlerManager::getInstance()->pumpEvents();
+
+		Driver->attachContext();
 		Driver->clearBuffers(CRGBA::Black);
 		Driver->setMatrixMode2D11();
 
diff -r 3060f77723b8 code/ryzom/client/src/far_tp.cpp
--- a/code/ryzom/client/src/far_tp.cpp	Sat Jan 15 13:05:38 2011 +0100
+++ b/code/ryzom/client/src/far_tp.cpp	Sat Jan 15 21:17:15 2011 +0100
@@ -582,6 +582,7 @@
 			// Server Hop part 3.2: bypass character selection ui & select the same character.
 			// Far TP part 3.2: bypass character selection ui & select the same character.
 			//   This is called from farTPmainloop(), when CONNECTION:USER_CHARS is received.
+			Driver->detachContext();
 			if( !FarTP.isReselectingChar() )
 			{
 				FarTP.selectCharAndEnter();
@@ -1053,6 +1054,8 @@
 
 	if (isIngame())
 	{
+		// Get Rendering context
+		Driver->attachContext();
 		// Display background (TODO: not Kami)
 		beginLoading (StartBackground);
 		UseEscapeDuringLoading = false;
@@ -1391,6 +1394,7 @@
 void CFarTP::farTPmainLoop()
 {
 	ConnectionReadySent = false;
+	Driver->detachContext();
 	LoginSM.pushEvent(CLoginStateMachine::ev_far_tp_main_loop_entered);
 	uint nbRecoSelectCharReceived = 0;
 
@@ -1430,6 +1434,7 @@
 				if ( nbRecoSelectCharReceived <= 1 )
 				{
 					ClientCfg.SelectCharacter = -1;	// turn off character autoselection
+					Driver->attachContext();
 					if ( ! FarTP.reselectCharacter() ) // it should not return here in farTPmainLoop() in the same state otherwise this would be called twice
 						return;
 				}
@@ -1441,6 +1446,7 @@
 		{
 			// Don't call sendReady() within the cotask but within the main loop, as it contains
 			// event/network loops that could trigger a global exit().
+			Driver->attachContext();
 			sendReady();
 			welcomeWindow = !isReselectingChar();
 		}
