Index: egPipeline.cpp
===================================================================
--- egPipeline.cpp	(revision 40)
+++ egPipeline.cpp	(working copy)
@@ -32,7 +32,120 @@
 
 #include "utDebug.h"
 
+bool PipelineShared::instanceFlag = false;
+PipelineShared* PipelineShared::single = 0;
+PipelineShared* PipelineShared::getInstance()
+{
+    if(! instanceFlag)
+    {
+        single = new PipelineShared();
+        instanceFlag = true;
+        return single;
+    }
+    else
+    {
+        return single;
+    }
+}
 
+RenderTarget *PipelineShared::findRenderTarget( const string &id )
+{
+	if( id == "" ) return 0x0;
+
+	for( uint32 i = 0; i < _renderTargets.size(); ++i )
+	{
+		if( _renderTargets[i]->id == id )
+		{
+			return _renderTargets[i];
+		}
+	}
+
+	return 0x0;
+}
+
+void PipelineShared::addRenderTarget( const RenderTarget & rt )
+{
+	if (!findRenderTarget(rt.id) )
+	{
+		_renderTargets.push_back( new RenderTarget(rt) );
+		_newRenderTargets.push_back( _renderTargets.size()-1 );
+	}
+}
+
+
+bool PipelineShared::createRenderTargets()
+{
+	/* With shared targets, this is only called upon resizes */
+	for( uint32 i = 0; i < _renderTargets.size(); ++i )
+	{
+		RenderTarget &rt = *_renderTargets[i];
+
+		uint32 width = (int)(rt.width * rt.scale), height = (int)(rt.height * rt.scale);
+		if( width == 0 ) width = (int)(Modules::renderer().getVPWidth() * rt.scale);
+		if( height == 0 ) height = (int)(Modules::renderer().getVPHeight() * rt.scale);
+
+		rt.rendBuf = Modules::renderer().createRenderBuffer(
+			width, height, rt.format, rt.hasDepthBuf, rt.numColBufs, rt.bilinear, 0 );
+		if( rt.rendBuf.fbo == 0 ) return false;
+
+		if( rt.samples > 0 )
+		{
+			// Also create a multisampled renderbuffer
+			rt.rendBufMultisample = Modules::renderer().createRenderBuffer(
+				width, height, rt.format, rt.hasDepthBuf, rt.numColBufs, rt.bilinear, rt.samples );
+			if( rt.rendBufMultisample.fbo == 0 ) return false;
+		}
+	}
+
+	return true;
+}
+
+bool PipelineShared::createNewRenderTargets()
+{
+	while ( !_newRenderTargets.empty() )
+	{
+		RenderTarget &rt =  *_renderTargets[_newRenderTargets.front()];
+		_newRenderTargets.pop_front();
+
+		uint32 width = (int)(rt.width * rt.scale), height = (int)(rt.height * rt.scale);
+		if( width == 0 ) width = (int)(Modules::renderer().getVPWidth() * rt.scale);
+		if( height == 0 ) height = (int)(Modules::renderer().getVPHeight() * rt.scale);
+
+		rt.rendBuf = Modules::renderer().createRenderBuffer(
+			width, height, rt.format, rt.hasDepthBuf, rt.numColBufs, rt.bilinear, 0 );
+		if( rt.rendBuf.fbo == 0 ) return false;
+
+		if( rt.samples > 0 )
+		{
+			// Also create a multisampled renderbuffer
+			rt.rendBufMultisample = Modules::renderer().createRenderBuffer(
+				width, height, rt.format, rt.hasDepthBuf, rt.numColBufs, rt.bilinear, rt.samples );
+			if( rt.rendBufMultisample.fbo == 0 ) return false;
+		}
+	}
+
+	return true;
+}
+
+void PipelineShared::destroyRenderTargets()
+{
+	for( uint32 i = 0; i < _renderTargets.size(); ++i )
+	{
+		RenderTarget &rt = *_renderTargets[i];
+
+		Modules::renderer().destroyRenderBuffer( rt.rendBuf );
+		delete _renderTargets[i];
+	}
+}
+
+void PipelineShared::resize()
+{
+	// Recreate render targets
+	destroyRenderTargets();
+	createRenderTargets();
+}
+
+
 PipelineResource::PipelineResource( const string &name, int flags ) :
 	Resource( ResourceTypes::Pipeline, name, flags )
 {
@@ -253,7 +366,7 @@
 }
 
 
-void PipelineResource::addRenderTarget( const string &id, bool depthBuf, uint32 numColBufs,
+void PipelineResource::addRenderTarget( const string &id, bool shared, bool depthBuf, uint32 numColBufs,
 										RenderBufferFormats::List format, bool bilinear, uint32 samples,
 										uint32 width, uint32 height, float scale )
 {
@@ -262,6 +375,7 @@
 	RenderTarget rt;
 	
 	rt.id = id;
+	rt.shared=shared;
 	rt.hasDepthBuf = depthBuf;
 	rt.numColBufs = numColBufs;
 	rt.format = format;
@@ -271,7 +385,9 @@
 	rt.height = height;
 	rt.scale = scale;
 
-	_renderTargets.push_back( rt );
+
+	if (!shared) _renderTargets.push_back( rt );
+	else PipelineShared::getInstance()->addRenderTarget( rt );
 }
 
 
@@ -286,8 +402,8 @@
 			return &_renderTargets[i];
 		}
 	}
-	
-	return 0x0;
+
+	return PipelineShared::getInstance()->findRenderTarget(id);
 }
 
 
@@ -354,7 +470,12 @@
 		{
 			if( node2.getAttribute( "id" ) == 0x0 ) return raiseError( "Missing RenderTarget attribute 'id'" );
 			string id = node2.getAttribute( "id" );
-			
+
+			bool shared = false;
+			if ( _stricmp( node2.getAttribute( "shared", "false"), "true" ) == 0 ||
+					_stricmp( node2.getAttribute( "shared", "0" ), "1" ) == 0 )
+				shared = true;
+
 			if( node2.getAttribute( "depthBuf" ) == 0x0 ) return raiseError( "Missing RenderTarget attribute 'depthBuf'" );
 			bool depth = false;
 			if( _stricmp( node2.getAttribute( "depthBuf" ), "true" ) == 0 ) depth = true;
@@ -385,7 +506,7 @@
 			uint32 height = atoi( node2.getAttribute( "height", "0" ) );
 			float scale = (float)atof( node2.getAttribute( "scale", "1" ) );
 
-			addRenderTarget( id, depth, numBuffers, format, bilinear,
+			addRenderTarget( id, shared, depth, numBuffers, format, bilinear,
 				min( maxSamples, Modules::config().sampleCount ), width, height, scale );
 
 			node2 = node1.getChildNode( "RenderTarget", ++nodeItr2 );
@@ -409,6 +530,9 @@
 		}
 	}
 
+	// Create new shared render targets
+	PipelineShared::getInstance()->createNewRenderTargets();
+
 	// Create render targets
 	if( !createRenderTargets() )
 	{
Index: egPipeline.h
===================================================================
--- egPipeline.h	(revision 40)
+++ egPipeline.h	(working copy)
@@ -29,6 +29,7 @@
 #include "egRendererBase.h"
 #include "egResource.h"
 #include "egMaterial.h"
+#include <list>
 #include <string>
 #include <vector>
 using namespace std;
@@ -140,6 +141,7 @@
 struct RenderTarget
 {
 	string						id;
+	bool						shared;		// Whether render target should be usable in all pipelines
 	bool						hasDepthBuf;
 	uint32						numColBufs;
 	RenderBufferFormats::List	format;
@@ -157,7 +159,33 @@
 	}
 };
 
+// Singleton class to share e.g. render targets across pipelines
+class PipelineShared
+{
+private:
+    static bool instanceFlag;
+    static PipelineShared *single;
 
+    vector< RenderTarget * >		_renderTargets; //  PipelineCommands assume the _renderTargets' addresses stay constant, so do not store them directly in the container..
+	list< size_t >		_newRenderTargets;
+
+	void addRenderTarget( const RenderTarget & );
+    RenderTarget *findRenderTarget( const string &id );
+	bool createRenderTargets();
+	bool createNewRenderTargets();
+	void destroyRenderTargets();
+
+    PipelineShared() { } // private constructor
+
+public:
+    static PipelineShared* getInstance();
+    ~PipelineShared()	{ instanceFlag = false; destroyRenderTargets(); }
+
+	void resize();
+
+    friend class PipelineResource;
+};
+
 class PipelineResource : public Resource
 {
 private:
@@ -168,7 +196,7 @@
 	bool raiseError( const string &msg, int line = -1 );
 	const string parseStage( XMLNode &node, PipelineStage &stage );
 
-	void addRenderTarget( const string &id, bool depthBuffer, uint32 numBuffers,
+	void addRenderTarget( const string &id, bool shared, bool depthBuffer, uint32 numBuffers,
 						  RenderBufferFormats::List format, bool bilinear, uint32 samples,
 						  uint32 width, uint32 height, float scale );
 	RenderTarget *findRenderTarget( const string &id );
