Răsfoiți Sursa

Few more classes ported

Marko Pintera 13 ani în urmă
părinte
comite
7f3dbd19c9

+ 7 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -86,6 +86,7 @@
     <ClInclude Include="OgreBitwise.h" />
     <ClInclude Include="OgreBuildSettings.h" />
     <ClInclude Include="OgreColourValue.h" />
+    <ClInclude Include="OgreCommon.h" />
     <ClInclude Include="OgreConfig.h" />
     <ClInclude Include="OgreD3D9Prerequisites.h" />
     <ClInclude Include="OgreD3D9Resource.h" />
@@ -102,6 +103,7 @@
     <ClInclude Include="OgreMath.h" />
     <ClInclude Include="OgreMatrix3.h" />
     <ClInclude Include="OgreMatrix4.h" />
+    <ClInclude Include="OgrePixelFormat.h" />
     <ClInclude Include="OgrePlane.h" />
     <ClInclude Include="OgrePlatform.h" />
     <ClInclude Include="OgrePlatformInformation.h" />
@@ -110,6 +112,7 @@
     <ClInclude Include="OgreQuaternion.h" />
     <ClInclude Include="OgreRay.h" />
     <ClInclude Include="OgreRenderSystemCapabilities.h" />
+    <ClInclude Include="OgreRenderTarget.h" />
     <ClInclude Include="OgreSharedPtr.h" />
     <ClInclude Include="OgreSingleton.h" />
     <ClInclude Include="OgreSphere.h" />
@@ -122,6 +125,7 @@
     <ClInclude Include="OgreVector3.h" />
     <ClInclude Include="OgreVector4.h" />
     <ClInclude Include="OgreVertexIndexData.h" />
+    <ClInclude Include="OgreViewport.h" />
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="targetver.h" />
   </ItemGroup>
@@ -141,15 +145,18 @@
     <ClCompile Include="OgreMath.cpp" />
     <ClCompile Include="OgreMatrix3.cpp" />
     <ClCompile Include="OgreMatrix4.cpp" />
+    <ClCompile Include="OgrePixelFormat.cpp" />
     <ClCompile Include="OgrePlane.cpp" />
     <ClCompile Include="OgreQuaternion.cpp" />
     <ClCompile Include="OgreRenderSystemCapabilities.cpp" />
+    <ClCompile Include="OgreRenderTarget.cpp" />
     <ClCompile Include="OgreString.cpp" />
     <ClCompile Include="OgreStringConverter.cpp" />
     <ClCompile Include="OgreVector2.cpp" />
     <ClCompile Include="OgreVector3.cpp" />
     <ClCompile Include="OgreVector4.cpp" />
     <ClCompile Include="OgreVertexIndexData.cpp" />
+    <ClCompile Include="OgreViewport.cpp" />
     <ClCompile Include="stdafx.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 21 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -168,6 +168,18 @@
     <ClInclude Include="OgreFrustum.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="OgreViewport.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="OgreCommon.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="OgreRenderTarget.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="OgrePixelFormat.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="stdafx.cpp">
@@ -245,5 +257,14 @@
     <ClCompile Include="OgreFrustum.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="OgreViewport.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="OgreRenderTarget.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="OgrePixelFormat.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 843 - 0
CamelotRenderer/OgreCommon.h

@@ -0,0 +1,843 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+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 and this permission notice 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 THE
+AUTHORS OR COPYRIGHT HOLDERS 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.
+-----------------------------------------------------------------------------
+*/
+#ifndef __Common_H__
+#define __Common_H__
+// Common stuff
+
+#include "OgreString.h"
+
+#if defined ( OGRE_GCC_VISIBILITY )
+#   pragma GCC visibility push(default)
+#endif
+
+#include <utility>
+#include <sstream>
+
+#if defined ( OGRE_GCC_VISIBILITY )
+#   pragma GCC visibility pop
+#endif
+
+namespace Ogre {
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup General
+	*  @{
+	*/
+
+	/// Fast general hashing algorithm
+	uint32 _OgreExport FastHash (const char * data, int len, uint32 hashSoFar = 0);
+	/// Combine hashes with same style as boost::hash_combine
+	template <typename T>
+	uint32 HashCombine (uint32 hashSoFar, const T& data)
+	{
+		return FastHash((const char*)&data, sizeof(T), hashSoFar);
+	}
+
+
+    /** Comparison functions used for the depth/stencil buffer operations and 
+		others. */
+    enum CompareFunction
+    {
+        CMPF_ALWAYS_FAIL,
+        CMPF_ALWAYS_PASS,
+        CMPF_LESS,
+        CMPF_LESS_EQUAL,
+        CMPF_EQUAL,
+        CMPF_NOT_EQUAL,
+        CMPF_GREATER_EQUAL,
+        CMPF_GREATER
+    };
+
+    /** High-level filtering options providing shortcuts to settings the
+        minification, magnification and mip filters. */
+    enum TextureFilterOptions
+    {
+        /// Equal to: min=FO_POINT, mag=FO_POINT, mip=FO_NONE
+        TFO_NONE,
+        /// Equal to: min=FO_LINEAR, mag=FO_LINEAR, mip=FO_POINT
+        TFO_BILINEAR,
+        /// Equal to: min=FO_LINEAR, mag=FO_LINEAR, mip=FO_LINEAR
+        TFO_TRILINEAR,
+        /// Equal to: min=FO_ANISOTROPIC, max=FO_ANISOTROPIC, mip=FO_LINEAR
+		TFO_ANISOTROPIC
+    };
+
+    enum FilterType
+    {
+        /// The filter used when shrinking a texture
+        FT_MIN,
+        /// The filter used when magnifying a texture
+        FT_MAG,
+        /// The filter used when determining the mipmap
+        FT_MIP
+    };
+    /** Filtering options for textures / mipmaps. */
+    enum FilterOptions
+    {
+        /// No filtering, used for FILT_MIP to turn off mipmapping
+        FO_NONE,
+        /// Use the closest pixel
+        FO_POINT,
+        /// Average of a 2x2 pixel area, denotes bilinear for MIN and MAG, trilinear for MIP
+        FO_LINEAR,
+        /// Similar to FO_LINEAR, but compensates for the angle of the texture plane
+        FO_ANISOTROPIC
+    };
+
+    /** Light shading modes. */
+    enum ShadeOptions
+    {
+        SO_FLAT,
+        SO_GOURAUD,
+        SO_PHONG
+    };
+
+    /** Fog modes. */
+    enum FogMode
+    {
+        /// No fog. Duh.
+        FOG_NONE,
+        /// Fog density increases  exponentially from the camera (fog = 1/e^(distance * density))
+        FOG_EXP,
+        /// Fog density increases at the square of FOG_EXP, i.e. even quicker (fog = 1/e^(distance * density)^2)
+        FOG_EXP2,
+        /// Fog density increases linearly between the start and end distances
+        FOG_LINEAR
+    };
+
+    /** Hardware culling modes based on vertex winding.
+        This setting applies to how the hardware API culls triangles it is sent. */
+    enum CullingMode
+    {
+        /// Hardware never culls triangles and renders everything it receives.
+        CULL_NONE = 1,
+        /// Hardware culls triangles whose vertices are listed clockwise in the view (default).
+        CULL_CLOCKWISE = 2,
+        /// Hardware culls triangles whose vertices are listed anticlockwise in the view.
+        CULL_ANTICLOCKWISE = 3
+    };
+
+    /** Manual culling modes based on vertex normals.
+        This setting applies to how the software culls triangles before sending them to the 
+		hardware API. This culling mode is used by scene managers which choose to implement it -
+		normally those which deal with large amounts of fixed world geometry which is often 
+		planar (software culling movable variable geometry is expensive). */
+    enum ManualCullingMode
+    {
+        /// No culling so everything is sent to the hardware.
+        MANUAL_CULL_NONE = 1,
+        /// Cull triangles whose normal is pointing away from the camera (default).
+        MANUAL_CULL_BACK = 2,
+        /// Cull triangles whose normal is pointing towards the camera.
+        MANUAL_CULL_FRONT = 3
+    };
+
+    /** Enumerates the wave types usable with the Ogre engine. */
+    enum WaveformType
+    {
+        /// Standard sine wave which smoothly changes from low to high and back again.
+        WFT_SINE,
+        /// An angular wave with a constant increase / decrease speed with pointed peaks.
+        WFT_TRIANGLE,
+        /// Half of the time is spent at the min, half at the max with instant transition between.
+        WFT_SQUARE,
+        /// Gradual steady increase from min to max over the period with an instant return to min at the end.
+        WFT_SAWTOOTH,
+        /// Gradual steady decrease from max to min over the period, with an instant return to max at the end.
+        WFT_INVERSE_SAWTOOTH,
+		/// Pulse Width Modulation. Works like WFT_SQUARE, except the high to low transition is controlled by duty cycle. 
+		/// With a duty cycle of 50% (0.5) will give the same output as WFT_SQUARE.
+		WFT_PWM
+    };
+
+    /** The polygon mode to use when rasterising. */
+    enum PolygonMode
+    {
+		/// Only points are rendered.
+        PM_POINTS = 1,
+		/// Wireframe models are rendered.
+        PM_WIREFRAME = 2,
+		/// Solid polygons are rendered.
+        PM_SOLID = 3
+    };
+
+    /** An enumeration of broad shadow techniques */
+    enum ShadowTechnique
+    {
+        /** No shadows */
+        SHADOWTYPE_NONE = 0x00,
+		/** Mask for additive shadows (not for direct use, use  SHADOWTYPE_ enum instead)
+		*/
+		SHADOWDETAILTYPE_ADDITIVE = 0x01,
+		/** Mask for modulative shadows (not for direct use, use  SHADOWTYPE_ enum instead)
+		*/
+		SHADOWDETAILTYPE_MODULATIVE = 0x02,
+		/** Mask for integrated shadows (not for direct use, use SHADOWTYPE_ enum instead)
+		*/
+		SHADOWDETAILTYPE_INTEGRATED = 0x04,
+		/** Mask for stencil shadows (not for direct use, use  SHADOWTYPE_ enum instead)
+		*/
+		SHADOWDETAILTYPE_STENCIL = 0x10,
+		/** Mask for texture shadows (not for direct use, use  SHADOWTYPE_ enum instead)
+		*/
+		SHADOWDETAILTYPE_TEXTURE = 0x20,
+		
+        /** Stencil shadow technique which renders all shadow volumes as
+            a modulation after all the non-transparent areas have been 
+            rendered. This technique is considerably less fillrate intensive 
+            than the additive stencil shadow approach when there are multiple
+            lights, but is not an accurate model. 
+        */
+        SHADOWTYPE_STENCIL_MODULATIVE = 0x12,
+        /** Stencil shadow technique which renders each light as a separate
+            additive pass to the scene. This technique can be very fillrate
+            intensive because it requires at least 2 passes of the entire
+            scene, more if there are multiple lights. However, it is a more
+            accurate model than the modulative stencil approach and this is
+            especially apparent when using coloured lights or bump mapping.
+        */
+        SHADOWTYPE_STENCIL_ADDITIVE = 0x11,
+        /** Texture-based shadow technique which involves a monochrome render-to-texture
+            of the shadow caster and a projection of that texture onto the 
+            shadow receivers as a modulative pass. 
+        */
+        SHADOWTYPE_TEXTURE_MODULATIVE = 0x22,
+		
+        /** Texture-based shadow technique which involves a render-to-texture
+            of the shadow caster and a projection of that texture onto the 
+            shadow receivers, built up per light as additive passes. 
+			This technique can be very fillrate intensive because it requires numLights + 2 
+			passes of the entire scene. However, it is a more accurate model than the 
+			modulative approach and this is especially apparent when using coloured lights 
+			or bump mapping.
+        */
+        SHADOWTYPE_TEXTURE_ADDITIVE = 0x21,
+
+		/** Texture-based shadow technique which involves a render-to-texture
+		of the shadow caster and a projection of that texture on to the shadow
+		receivers, with the usage of those shadow textures completely controlled
+		by the materials of the receivers.
+		This technique is easily the most flexible of all techniques because 
+		the material author is in complete control over how the shadows are
+		combined with regular rendering. It can perform shadows as accurately
+		as SHADOWTYPE_TEXTURE_ADDITIVE but more efficiently because it requires
+		less passes. However it also requires more expertise to use, and 
+		in almost all cases, shader capable hardware to really use to the full.
+		@note The 'additive' part of this mode means that the colour of
+		the rendered shadow texture is by default plain black. It does
+		not mean it does the adding on your receivers automatically though, how you
+		use that result is up to you.
+		*/
+		SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED = 0x25,
+		/** Texture-based shadow technique which involves a render-to-texture
+			of the shadow caster and a projection of that texture on to the shadow
+			receivers, with the usage of those shadow textures completely controlled
+			by the materials of the receivers.
+			This technique is easily the most flexible of all techniques because 
+			the material author is in complete control over how the shadows are
+			combined with regular rendering. It can perform shadows as accurately
+			as SHADOWTYPE_TEXTURE_ADDITIVE but more efficiently because it requires
+			less passes. However it also requires more expertise to use, and 
+			in almost all cases, shader capable hardware to really use to the full.
+			@note The 'modulative' part of this mode means that the colour of
+			the rendered shadow texture is by default the 'shadow colour'. It does
+			not mean it modulates on your receivers automatically though, how you
+			use that result is up to you.
+		*/
+		SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED = 0x26
+    };
+
+    /** An enumeration describing which material properties should track the vertex colours */
+    typedef int TrackVertexColourType;
+    enum TrackVertexColourEnum {
+        TVC_NONE        = 0x0,
+        TVC_AMBIENT     = 0x1,        
+        TVC_DIFFUSE     = 0x2,
+        TVC_SPECULAR    = 0x4,
+        TVC_EMISSIVE    = 0x8
+    };
+
+    /** Sort mode for billboard-set and particle-system */
+    enum SortMode
+    {
+        /** Sort by direction of the camera */
+        SM_DIRECTION,
+        /** Sort by distance from the camera */
+        SM_DISTANCE
+    };
+
+    /** Defines the frame buffer types. */
+    enum FrameBufferType {
+        FBT_COLOUR  = 0x1,
+        FBT_DEPTH   = 0x2,
+        FBT_STENCIL = 0x4
+    };
+    
+	
+	/** A hashed vector.
+	*/
+	template <typename T>
+	class HashedVector
+	{
+	public:
+		typedef std::vector<T> VectorImpl;
+	protected:
+		VectorImpl mList;
+		mutable uint32 mListHash;
+		mutable bool mListHashDirty;
+
+		void addToHash(const T& newPtr) const
+		{
+			mListHash = FastHash((const char*)&newPtr, sizeof(T), mListHash);
+		}
+		void recalcHash() const
+		{
+			mListHash = 0;
+			for (const_iterator i = mList.begin(); i != mList.end(); ++i)
+				addToHash(*i);
+			mListHashDirty = false;
+			
+		}
+
+	public:
+		typedef typename VectorImpl::value_type value_type;
+		typedef typename VectorImpl::pointer pointer;
+		typedef typename VectorImpl::reference reference;
+		typedef typename VectorImpl::const_reference const_reference;
+		typedef typename VectorImpl::size_type size_type;
+		typedef typename VectorImpl::difference_type difference_type;
+		typedef typename VectorImpl::iterator iterator;
+		typedef typename VectorImpl::const_iterator const_iterator;
+		typedef typename VectorImpl::reverse_iterator reverse_iterator;
+		typedef typename VectorImpl::const_reverse_iterator const_reverse_iterator;
+
+		void dirtyHash()
+		{
+			mListHashDirty = true;
+		}
+		bool isHashDirty() const
+		{
+			return mListHashDirty;
+		}
+
+		iterator begin() 
+		{ 
+			// we have to assume that hash needs recalculating on non-const
+			dirtyHash();
+			return mList.begin(); 
+		}
+		iterator end() { return mList.end(); }
+		const_iterator begin() const { return mList.begin(); }
+		const_iterator end() const { return mList.end(); }
+		reverse_iterator rbegin() 
+		{ 
+			// we have to assume that hash needs recalculating on non-const
+			dirtyHash();
+			return mList.rbegin(); 
+		}
+		reverse_iterator rend() { return mList.rend(); }
+		const_reverse_iterator rbegin() const { return mList.rbegin(); }
+		const_reverse_iterator rend() const { return mList.rend(); }
+		size_type size() const { return mList.size(); }
+		size_type max_size() const { return mList.max_size(); }
+		size_type capacity() const { return mList.capacity(); }
+		bool empty() const { return mList.empty(); }
+		reference operator[](size_type n) 
+		{ 
+			// we have to assume that hash needs recalculating on non-const
+			dirtyHash();
+			return mList[n]; 
+		}
+		const_reference operator[](size_type n) const { return mList[n]; }
+		reference at(size_type n) 
+		{ 
+			// we have to assume that hash needs recalculating on non-const
+			dirtyHash();
+			return mList.const_iterator(n); 
+		}
+		const_reference at(size_type n) const { return mList.at(n); }
+		HashedVector() : mListHash(0), mListHashDirty(false) {}
+		HashedVector(size_type n) : mList(n), mListHash(0), mListHashDirty(n > 0) {}
+		HashedVector(size_type n, const T& t) : mList(n, t), mListHash(0), mListHashDirty(n > 0) {}
+		HashedVector(const HashedVector<T>& rhs) 
+			: mList(rhs.mList), mListHash(rhs.mListHash), mListHashDirty(rhs.mListHashDirty) {}
+
+		template <class InputIterator>
+		HashedVector(InputIterator a, InputIterator b)
+			: mList(a, b), mListHashDirty(false)
+		{
+			dirtyHash();
+		}
+
+		~HashedVector() {}
+		HashedVector<T>& operator=(const HashedVector<T>& rhs)
+		{
+			mList = rhs.mList;
+			mListHash = rhs.mListHash;
+			mListHashDirty = rhs.mListHashDirty;
+			return *this;
+		}
+
+		void reserve(size_t t) { mList.reserve(t); }
+		reference front() 
+		{ 
+			// we have to assume that hash needs recalculating on non-const
+			dirtyHash();
+			return mList.front(); 
+		}
+		const_reference front() const { return mList.front(); }
+		reference back()  
+		{ 
+			// we have to assume that hash needs recalculating on non-const
+			dirtyHash();
+			return mList.back(); 
+		}
+		const_reference back() const { return mList.back(); }
+		void push_back(const T& t)
+		{ 
+			mList.push_back(t);
+			// Quick progressive hash add
+			if (!isHashDirty())
+				addToHash(t);
+		}
+		void pop_back()
+		{
+			mList.pop_back();
+			dirtyHash();
+		}
+		void swap(HashedVector<T>& rhs)
+		{
+			mList.swap(rhs.mList);
+			dirtyHash();
+		}
+		iterator insert(iterator pos, const T& t)
+		{
+			bool recalc = (pos != end());
+			iterator ret = mList.insert(pos, t);
+			if (recalc)
+				dirtyHash();
+			else
+				addToHash(t);
+			return ret;
+		}
+
+		template <class InputIterator>
+		void insert(iterator pos,
+			InputIterator f, InputIterator l)
+		{
+			mList.insert(pos, f, l);
+			dirtyHash();
+		}
+
+		void insert(iterator pos, size_type n, const T& x)
+		{
+			mList.insert(pos, n, x);
+			dirtyHash();
+		}
+
+		iterator erase(iterator pos)
+		{
+			iterator ret = mList.erase(pos);
+			dirtyHash();
+			return ret;
+		}
+		iterator erase(iterator first, iterator last)
+		{
+			iterator ret = mList.erase(first, last);
+			dirtyHash();
+			return ret;
+		}
+		void clear()
+		{
+			mList.clear();
+			mListHash = 0;
+			mListHashDirty = false;
+		}
+
+		void resize(size_type n, const T& t = T())
+		{
+			bool recalc = false;
+			if (n != size())
+				recalc = true;
+
+			mList.resize(n, t);
+			if (recalc)
+				dirtyHash();
+		}
+
+		bool operator==(const HashedVector<T>& b)
+		{ return mListHash == b.mListHash; }
+
+		bool operator<(const HashedVector<T>& b)
+		{ return mListHash < b.mListHash; }
+
+
+		/// Get the hash value
+		uint32 getHash() const 
+		{ 
+			if (isHashDirty())
+				recalcHash();
+
+			return mListHash; 
+		}
+	public:
+
+
+
+	};
+
+	class Light;
+	typedef HashedVector<Light*> LightList;
+
+
+
+    typedef map<String, bool>::type UnaryOptionList;
+    typedef map<String, String>::type BinaryOptionList;
+
+	/// Name / value parameter pair (first = name, second = value)
+	typedef map<String, String>::type NameValuePairList;
+
+    /// Alias / Texture name pair (first = alias, second = texture name)
+    typedef map<String, String>::type AliasTextureNamePairList;
+
+        template< typename T > struct TRect
+        {
+          T left, top, right, bottom;
+          TRect() : left(0), top(0), right(0), bottom(0) {}
+          TRect( T const & l, T const & t, T const & r, T const & b )
+            : left( l ), top( t ), right( r ), bottom( b )
+          {
+          }
+          TRect( TRect const & o )
+            : left( o.left ), top( o.top ), right( o.right ), bottom( o.bottom )
+          {
+          }
+          TRect & operator=( TRect const & o )
+          {
+            left = o.left;
+            top = o.top;
+            right = o.right;
+            bottom = o.bottom;
+            return *this;
+          }
+          T width() const
+          {
+            return right - left;
+          }
+          T height() const
+          {
+            return bottom - top;
+          }
+		  bool isNull() const
+		  {
+			  return width() == 0 || height() == 0;
+		  }
+		  void setNull()
+		  {
+			  left = right = top = bottom = 0;
+		  }
+		  TRect & merge(const TRect& rhs)
+		  {
+			  if (isNull())
+			  {
+				  *this = rhs;
+			  }
+			  else if (!rhs.isNull())
+			  {
+				  left = std::min(left, rhs.left);
+				  right = std::max(right, rhs.right);
+				  top = std::min(top, rhs.top);
+				  bottom = std::max(bottom, rhs.bottom);
+			  }
+
+			  return *this;
+
+		  }
+		  TRect intersect(const TRect& rhs) const
+		  {
+			  TRect ret;
+			  if (isNull() || rhs.isNull())
+			  {
+				  // empty
+				  return ret;
+			  }
+			  else
+			  {
+				  ret.left = std::max(left, rhs.left);
+				  ret.right = std::min(right, rhs.right);
+				  ret.top = std::max(top, rhs.top);
+				  ret.bottom = std::min(bottom, rhs.bottom);
+			  }
+
+			  if (ret.left > ret.right || ret.top > ret.bottom)
+			  {
+				  // no intersection, return empty
+				  ret.left = ret.top = ret.right = ret.bottom = 0;
+			  }
+
+			  return ret;
+
+		  }
+
+        };
+		template<typename T>
+		std::ostream& operator<<(std::ostream& o, const TRect<T>& r)
+		{
+			o << "TRect<>(l:" << r.left << ", t:" << r.top << ", r:" << r.right << ", b:" << r.bottom << ")";
+			return o;
+		}
+
+        /** Structure used to define a rectangle in a 2-D floating point space.
+        */
+        typedef TRect<float> FloatRect;
+
+		/** Structure used to define a rectangle in a 2-D floating point space, 
+			subject to double / single floating point settings.
+		*/
+		typedef TRect<Real> RealRect;
+
+        /** Structure used to define a rectangle in a 2-D integer space.
+        */
+        typedef TRect< long > Rect;
+
+        /** Structure used to define a box in a 3-D integer space.
+         	Note that the left, top, and front edges are included but the right, 
+         	bottom and back ones are not.
+         */
+        struct Box
+        {
+            size_t left, top, right, bottom, front, back;
+			/// Parameterless constructor for setting the members manually
+            Box()
+				: left(0), top(0), right(1), bottom(1), front(0), back(1)
+            {
+            }
+            /** Define a box from left, top, right and bottom coordinates
+            	This box will have depth one (front=0 and back=1).
+            	@param	l	x value of left edge
+            	@param	t	y value of top edge
+            	@param	r	x value of right edge
+            	@param	b	y value of bottom edge
+            	@note Note that the left, top, and front edges are included 
+ 		           	but the right, bottom and back ones are not.
+            */
+            Box( size_t l, size_t t, size_t r, size_t b ):
+                left(l),
+                top(t),   
+                right(r),
+                bottom(b),
+                front(0),
+                back(1)
+            {
+          		assert(right >= left && bottom >= top && back >= front);
+            }
+            /** Define a box from left, top, front, right, bottom and back
+            	coordinates.
+            	@param	l	x value of left edge
+            	@param	t	y value of top edge
+            	@param  ff  z value of front edge
+            	@param	r	x value of right edge
+            	@param	b	y value of bottom edge
+            	@param  bb  z value of back edge
+            	@note Note that the left, top, and front edges are included 
+ 		           	but the right, bottom and back ones are not.
+            */
+            Box( size_t l, size_t t, size_t ff, size_t r, size_t b, size_t bb ):
+                left(l),
+                top(t),   
+                right(r),
+                bottom(b),
+                front(ff),
+                back(bb)
+            {
+          		assert(right >= left && bottom >= top && back >= front);
+            }
+            
+            /// Return true if the other box is a part of this one
+            bool contains(const Box &def) const
+            {
+            	return (def.left >= left && def.top >= top && def.front >= front &&
+					def.right <= right && def.bottom <= bottom && def.back <= back);
+            }
+            
+            /// Get the width of this box
+            size_t getWidth() const { return right-left; }
+            /// Get the height of this box
+            size_t getHeight() const { return bottom-top; }
+            /// Get the depth of this box
+            size_t getDepth() const { return back-front; }
+        };
+
+    
+	
+	/** Locate command-line options of the unary form '-blah' and of the
+        binary form '-blah foo', passing back the index of the next non-option.
+    @param numargs, argv The standard parameters passed to the main method
+    @param unaryOptList Map of unary options (i.e. those that do not require a parameter).
+        Should be pre-populated with, for example '-e' in the key and false in the 
+        value. Options which are found will be set to true on return.
+    @param binOptList Map of binary options (i.e. those that require a parameter
+        e.g. '-e afile.txt').
+        Should be pre-populated with, for example '-e' and the default setting. 
+        Options which are found will have the value updated.
+    */
+    int _OgreExport findCommandLineOpts(int numargs, char** argv, UnaryOptionList& unaryOptList, 
+        BinaryOptionList& binOptList);
+
+	/// Generic result of clipping
+	enum ClipResult
+	{
+		/// Nothing was clipped
+		CLIPPED_NONE = 0,
+		/// Partially clipped
+		CLIPPED_SOME = 1, 
+		/// Everything was clipped away
+		CLIPPED_ALL = 2
+	};
+
+	/// Render window creation parameters.
+	struct RenderWindowDescription
+	{
+		String				name;
+		unsigned int		width;
+		unsigned int		height;
+		bool				useFullScreen;
+		NameValuePairList	miscParams;
+	};
+
+	/// Render window creation parameters container.
+	typedef vector<RenderWindowDescription>::type RenderWindowDescriptionList;
+
+	/// Render window container.
+	typedef vector<RenderWindow*>::type RenderWindowList;
+
+	/// Utility class to generate a sequentially numbered series of names
+	class _OgreExport NameGenerator
+	{
+	protected:
+		String mPrefix;
+		unsigned long long int mNext;
+		OGRE_AUTO_MUTEX
+	public:
+		NameGenerator(const NameGenerator& rhs)
+			: mPrefix(rhs.mPrefix), mNext(rhs.mNext) {}
+		
+		NameGenerator(const String& prefix) : mPrefix(prefix), mNext(1) {}
+
+		/// Generate a new name
+		String generate()
+		{
+			OGRE_LOCK_AUTO_MUTEX
+			std::ostringstream s;
+			s << mPrefix << mNext++;
+			return s.str();
+		}
+
+		/// Reset the internal counter
+		void reset()
+		{
+			OGRE_LOCK_AUTO_MUTEX
+			mNext = 1ULL;
+		}
+
+		/// Manually set the internal counter (use caution)
+		void setNext(unsigned long long int val)
+		{
+			OGRE_LOCK_AUTO_MUTEX
+			mNext = val;
+		}
+
+		/// Get the internal counter
+		unsigned long long int getNext() const
+		{
+			// lock even on get because 64-bit may not be atomic read
+			OGRE_LOCK_AUTO_MUTEX
+			return mNext;
+		}
+
+
+
+
+	};
+
+	/** Template class describing a simple pool of items.
+	*/
+	template <typename T>
+	class Pool
+	{
+	protected:
+		typedef typename list<T>::type ItemList;
+		ItemList mItems;
+		OGRE_AUTO_MUTEX
+	public:
+		Pool() {} 
+		virtual ~Pool() {}
+
+		/** Get the next item from the pool.
+		@returns pair indicating whether there was a free item, and the item if so
+		*/
+		virtual std::pair<bool, T> removeItem()
+		{
+			OGRE_LOCK_AUTO_MUTEX
+			std::pair<bool, T> ret;
+			if (mItems.empty())
+			{
+				ret.first = false;
+			}
+			else
+			{
+				ret.first = true;
+				ret.second = mItems.front();
+				mItems.pop_front();
+			}
+			return ret;
+		}
+
+		/** Add a new item to the pool. 
+		*/
+		virtual void addItem(const T& i)
+		{
+			OGRE_LOCK_AUTO_MUTEX
+			mItems.push_front(i);
+		}
+		/// Clear the pool
+		virtual void clear()
+		{
+			OGRE_LOCK_AUTO_MUTEX
+			mItems.clear();
+		}
+
+
+
+	};
+	/** @} */
+	/** @} */
+}
+
+#endif

+ 1383 - 0
CamelotRenderer/OgrePixelFormat.cpp

@@ -0,0 +1,1383 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+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 and this permission notice 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 THE
+AUTHORS OR COPYRIGHT HOLDERS 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.
+-----------------------------------------------------------------------------
+*/
+
+#include "OgrePixelFormat.h"
+#include "OgreBitwise.h"
+#include "OgreColourValue.h"
+#include "OgreException.h"
+
+
+namespace Ogre {
+
+    //-----------------------------------------------------------------------
+    /**
+    * A record that describes a pixel format in detail.
+    */
+    struct PixelFormatDescription {
+        /* Name of the format, as in the enum */
+        const char *name;
+        /* Number of bytes one element (colour value) takes. */
+        unsigned char elemBytes;
+        /* Pixel format flags, see enum PixelFormatFlags for the bit field
+        * definitions
+        */
+        uint32 flags;
+        /** Component type
+         */
+        PixelComponentType componentType;
+        /** Component count
+         */
+        unsigned char componentCount;
+        /* Number of bits for red(or luminance), green, blue, alpha
+        */
+        unsigned char rbits,gbits,bbits,abits; /*, ibits, dbits, ... */
+
+        /* Masks and shifts as used by packers/unpackers */
+        uint32 rmask, gmask, bmask, amask;
+        unsigned char rshift, gshift, bshift, ashift;
+    };
+    //-----------------------------------------------------------------------
+    /** Pixel format database */
+    PixelFormatDescription _pixelFormats[PF_COUNT] = {
+	//-----------------------------------------------------------------------
+        {"PF_UNKNOWN",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        0,
+        /* Component type and count */
+        PCT_BYTE, 0,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_L8",
+        /* Bytes per element */
+        1,
+        /* Flags */
+        PFF_LUMINANCE | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 1,
+        /* rbits, gbits, bbits, abits */
+        8, 0, 0, 0,
+        /* Masks and shifts */
+        0xFF, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_L16",
+        /* Bytes per element */
+        2,
+        /* Flags */
+        PFF_LUMINANCE | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_SHORT, 1,
+        /* rbits, gbits, bbits, abits */
+        16, 0, 0, 0,
+        /* Masks and shifts */
+        0xFFFF, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_A8",
+        /* Bytes per element */
+        1,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 1,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 8,
+        /* Masks and shifts */
+        0, 0, 0, 0xFF, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_A4L4",
+        /* Bytes per element */
+        1,
+        /* Flags */
+        PFF_HASALPHA | PFF_LUMINANCE | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 2,
+        /* rbits, gbits, bbits, abits */
+        4, 0, 0, 4,
+        /* Masks and shifts */
+        0x0F, 0, 0, 0xF0, 0, 0, 0, 4
+        },
+	//-----------------------------------------------------------------------
+        {"PF_BYTE_LA",
+        /* Bytes per element */
+        2,
+        /* Flags */
+        PFF_HASALPHA | PFF_LUMINANCE,
+        /* Component type and count */
+        PCT_BYTE, 2,
+        /* rbits, gbits, bbits, abits */
+        8, 0, 0, 8,
+        /* Masks and shifts */
+        0,0,0,0,0,0,0,0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_R5G6B5",
+        /* Bytes per element */
+        2,
+        /* Flags */
+        PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        5, 6, 5, 0,
+        /* Masks and shifts */
+        0xF800, 0x07E0, 0x001F, 0,
+        11, 5, 0, 0
+        },
+	//-----------------------------------------------------------------------
+		{"PF_B5G6R5",
+        /* Bytes per element */
+        2,
+        /* Flags */
+        PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        5, 6, 5, 0,
+        /* Masks and shifts */
+        0x001F, 0x07E0, 0xF800, 0,
+        0, 5, 11, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_A4R4G4B4",
+        /* Bytes per element */
+        2,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        4, 4, 4, 4,
+        /* Masks and shifts */
+        0x0F00, 0x00F0, 0x000F, 0xF000,
+        8, 4, 0, 12
+        },
+	//-----------------------------------------------------------------------
+        {"PF_A1R5G5B5",
+        /* Bytes per element */
+        2,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        5, 5, 5, 1,
+        /* Masks and shifts */
+        0x7C00, 0x03E0, 0x001F, 0x8000,
+        10, 5, 0, 15,
+        },
+	//-----------------------------------------------------------------------
+        {"PF_R8G8B8",
+        /* Bytes per element */
+        3,  // 24 bit integer -- special
+        /* Flags */
+        PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        8, 8, 8, 0,
+        /* Masks and shifts */
+        0xFF0000, 0x00FF00, 0x0000FF, 0,
+        16, 8, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_B8G8R8",
+        /* Bytes per element */
+        3,  // 24 bit integer -- special
+        /* Flags */
+        PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        8, 8, 8, 0,
+        /* Masks and shifts */
+        0x0000FF, 0x00FF00, 0xFF0000, 0,
+        0, 8, 16, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_A8R8G8B8",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        8, 8, 8, 8,
+        /* Masks and shifts */
+        0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
+        16, 8, 0, 24
+        },
+	//-----------------------------------------------------------------------
+        {"PF_A8B8G8R8",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        8, 8, 8, 8,
+        /* Masks and shifts */
+        0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000,
+        0, 8, 16, 24,
+        },
+	//-----------------------------------------------------------------------
+        {"PF_B8G8R8A8",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        8, 8, 8, 8,
+        /* Masks and shifts */
+        0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF,
+        8, 16, 24, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_A2R10G10B10",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        10, 10, 10, 2,
+        /* Masks and shifts */
+        0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000,
+        20, 10, 0, 30
+        },
+	//-----------------------------------------------------------------------
+        {"PF_A2B10G10R10",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        10, 10, 10, 2,
+        /* Masks and shifts */
+        0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000,
+        0, 10, 20, 30
+        },
+	//-----------------------------------------------------------------------
+        {"PF_DXT1",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_BYTE, 3, // No alpha
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_DXT2",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_DXT3",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_DXT4",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_DXT5",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_FLOAT16_RGB",
+        /* Bytes per element */
+        6,
+        /* Flags */
+        PFF_FLOAT,
+        /* Component type and count */
+        PCT_FLOAT16, 3,
+        /* rbits, gbits, bbits, abits */
+        16, 16, 16, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_FLOAT16_RGBA",
+        /* Bytes per element */
+        8,
+        /* Flags */
+        PFF_FLOAT | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_FLOAT16, 4,
+        /* rbits, gbits, bbits, abits */
+        16, 16, 16, 16,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_FLOAT32_RGB",
+        /* Bytes per element */
+        12,
+        /* Flags */
+        PFF_FLOAT,
+        /* Component type and count */
+        PCT_FLOAT32, 3,
+        /* rbits, gbits, bbits, abits */
+        32, 32, 32, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_FLOAT32_RGBA",
+        /* Bytes per element */
+        16,
+        /* Flags */
+        PFF_FLOAT | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_FLOAT32, 4,
+        /* rbits, gbits, bbits, abits */
+        32, 32, 32, 32,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_X8R8G8B8",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        8, 8, 8, 0,
+        /* Masks and shifts */
+        0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
+        16, 8, 0, 24
+        },
+	//-----------------------------------------------------------------------
+        {"PF_X8B8G8R8",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        8, 8, 8, 0,
+        /* Masks and shifts */
+        0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000,
+        0, 8, 16, 24
+        },
+	//-----------------------------------------------------------------------
+        {"PF_R8G8B8A8",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_HASALPHA | PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        8, 8, 8, 8,
+        /* Masks and shifts */
+        0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF,
+        24, 16, 8, 0
+        },
+	//-----------------------------------------------------------------------
+		{"PF_DEPTH",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_DEPTH,
+        /* Component type and count */
+        PCT_FLOAT32, 1, // ?
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+		0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+		{"PF_SHORT_RGBA",
+		/* Bytes per element */
+        8,
+        /* Flags */
+        PFF_HASALPHA,
+        /* Component type and count */
+        PCT_SHORT, 4,
+        /* rbits, gbits, bbits, abits */
+        16, 16, 16, 16,
+        /* Masks and shifts */
+		0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_R3G3B2",
+        /* Bytes per element */
+        1,
+        /* Flags */
+        PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        3, 3, 2, 0,
+        /* Masks and shifts */
+        0xE0, 0x1C, 0x03, 0,
+        5, 2, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_FLOAT16_R",
+        /* Bytes per element */
+        2,
+        /* Flags */
+        PFF_FLOAT,
+        /* Component type and count */
+        PCT_FLOAT16, 1,
+        /* rbits, gbits, bbits, abits */
+        16, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_FLOAT32_R",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_FLOAT,
+        /* Component type and count */
+        PCT_FLOAT32, 1,
+        /* rbits, gbits, bbits, abits */
+        32, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_SHORT_GR",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_NATIVEENDIAN,
+        /* Component type and count */
+        PCT_SHORT, 2,
+        /* rbits, gbits, bbits, abits */
+        16, 16, 0, 0,
+        /* Masks and shifts */
+        0x0000FFFF, 0xFFFF0000, 0, 0, 
+		0, 16, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_FLOAT16_GR",
+        /* Bytes per element */
+        4,
+        /* Flags */
+        PFF_FLOAT,
+        /* Component type and count */
+        PCT_FLOAT16, 2,
+        /* rbits, gbits, bbits, abits */
+        16, 16, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+        {"PF_FLOAT32_GR",
+        /* Bytes per element */
+        8,
+        /* Flags */
+        PFF_FLOAT,
+        /* Component type and count */
+        PCT_FLOAT32, 2,
+        /* rbits, gbits, bbits, abits */
+        32, 32, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+	//-----------------------------------------------------------------------
+		{"PF_SHORT_RGB",
+		/* Bytes per element */
+        6,
+        /* Flags */
+        0,
+        /* Component type and count */
+        PCT_SHORT, 3,
+        /* rbits, gbits, bbits, abits */
+        16, 16, 16, 0,
+        /* Masks and shifts */
+		0, 0, 0, 0, 0, 0, 0, 0
+        },
+    //-----------------------------------------------------------------------
+		{"PF_PVRTC_RGB2",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+    //-----------------------------------------------------------------------
+		{"PF_PVRTC_RGBA2",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+    //-----------------------------------------------------------------------
+		{"PF_PVRTC_RGB4",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED,
+        /* Component type and count */
+        PCT_BYTE, 3,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+    //-----------------------------------------------------------------------
+		{"PF_PVRTC_RGBA4",
+        /* Bytes per element */
+        0,
+        /* Flags */
+        PFF_COMPRESSED | PFF_HASALPHA,
+        /* Component type and count */
+        PCT_BYTE, 4,
+        /* rbits, gbits, bbits, abits */
+        0, 0, 0, 0,
+        /* Masks and shifts */
+        0, 0, 0, 0, 0, 0, 0, 0
+        },
+        
+    };
+    //-----------------------------------------------------------------------
+	size_t PixelBox::getConsecutiveSize() const
+	{
+		return PixelUtil::getMemorySize(getWidth(), getHeight(), getDepth(), format);
+	}
+	PixelBox PixelBox::getSubVolume(const Box &def) const
+	{
+		if(PixelUtil::isCompressed(format))
+		{
+			if(def.left == left && def.top == top && def.front == front &&
+			   def.right == right && def.bottom == bottom && def.back == back)
+			{
+				// Entire buffer is being queried
+				return *this;
+			}
+			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot return subvolume of compressed PixelBuffer", "PixelBox::getSubVolume");
+		}
+		if(!contains(def))
+			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Bounds out of range", "PixelBox::getSubVolume");
+
+		const size_t elemSize = PixelUtil::getNumElemBytes(format);
+		// Calculate new data origin
+		// Notice how we do not propagate left/top/front from the incoming box, since
+		// the returned pointer is already offset
+		PixelBox rval(def.getWidth(), def.getHeight(), def.getDepth(), format, 
+			((uint8*)data) + ((def.left-left)*elemSize)
+			+ ((def.top-top)*rowPitch*elemSize)
+			+ ((def.front-front)*slicePitch*elemSize)
+		);
+
+		rval.rowPitch = rowPitch;
+		rval.slicePitch = slicePitch;
+		rval.format = format;
+
+		return rval;
+	}
+    //-----------------------------------------------------------------------
+    /**
+    * Directly get the description record for provided pixel format. For debug builds,
+    * this checks the bounds of fmt with an assertion.
+    */
+    static inline const PixelFormatDescription &getDescriptionFor(const PixelFormat fmt)
+    {
+        const int ord = (int)fmt;
+        assert(ord>=0 && ord<PF_COUNT);
+
+        return _pixelFormats[ord];
+    }
+    //-----------------------------------------------------------------------
+    size_t PixelUtil::getNumElemBytes( PixelFormat format )
+    {
+        return getDescriptionFor(format).elemBytes;
+    }
+	//-----------------------------------------------------------------------
+	size_t PixelUtil::getMemorySize(size_t width, size_t height, size_t depth, PixelFormat format)
+	{
+		if(isCompressed(format))
+		{
+			switch(format)
+			{
+				// DXT formats work by dividing the image into 4x4 blocks, then encoding each
+				// 4x4 block with a certain number of bytes. 
+				case PF_DXT1:
+					return ((width+3)/4)*((height+3)/4)*8 * depth;
+				case PF_DXT2:
+				case PF_DXT3:
+				case PF_DXT4:
+				case PF_DXT5:
+					return ((width+3)/4)*((height+3)/4)*16 * depth;
+
+                // Size calculations from the PVRTC OpenGL extension spec
+                // http://www.khronos.org/registry/gles/extensions/IMG/IMG_texture_compression_pvrtc.txt
+                // Basically, 32 bytes is the minimum texture size.  Smaller textures are padded up to 32 bytes
+                case PF_PVRTC_RGB2:
+                case PF_PVRTC_RGBA2:
+					assert(depth == 1);
+                    return (std::max((int)width, 16) * std::max((int)height, 8) * 2 + 7) / 8;
+                case PF_PVRTC_RGB4:
+                case PF_PVRTC_RGBA4:
+					assert(depth == 1);
+                    return (std::max((int)width, 8) * std::max((int)height, 8) * 4 + 7) / 8;
+				default:
+				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid compressed pixel format",
+					"PixelUtil::getMemorySize");
+			}
+		}
+		else
+		{
+			return width*height*depth*getNumElemBytes(format);
+		}
+	}
+    //-----------------------------------------------------------------------
+    size_t PixelUtil::getNumElemBits( PixelFormat format )
+    {
+        return getDescriptionFor(format).elemBytes * 8;
+    }
+    //-----------------------------------------------------------------------
+    unsigned int PixelUtil::getFlags( PixelFormat format )
+    {
+        return getDescriptionFor(format).flags;
+    }
+    //-----------------------------------------------------------------------
+    bool PixelUtil::hasAlpha(PixelFormat format)
+    {
+        return (PixelUtil::getFlags(format) & PFF_HASALPHA) > 0;
+    }
+    //-----------------------------------------------------------------------
+    bool PixelUtil::isFloatingPoint(PixelFormat format)
+    {
+        return (PixelUtil::getFlags(format) & PFF_FLOAT) > 0;
+    }
+    //-----------------------------------------------------------------------
+    bool PixelUtil::isCompressed(PixelFormat format)
+    {
+        return (PixelUtil::getFlags(format) & PFF_COMPRESSED) > 0;
+    }
+    //-----------------------------------------------------------------------
+    bool PixelUtil::isDepth(PixelFormat format)
+    {
+        return (PixelUtil::getFlags(format) & PFF_DEPTH) > 0;
+    }
+    //-----------------------------------------------------------------------
+    bool PixelUtil::isNativeEndian(PixelFormat format)
+    {
+        return (PixelUtil::getFlags(format) & PFF_NATIVEENDIAN) > 0;
+    }
+    //-----------------------------------------------------------------------
+    bool PixelUtil::isLuminance(PixelFormat format)
+    {
+        return (PixelUtil::getFlags(format) & PFF_LUMINANCE) > 0;
+    }
+    //-----------------------------------------------------------------------
+	bool PixelUtil::isValidExtent(size_t width, size_t height, size_t depth, PixelFormat format)
+	{
+		if(isCompressed(format))
+		{
+			switch(format)
+			{
+				case PF_DXT1:
+				case PF_DXT2:
+				case PF_DXT3:
+				case PF_DXT4:
+				case PF_DXT5:
+					return ((width&3)==0 && (height&3)==0 && depth==1);
+				default:
+					return true;
+			}
+		}
+		else
+		{
+			return true;
+		}
+	}
+	//-----------------------------------------------------------------------
+    void PixelUtil::getBitDepths(PixelFormat format, int rgba[4])
+    {
+        const PixelFormatDescription &des = getDescriptionFor(format);
+        rgba[0] = des.rbits;
+        rgba[1] = des.gbits;
+        rgba[2] = des.bbits;
+        rgba[3] = des.abits;
+    }
+	//-----------------------------------------------------------------------
+	void PixelUtil::getBitMasks(PixelFormat format, uint32 rgba[4])
+    {
+        const PixelFormatDescription &des = getDescriptionFor(format);
+        rgba[0] = des.rmask;
+        rgba[1] = des.gmask;
+        rgba[2] = des.bmask;
+        rgba[3] = des.amask;
+    }
+	//---------------------------------------------------------------------
+	void PixelUtil::getBitShifts(PixelFormat format, unsigned char rgba[4])
+	{
+		const PixelFormatDescription &des = getDescriptionFor(format);
+		rgba[0] = des.rshift;
+		rgba[1] = des.gshift;
+		rgba[2] = des.bshift;
+		rgba[3] = des.ashift;
+	}
+    //-----------------------------------------------------------------------
+    String PixelUtil::getFormatName(PixelFormat srcformat)
+    {
+        return getDescriptionFor(srcformat).name;
+    }
+    //-----------------------------------------------------------------------
+    bool PixelUtil::isAccessible(PixelFormat srcformat)
+    {
+        if (srcformat == PF_UNKNOWN)
+            return false;
+        unsigned int flags = getFlags(srcformat);
+        return !((flags & PFF_COMPRESSED) || (flags & PFF_DEPTH));
+    }
+    //-----------------------------------------------------------------------
+    PixelComponentType PixelUtil::getComponentType(PixelFormat fmt)
+    {
+        const PixelFormatDescription &des = getDescriptionFor(fmt);
+        return des.componentType;
+    }
+    //-----------------------------------------------------------------------
+    size_t PixelUtil::getComponentCount(PixelFormat fmt)
+    {
+        const PixelFormatDescription &des = getDescriptionFor(fmt);
+        return des.componentCount;
+    }
+    //-----------------------------------------------------------------------
+    PixelFormat PixelUtil::getFormatFromName(const String& name, bool accessibleOnly, bool caseSensitive)
+    {
+        String tmp = name;
+        if (!caseSensitive)
+        {
+            // We are stored upper-case format names.
+            StringUtil::toUpperCase(tmp);
+        }
+
+        for (int i = 0; i < PF_COUNT; ++i)
+        {
+            PixelFormat pf = static_cast<PixelFormat>(i);
+            if (!accessibleOnly || isAccessible(pf))
+            {
+                if (tmp == getFormatName(pf))
+                    return pf;
+            }
+        }
+        return PF_UNKNOWN;
+    }
+    //-----------------------------------------------------------------------
+    String PixelUtil::getBNFExpressionOfPixelFormats(bool accessibleOnly)
+    {
+        // Collect format names sorted by length, it's required by BNF compiler
+        // that similar tokens need longer ones comes first.
+        typedef multimap<String::size_type, String>::type FormatNameMap;
+        FormatNameMap formatNames;
+        for (size_t i = 0; i < PF_COUNT; ++i)
+        {
+            PixelFormat pf = static_cast<PixelFormat>(i);
+            if (!accessibleOnly || isAccessible(pf))
+            {
+                String formatName = getFormatName(pf);
+                formatNames.insert(std::make_pair(formatName.length(), formatName));
+            }
+        }
+
+        // Populate the BNF expression in reverse order
+        String result;
+        // Note: Stupid M$ VC7.1 can't dealing operator!= with FormatNameMap::const_reverse_iterator.
+        for (FormatNameMap::reverse_iterator j = formatNames.rbegin(); j != formatNames.rend(); ++j)
+        {
+            if (!result.empty())
+                result += " | ";
+            result += "'" + j->second + "'";
+        }
+
+        return result;
+    }
+    //-----------------------------------------------------------------------
+    PixelFormat PixelUtil::getFormatForBitDepths(PixelFormat fmt, ushort integerBits, ushort floatBits)
+    {
+        switch (integerBits)
+        {
+        case 16:
+            switch (fmt)
+            {
+            case PF_R8G8B8:
+            case PF_X8R8G8B8:
+                return PF_R5G6B5;
+
+            case PF_B8G8R8:
+            case PF_X8B8G8R8:
+                return PF_B5G6R5;
+
+            case PF_A8R8G8B8:
+            case PF_R8G8B8A8:
+            case PF_A8B8G8R8:
+            case PF_B8G8R8A8:
+                return PF_A4R4G4B4;
+
+            case PF_A2R10G10B10:
+            case PF_A2B10G10R10:
+                return PF_A1R5G5B5;
+
+            default:
+                // use original image format
+                break;
+            }
+            break;
+
+        case 32:
+            switch (fmt)
+            {
+            case PF_R5G6B5:
+                return PF_X8R8G8B8;
+
+            case PF_B5G6R5:
+                return PF_X8B8G8R8;
+
+            case PF_A4R4G4B4:
+                return PF_A8R8G8B8;
+
+            case PF_A1R5G5B5:
+                return PF_A2R10G10B10;
+
+            default:
+                // use original image format
+                break;
+            }
+            break;
+
+        default:
+            // use original image format
+            break;
+        }
+
+        switch (floatBits)
+        {
+        case 16:
+            switch (fmt)
+            {
+            case PF_FLOAT32_R:
+                return PF_FLOAT16_R;
+
+            case PF_FLOAT32_RGB:
+                return PF_FLOAT16_RGB;
+
+            case PF_FLOAT32_RGBA:
+                return PF_FLOAT16_RGBA;
+
+            default:
+                // use original image format
+                break;
+            }
+            break;
+
+        case 32:
+            switch (fmt)
+            {
+            case PF_FLOAT16_R:
+                return PF_FLOAT32_R;
+
+            case PF_FLOAT16_RGB:
+                return PF_FLOAT32_RGB;
+
+            case PF_FLOAT16_RGBA:
+                return PF_FLOAT32_RGBA;
+
+            default:
+                // use original image format
+                break;
+            }
+            break;
+
+        default:
+            // use original image format
+            break;
+        }
+
+        return fmt;
+    }
+    //-----------------------------------------------------------------------
+    /*************************************************************************
+    * Pixel packing/unpacking utilities
+    */
+    void PixelUtil::packColour(const ColourValue &colour, const PixelFormat pf,  void* dest)
+    {
+        packColour(colour.r, colour.g, colour.b, colour.a, pf, dest);
+    }
+    //-----------------------------------------------------------------------
+    void PixelUtil::packColour(const uint8 r, const uint8 g, const uint8 b, const uint8 a, const PixelFormat pf,  void* dest)
+    {
+        const PixelFormatDescription &des = getDescriptionFor(pf);
+        if(des.flags & PFF_NATIVEENDIAN) {
+            // Shortcut for integer formats packing
+            unsigned int value = ((Bitwise::fixedToFixed(r, 8, des.rbits)<<des.rshift) & des.rmask) |
+                ((Bitwise::fixedToFixed(g, 8, des.gbits)<<des.gshift) & des.gmask) |
+                ((Bitwise::fixedToFixed(b, 8, des.bbits)<<des.bshift) & des.bmask) |
+                ((Bitwise::fixedToFixed(a, 8, des.abits)<<des.ashift) & des.amask);
+            // And write to memory
+            Bitwise::intWrite(dest, des.elemBytes, value);
+        } else {
+            // Convert to float
+            packColour((float)r/255.0f,(float)g/255.0f,(float)b/255.0f,(float)a/255.0f, pf, dest);
+        }
+    }
+    //-----------------------------------------------------------------------
+    void PixelUtil::packColour(const float r, const float g, const float b, const float a, const PixelFormat pf,  void* dest)
+    {
+        // Catch-it-all here
+        const PixelFormatDescription &des = getDescriptionFor(pf);
+        if(des.flags & PFF_NATIVEENDIAN) {
+            // Do the packing
+            //std::cerr << dest << " " << r << " " << g <<  " " << b << " " << a << std::endl;
+            const unsigned int value = ((Bitwise::floatToFixed(r, des.rbits)<<des.rshift) & des.rmask) |
+                ((Bitwise::floatToFixed(g, des.gbits)<<des.gshift) & des.gmask) |
+                ((Bitwise::floatToFixed(b, des.bbits)<<des.bshift) & des.bmask) |
+                ((Bitwise::floatToFixed(a, des.abits)<<des.ashift) & des.amask);
+            // And write to memory
+            Bitwise::intWrite(dest, des.elemBytes, value);
+        } else {
+            switch(pf)
+            {
+            case PF_FLOAT32_R:
+                ((float*)dest)[0] = r;
+                break;
+			case PF_FLOAT32_GR:
+				((float*)dest)[0] = g;
+				((float*)dest)[1] = r;
+				break;
+            case PF_FLOAT32_RGB:
+                ((float*)dest)[0] = r;
+                ((float*)dest)[1] = g;
+                ((float*)dest)[2] = b;
+                break;
+            case PF_FLOAT32_RGBA:
+                ((float*)dest)[0] = r;
+                ((float*)dest)[1] = g;
+                ((float*)dest)[2] = b;
+                ((float*)dest)[3] = a;
+                break;
+            case PF_FLOAT16_R:
+                ((uint16*)dest)[0] = Bitwise::floatToHalf(r);
+                break;
+			case PF_FLOAT16_GR:
+				((uint16*)dest)[0] = Bitwise::floatToHalf(g);
+				((uint16*)dest)[1] = Bitwise::floatToHalf(r);
+				break;
+            case PF_FLOAT16_RGB:
+                ((uint16*)dest)[0] = Bitwise::floatToHalf(r);
+                ((uint16*)dest)[1] = Bitwise::floatToHalf(g);
+                ((uint16*)dest)[2] = Bitwise::floatToHalf(b);
+                break;
+            case PF_FLOAT16_RGBA:
+                ((uint16*)dest)[0] = Bitwise::floatToHalf(r);
+                ((uint16*)dest)[1] = Bitwise::floatToHalf(g);
+                ((uint16*)dest)[2] = Bitwise::floatToHalf(b);
+                ((uint16*)dest)[3] = Bitwise::floatToHalf(a);
+                break;
+            case PF_SHORT_RGB:
+				((uint16*)dest)[0] = (uint16)Bitwise::floatToFixed(r, 16);
+                ((uint16*)dest)[1] = (uint16)Bitwise::floatToFixed(g, 16);
+                ((uint16*)dest)[2] = (uint16)Bitwise::floatToFixed(b, 16);
+                break;
+			case PF_SHORT_RGBA:
+				((uint16*)dest)[0] = (uint16)Bitwise::floatToFixed(r, 16);
+                ((uint16*)dest)[1] = (uint16)Bitwise::floatToFixed(g, 16);
+                ((uint16*)dest)[2] = (uint16)Bitwise::floatToFixed(b, 16);
+                ((uint16*)dest)[3] = (uint16)Bitwise::floatToFixed(a, 16);
+				break;
+			case PF_BYTE_LA:
+				((uint8*)dest)[0] = (uint8)Bitwise::floatToFixed(r, 8);
+                ((uint8*)dest)[1] = (uint8)Bitwise::floatToFixed(a, 8);
+				break;
+            default:
+                // Not yet supported
+                OGRE_EXCEPT(
+                    Exception::ERR_NOT_IMPLEMENTED,
+                    "pack to "+getFormatName(pf)+" not implemented",
+                    "PixelUtil::packColour");
+                break;
+            }
+        }
+    }
+    //-----------------------------------------------------------------------
+    void PixelUtil::unpackColour(ColourValue *colour, PixelFormat pf,  const void* src)
+    {
+        unpackColour(&colour->r, &colour->g, &colour->b, &colour->a, pf, src);
+    }
+    //-----------------------------------------------------------------------
+    void PixelUtil::unpackColour(uint8 *r, uint8 *g, uint8 *b, uint8 *a, PixelFormat pf,  const void* src)
+    {
+        const PixelFormatDescription &des = getDescriptionFor(pf);
+        if(des.flags & PFF_NATIVEENDIAN) {
+            // Shortcut for integer formats unpacking
+            const unsigned int value = Bitwise::intRead(src, des.elemBytes);
+            if(des.flags & PFF_LUMINANCE)
+            {
+                // Luminance format -- only rbits used
+                *r = *g = *b = (uint8)Bitwise::fixedToFixed(
+                    (value & des.rmask)>>des.rshift, des.rbits, 8);
+            }
+            else
+            {
+                *r = (uint8)Bitwise::fixedToFixed((value & des.rmask)>>des.rshift, des.rbits, 8);
+                *g = (uint8)Bitwise::fixedToFixed((value & des.gmask)>>des.gshift, des.gbits, 8);
+                *b = (uint8)Bitwise::fixedToFixed((value & des.bmask)>>des.bshift, des.bbits, 8);
+            }
+            if(des.flags & PFF_HASALPHA)
+            {
+                *a = (uint8)Bitwise::fixedToFixed((value & des.amask)>>des.ashift, des.abits, 8);
+            }
+            else
+            {
+                *a = 255; // No alpha, default a component to full
+            }
+        } else {
+            // Do the operation with the more generic floating point
+            float rr, gg, bb, aa;
+            unpackColour(&rr,&gg,&bb,&aa, pf, src);
+            *r = (uint8)Bitwise::floatToFixed(rr, 8);
+            *g = (uint8)Bitwise::floatToFixed(gg, 8);
+            *b = (uint8)Bitwise::floatToFixed(bb, 8);
+            *a = (uint8)Bitwise::floatToFixed(aa, 8);
+        }
+    }
+    //-----------------------------------------------------------------------
+    void PixelUtil::unpackColour(float *r, float *g, float *b, float *a,
+        PixelFormat pf,  const void* src)
+    {
+        const PixelFormatDescription &des = getDescriptionFor(pf);
+        if(des.flags & PFF_NATIVEENDIAN) {
+            // Shortcut for integer formats unpacking
+            const unsigned int value = Bitwise::intRead(src, des.elemBytes);
+            if(des.flags & PFF_LUMINANCE)
+            {
+                // Luminance format -- only rbits used
+                *r = *g = *b = Bitwise::fixedToFloat(
+                    (value & des.rmask)>>des.rshift, des.rbits);
+            }
+            else
+            {
+                *r = Bitwise::fixedToFloat((value & des.rmask)>>des.rshift, des.rbits);
+                *g = Bitwise::fixedToFloat((value & des.gmask)>>des.gshift, des.gbits);
+                *b = Bitwise::fixedToFloat((value & des.bmask)>>des.bshift, des.bbits);
+            }
+            if(des.flags & PFF_HASALPHA)
+            {
+                *a = Bitwise::fixedToFloat((value & des.amask)>>des.ashift, des.abits);
+            }
+            else
+            {
+                *a = 1.0f; // No alpha, default a component to full
+            }
+        } else {
+            switch(pf)
+            {
+            case PF_FLOAT32_R:
+                *r = *g = *b = ((float*)src)[0];
+                *a = 1.0f;
+                break;
+			case PF_FLOAT32_GR:
+				*g = ((float*)src)[0];
+				*r = *b = ((float*)src)[1];
+				*a = 1.0f;
+				break;
+            case PF_FLOAT32_RGB:
+                *r = ((float*)src)[0];
+                *g = ((float*)src)[1];
+                *b = ((float*)src)[2];
+                *a = 1.0f;
+                break;
+            case PF_FLOAT32_RGBA:
+                *r = ((float*)src)[0];
+                *g = ((float*)src)[1];
+                *b = ((float*)src)[2];
+                *a = ((float*)src)[3];
+                break;
+            case PF_FLOAT16_R:
+                *r = *g = *b = Bitwise::halfToFloat(((uint16*)src)[0]);
+                *a = 1.0f;
+                break;
+			case PF_FLOAT16_GR:
+				*g = Bitwise::halfToFloat(((uint16*)src)[0]);
+				*r = *b = Bitwise::halfToFloat(((uint16*)src)[1]);
+				*a = 1.0f;
+				break;
+            case PF_FLOAT16_RGB:
+                *r = Bitwise::halfToFloat(((uint16*)src)[0]);
+                *g = Bitwise::halfToFloat(((uint16*)src)[1]);
+                *b = Bitwise::halfToFloat(((uint16*)src)[2]);
+                *a = 1.0f;
+                break;
+            case PF_FLOAT16_RGBA:
+                *r = Bitwise::halfToFloat(((uint16*)src)[0]);
+                *g = Bitwise::halfToFloat(((uint16*)src)[1]);
+                *b = Bitwise::halfToFloat(((uint16*)src)[2]);
+                *a = Bitwise::halfToFloat(((uint16*)src)[3]);
+                break;
+			case PF_SHORT_RGB:
+				*r = Bitwise::fixedToFloat(((uint16*)src)[0], 16);
+                *g = Bitwise::fixedToFloat(((uint16*)src)[1], 16);
+				*b = Bitwise::fixedToFloat(((uint16*)src)[2], 16);
+				*a = 1.0f;
+				break;
+			case PF_SHORT_RGBA:
+				*r = Bitwise::fixedToFloat(((uint16*)src)[0], 16);
+                *g = Bitwise::fixedToFloat(((uint16*)src)[1], 16);
+				*b = Bitwise::fixedToFloat(((uint16*)src)[2], 16);
+				*a = Bitwise::fixedToFloat(((uint16*)src)[3], 16);
+				break;
+			case PF_BYTE_LA:
+				*r = *g = *b = Bitwise::fixedToFloat(((uint8*)src)[0], 8);
+				*a = Bitwise::fixedToFloat(((uint8*)src)[1], 8);
+				break;
+            default:
+                // Not yet supported
+                OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
+                    "unpack from "+getFormatName(pf)+" not implemented",
+                    "PixelUtil::unpackColour");
+                break;
+            }
+        }
+    }
+    //-----------------------------------------------------------------------
+    /* Convert pixels from one format to another */
+    void PixelUtil::bulkPixelConversion(void *srcp, PixelFormat srcFormat,
+        void *destp, PixelFormat dstFormat, unsigned int count)
+    {
+        PixelBox src(count, 1, 1, srcFormat, srcp),
+				 dst(count, 1, 1, dstFormat, destp);
+
+        bulkPixelConversion(src, dst);
+    }
+    //-----------------------------------------------------------------------
+    void PixelUtil::bulkPixelConversion(const PixelBox &src, const PixelBox &dst)
+    {
+        assert(src.getWidth() == dst.getWidth() &&
+			   src.getHeight() == dst.getHeight() &&
+			   src.getDepth() == dst.getDepth());
+
+		// Check for compressed formats, we don't support decompression, compression or recoding
+		if(PixelUtil::isCompressed(src.format) || PixelUtil::isCompressed(dst.format))
+		{
+			if(src.format == dst.format)
+			{
+				memcpy(dst.data, src.data, src.getConsecutiveSize());
+				return;
+			}
+			else
+			{
+				OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
+					"This method can not be used to compress or decompress images",
+					"PixelUtil::bulkPixelConversion");
+			}
+		}
+
+        // The easy case
+        if(src.format == dst.format) {
+            // Everything consecutive?
+            if(src.isConsecutive() && dst.isConsecutive())
+            {
+				memcpy(dst.data, src.data, src.getConsecutiveSize());
+                return;
+            }
+
+            const size_t srcPixelSize = PixelUtil::getNumElemBytes(src.format);
+            const size_t dstPixelSize = PixelUtil::getNumElemBytes(dst.format);
+            uint8 *srcptr = static_cast<uint8*>(src.data)
+                + (src.left + src.top * src.rowPitch + src.front * src.slicePitch) * srcPixelSize;
+            uint8 *dstptr = static_cast<uint8*>(dst.data)
+				+ (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch) * dstPixelSize;
+
+            // Calculate pitches+skips in bytes
+            const size_t srcRowPitchBytes = src.rowPitch*srcPixelSize;
+            //const size_t srcRowSkipBytes = src.getRowSkip()*srcPixelSize;
+            const size_t srcSliceSkipBytes = src.getSliceSkip()*srcPixelSize;
+
+            const size_t dstRowPitchBytes = dst.rowPitch*dstPixelSize;
+            //const size_t dstRowSkipBytes = dst.getRowSkip()*dstPixelSize;
+            const size_t dstSliceSkipBytes = dst.getSliceSkip()*dstPixelSize;
+
+            // Otherwise, copy per row
+            const size_t rowSize = src.getWidth()*srcPixelSize;
+            for(size_t z=src.front; z<src.back; z++)
+            {
+                for(size_t y=src.top; y<src.bottom; y++)
+                {
+					memcpy(dstptr, srcptr, rowSize);
+                    srcptr += srcRowPitchBytes;
+                    dstptr += dstRowPitchBytes;
+                }
+                srcptr += srcSliceSkipBytes;
+                dstptr += dstSliceSkipBytes;
+            }
+            return;
+        }
+		// Converting to PF_X8R8G8B8 is exactly the same as converting to
+		// PF_A8R8G8B8. (same with PF_X8B8G8R8 and PF_A8B8G8R8)
+		if(dst.format == PF_X8R8G8B8 || dst.format == PF_X8B8G8R8)
+		{
+			// Do the same conversion, with PF_A8R8G8B8, which has a lot of
+			// optimized conversions
+			PixelBox tempdst = dst;
+			tempdst.format = dst.format==PF_X8R8G8B8?PF_A8R8G8B8:PF_A8B8G8R8;
+			bulkPixelConversion(src, tempdst);
+			return;
+		}
+		// Converting from PF_X8R8G8B8 is exactly the same as converting from
+		// PF_A8R8G8B8, given that the destination format does not have alpha.
+		if((src.format == PF_X8R8G8B8||src.format == PF_X8B8G8R8) && !hasAlpha(dst.format))
+		{
+			// Do the same conversion, with PF_A8R8G8B8, which has a lot of
+			// optimized conversions
+			PixelBox tempsrc = src;
+			tempsrc.format = src.format==PF_X8R8G8B8?PF_A8R8G8B8:PF_A8B8G8R8;
+			bulkPixelConversion(tempsrc, dst);
+			return;
+		}
+
+        const size_t srcPixelSize = PixelUtil::getNumElemBytes(src.format);
+        const size_t dstPixelSize = PixelUtil::getNumElemBytes(dst.format);
+        uint8 *srcptr = static_cast<uint8*>(src.data)
+            + (src.left + src.top * src.rowPitch + src.front * src.slicePitch) * srcPixelSize;
+        uint8 *dstptr = static_cast<uint8*>(dst.data)
+            + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch) * dstPixelSize;
+		
+		// Old way, not taking into account box dimensions
+		//uint8 *srcptr = static_cast<uint8*>(src.data), *dstptr = static_cast<uint8*>(dst.data);
+
+        // Calculate pitches+skips in bytes
+        const size_t srcRowSkipBytes = src.getRowSkip()*srcPixelSize;
+        const size_t srcSliceSkipBytes = src.getSliceSkip()*srcPixelSize;
+        const size_t dstRowSkipBytes = dst.getRowSkip()*dstPixelSize;
+        const size_t dstSliceSkipBytes = dst.getSliceSkip()*dstPixelSize;
+
+        // The brute force fallback
+        float r,g,b,a;
+        for(size_t z=src.front; z<src.back; z++)
+        {
+            for(size_t y=src.top; y<src.bottom; y++)
+            {
+                for(size_t x=src.left; x<src.right; x++)
+                {
+                    unpackColour(&r, &g, &b, &a, src.format, srcptr);
+                    packColour(r, g, b, a, dst.format, dstptr);
+                    srcptr += srcPixelSize;
+                    dstptr += dstPixelSize;
+                }
+                srcptr += srcRowSkipBytes;
+                dstptr += dstRowSkipBytes;
+            }
+            srcptr += srcSliceSkipBytes;
+            dstptr += dstSliceSkipBytes;
+        }
+    }
+
+    ColourValue PixelBox::getColourAt(size_t x, size_t y, size_t z)
+    {
+        ColourValue cv;
+
+        unsigned char pixelSize = PixelUtil::getNumElemBytes(format);
+        size_t pixelOffset = pixelSize * (z * slicePitch + y * rowPitch + x);
+        PixelUtil::unpackColour(&cv, format, (unsigned char *)data + pixelOffset);
+
+        return cv;
+    }
+
+    void PixelBox::setColourAt(ColourValue const &cv, size_t x, size_t y, size_t z)
+    {
+        unsigned char pixelSize = PixelUtil::getNumElemBytes(format);
+        size_t pixelOffset = pixelSize * (z * slicePitch + y * rowPitch + x);
+        PixelUtil::packColour(cv, format, (unsigned char *)data + pixelOffset);
+    }
+
+}

+ 509 - 0
CamelotRenderer/OgrePixelFormat.h

@@ -0,0 +1,509 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+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 and this permission notice 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 THE
+AUTHORS OR COPYRIGHT HOLDERS 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.
+-----------------------------------------------------------------------------
+*/
+#ifndef _PixelFormat_H__
+#define _PixelFormat_H__
+
+#include "OgrePrerequisites.h"
+#include "OgreCommon.h"
+
+namespace Ogre {
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup Image
+	*  @{
+	*/
+	/** The pixel format used for images, textures, and render surfaces */
+    enum PixelFormat
+    {
+        /// Unknown pixel format.
+        PF_UNKNOWN = 0,
+        /// 8-bit pixel format, all bits luminace.
+        PF_L8 = 1,
+		PF_BYTE_L = PF_L8,
+        /// 16-bit pixel format, all bits luminace.
+        PF_L16 = 2,
+		PF_SHORT_L = PF_L16,
+        /// 8-bit pixel format, all bits alpha.
+        PF_A8 = 3,
+		PF_BYTE_A = PF_A8,
+        /// 8-bit pixel format, 4 bits alpha, 4 bits luminance.
+        PF_A4L4 = 4,
+		/// 2 byte pixel format, 1 byte luminance, 1 byte alpha
+		PF_BYTE_LA = 5,
+        /// 16-bit pixel format, 5 bits red, 6 bits green, 5 bits blue.
+        PF_R5G6B5 = 6,
+		/// 16-bit pixel format, 5 bits red, 6 bits green, 5 bits blue.
+        PF_B5G6R5 = 7,
+        /// 8-bit pixel format, 2 bits blue, 3 bits green, 3 bits red.
+        PF_R3G3B2 = 31,
+        /// 16-bit pixel format, 4 bits for alpha, red, green and blue.
+        PF_A4R4G4B4 = 8,
+        /// 16-bit pixel format, 5 bits for blue, green, red and 1 for alpha.
+        PF_A1R5G5B5 = 9,
+        /// 24-bit pixel format, 8 bits for red, green and blue.
+        PF_R8G8B8 = 10,
+        /// 24-bit pixel format, 8 bits for blue, green and red.
+        PF_B8G8R8 = 11,
+        /// 32-bit pixel format, 8 bits for alpha, red, green and blue.
+        PF_A8R8G8B8 = 12,
+        /// 32-bit pixel format, 8 bits for blue, green, red and alpha.
+        PF_A8B8G8R8 = 13,
+        /// 32-bit pixel format, 8 bits for blue, green, red and alpha.
+        PF_B8G8R8A8 = 14,
+		/// 32-bit pixel format, 8 bits for red, green, blue and alpha.
+		PF_R8G8B8A8 = 28,
+        /// 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue
+        /// like PF_A8R8G8B8, but alpha will get discarded
+        PF_X8R8G8B8 = 26,
+        /// 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red
+        /// like PF_A8B8G8R8, but alpha will get discarded
+        PF_X8B8G8R8 = 27,
+#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
+		/// 3 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue
+		PF_BYTE_RGB = PF_R8G8B8,
+		/// 3 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red
+		PF_BYTE_BGR = PF_B8G8R8,
+		/// 4 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red and one byte for alpha
+		PF_BYTE_BGRA = PF_B8G8R8A8,
+		/// 4 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue, and one byte for alpha
+		PF_BYTE_RGBA = PF_R8G8B8A8,
+#else
+		/// 3 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue
+		PF_BYTE_RGB = PF_B8G8R8,
+		/// 3 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red
+		PF_BYTE_BGR = PF_R8G8B8,
+		/// 4 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red and one byte for alpha
+		PF_BYTE_BGRA = PF_A8R8G8B8,
+		/// 4 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue, and one byte for alpha
+		PF_BYTE_RGBA = PF_A8B8G8R8,
+#endif        
+        /// 32-bit pixel format, 2 bits for alpha, 10 bits for red, green and blue.
+        PF_A2R10G10B10 = 15,
+        /// 32-bit pixel format, 10 bits for blue, green and red, 2 bits for alpha.
+        PF_A2B10G10R10 = 16,
+        /// DDS (DirectDraw Surface) DXT1 format
+        PF_DXT1 = 17,
+        /// DDS (DirectDraw Surface) DXT2 format
+        PF_DXT2 = 18,
+        /// DDS (DirectDraw Surface) DXT3 format
+        PF_DXT3 = 19,
+        /// DDS (DirectDraw Surface) DXT4 format
+        PF_DXT4 = 20,
+        /// DDS (DirectDraw Surface) DXT5 format
+        PF_DXT5 = 21,
+		// 16-bit pixel format, 16 bits (float) for red
+        PF_FLOAT16_R = 32,
+        // 48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue
+        PF_FLOAT16_RGB = 22,
+        // 64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue, 16 bits (float) for alpha
+        PF_FLOAT16_RGBA = 23,
+		// 32-bit pixel format, 32 bits (float) for red
+        PF_FLOAT32_R = 33,
+        // 96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue
+        PF_FLOAT32_RGB = 24,
+        // 128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, 32 bits (float) for alpha
+        PF_FLOAT32_RGBA = 25,
+		// 32-bit, 2-channel s10e5 floating point pixel format, 16-bit green, 16-bit red
+		PF_FLOAT16_GR = 35,
+		// 64-bit, 2-channel floating point pixel format, 32-bit green, 32-bit red
+		PF_FLOAT32_GR = 36,
+		// Depth texture format
+		PF_DEPTH = 29,
+		// 64-bit pixel format, 16 bits for red, green, blue and alpha
+		PF_SHORT_RGBA = 30,
+		// 32-bit pixel format, 16-bit green, 16-bit red
+		PF_SHORT_GR = 34,
+		// 48-bit pixel format, 16 bits for red, green and blue
+		PF_SHORT_RGB = 37,
+        /// PVRTC (PowerVR) RGB 2 bpp
+        PF_PVRTC_RGB2 = 38,
+        /// PVRTC (PowerVR) RGBA 2 bpp
+        PF_PVRTC_RGBA2 = 39,
+        /// PVRTC (PowerVR) RGB 4 bpp
+        PF_PVRTC_RGB4 = 40,
+        /// PVRTC (PowerVR) RGBA 4 bpp
+        PF_PVRTC_RGBA4 = 41,
+		// Number of pixel formats currently defined
+        PF_COUNT = 42
+    };
+	typedef vector<PixelFormat>::type PixelFormatList;
+
+    /**
+     * Flags defining some on/off properties of pixel formats
+     */
+    enum PixelFormatFlags {
+        // This format has an alpha channel
+        PFF_HASALPHA        = 0x00000001,      
+        // This format is compressed. This invalidates the values in elemBytes,
+        // elemBits and the bit counts as these might not be fixed in a compressed format.
+        PFF_COMPRESSED    = 0x00000002,
+        // This is a floating point format
+        PFF_FLOAT           = 0x00000004,         
+        // This is a depth format (for depth textures)
+        PFF_DEPTH           = 0x00000008,
+        // Format is in native endian. Generally true for the 16, 24 and 32 bits
+        // formats which can be represented as machine integers.
+        PFF_NATIVEENDIAN    = 0x00000010,
+        // This is an intensity format instead of a RGB one. The luminance
+        // replaces R,G and B. (but not A)
+        PFF_LUMINANCE       = 0x00000020
+    };
+    
+    /** Pixel component format */
+    enum PixelComponentType
+    {
+        PCT_BYTE = 0,    /// Byte per component (8 bit fixed 0.0..1.0)
+        PCT_SHORT = 1,   /// Short per component (16 bit fixed 0.0..1.0))
+        PCT_FLOAT16 = 2, /// 16 bit float per component
+        PCT_FLOAT32 = 3, /// 32 bit float per component
+        PCT_COUNT = 4    /// Number of pixel types
+    };
+    
+	/** A primitive describing a volume (3D), image (2D) or line (1D) of pixels in memory.
+     	In case of a rectangle, depth must be 1. 
+     	Pixels are stored as a succession of "depth" slices, each containing "height" rows of 
+     	"width" pixels.
+    */
+    class _OgreExport PixelBox: public Box {
+    public:
+    	/// Parameter constructor for setting the members manually
+    	PixelBox() {}
+		~PixelBox() {}
+		/** Constructor providing extents in the form of a Box object. This constructor
+    		assumes the pixel data is laid out consecutively in memory. (this
+    		means row after row, slice after slice, with no space in between)
+    		@param extents	    Extents of the region defined by data
+    		@param pixelFormat	Format of this buffer
+    		@param pixelData	Pointer to the actual data
+    	*/
+		PixelBox(const Box &extents, PixelFormat pixelFormat, void *pixelData=0):
+			Box(extents), data(pixelData), format(pixelFormat)
+		{
+			setConsecutive();
+		}
+    	/** Constructor providing width, height and depth. This constructor
+    		assumes the pixel data is laid out consecutively in memory. (this
+    		means row after row, slice after slice, with no space in between)
+    		@param width	    Width of the region
+    		@param height	    Height of the region
+    		@param depth	    Depth of the region
+    		@param pixelFormat	Format of this buffer
+    		@param pixelData    Pointer to the actual data
+    	*/
+    	PixelBox(size_t width, size_t height, size_t depth, PixelFormat pixelFormat, void *pixelData=0):
+    		Box(0, 0, 0, width, height, depth),
+    		data(pixelData), format(pixelFormat)
+    	{
+    		setConsecutive();
+    	}
+    	
+        /// The data pointer 
+        void *data;
+        /// The pixel format 
+        PixelFormat format;
+        /** Number of elements between the leftmost pixel of one row and the left
+         	pixel of the next. This value must always be equal to getWidth() (consecutive) 
+			for compressed formats.
+        */
+        size_t rowPitch;
+        /** Number of elements between the top left pixel of one (depth) slice and 
+         	the top left pixel of the next. This can be a negative value. Must be a multiple of
+         	rowPitch. This value must always be equal to getWidth()*getHeight() (consecutive) 
+			for compressed formats.
+        */
+        size_t slicePitch;
+        
+        /** Set the rowPitch and slicePitch so that the buffer is laid out consecutive 
+         	in memory.
+        */        
+        void setConsecutive()
+        {
+            rowPitch = getWidth();
+            slicePitch = getWidth()*getHeight();
+        }
+        /**	Get the number of elements between one past the rightmost pixel of 
+         	one row and the leftmost pixel of the next row. (IE this is zero if rows
+         	are consecutive).
+        */
+        size_t getRowSkip() const { return rowPitch - getWidth(); }
+        /** Get the number of elements between one past the right bottom pixel of
+         	one slice and the left top pixel of the next slice. (IE this is zero if slices
+         	are consecutive).
+        */
+        size_t getSliceSkip() const { return slicePitch - (getHeight() * rowPitch); }
+
+        /** Return whether this buffer is laid out consecutive in memory (ie the pitches
+         	are equal to the dimensions)
+        */        
+        bool isConsecutive() const 
+		{ 
+			return rowPitch == getWidth() && slicePitch == getWidth()*getHeight(); 
+		}
+        /** Return the size (in bytes) this image would take if it was
+        	laid out consecutive in memory
+      	*/
+      	size_t getConsecutiveSize() const;
+      	/** Return a subvolume of this PixelBox.
+      		@param def	Defines the bounds of the subregion to return
+      		@returns	A pixel box describing the region and the data in it
+      		@remarks	This function does not copy any data, it just returns
+      			a PixelBox object with a data pointer pointing somewhere inside 
+      			the data of object.
+      		@throws	Exception(ERR_INVALIDPARAMS) if def is not fully contained
+      	*/
+      	PixelBox getSubVolume(const Box &def) const;
+        
+        /**
+         * Get colour value from a certain location in the PixelBox. The z coordinate
+         * is only valid for cubemaps and volume textures. This uses the first (largest)
+         * mipmap.
+         */
+        ColourValue getColourAt(size_t x, size_t y, size_t z);
+
+        /**
+         * Set colour value at a certain location in the PixelBox. The z coordinate
+         * is only valid for cubemaps and volume textures. This uses the first (largest)
+         * mipmap.
+         */
+        void setColourAt(ColourValue const &cv, size_t x, size_t y, size_t z);
+    };
+    
+
+    /**
+     * Some utility functions for packing and unpacking pixel data
+     */
+    class _OgreExport PixelUtil {
+    public:
+        /** Returns the size in bytes of an element of the given pixel format.
+         @returns
+               The size in bytes of an element. See Remarks.
+         @remarks
+               Passing PF_UNKNOWN will result in returning a size of 0 bytes.
+        */
+        static size_t getNumElemBytes( PixelFormat format );
+
+        /** Returns the size in bits of an element of the given pixel format.
+          @returns
+               The size in bits of an element. See Remarks.
+           @remarks
+               Passing PF_UNKNOWN will result in returning a size of 0 bits.
+        */
+        static size_t getNumElemBits( PixelFormat format );
+
+		/** Returns the size in memory of a region with the given extents and pixel
+			format with consecutive memory layout.
+			@param width
+				The width of the area
+			@param height
+				The height of the area
+			@param depth
+				The depth of the area
+			@param format
+				The format of the area
+		  	@returns
+		  		The size in bytes
+			@remarks
+				In case that the format is non-compressed, this simply returns
+				width*height*depth*PixelUtil::getNumElemBytes(format). In the compressed
+				case, this does serious magic.
+		*/
+		static size_t getMemorySize(size_t width, size_t height, size_t depth, PixelFormat format);
+		
+        /** Returns the property flags for this pixel format
+          @returns
+               A bitfield combination of PFF_HASALPHA, PFF_ISCOMPRESSED,
+               PFF_FLOAT, PFF_DEPTH, PFF_NATIVEENDIAN, PFF_LUMINANCE
+          @remarks
+               This replaces the seperate functions for formatHasAlpha, formatIsFloat, ...
+        */
+        static unsigned int getFlags( PixelFormat format );
+
+        /** Shortcut method to determine if the format has an alpha component */
+        static bool hasAlpha(PixelFormat format);
+        /** Shortcut method to determine if the format is floating point */
+        static bool isFloatingPoint(PixelFormat format);
+        /** Shortcut method to determine if the format is compressed */
+        static bool isCompressed(PixelFormat format);
+        /** Shortcut method to determine if the format is a depth format. */
+        static bool isDepth(PixelFormat format);
+        /** Shortcut method to determine if the format is in native endian format. */
+        static bool isNativeEndian(PixelFormat format);
+        /** Shortcut method to determine if the format is a luminance format. */
+        static bool isLuminance(PixelFormat format);
+		
+		/** Return wether a certain image extent is valid for this image format.
+			@param width
+				The width of the area
+			@param height
+				The height of the area
+			@param depth
+				The depth of the area
+			@param format
+				The format of the area
+			@remarks For non-compressed formats, this is always true. For DXT formats,
+			only sizes with a width and height multiple of 4 and depth 1 are allowed.
+		*/
+		static bool isValidExtent(size_t width, size_t height, size_t depth, PixelFormat format);
+
+        /** Gives the number of bits (RGBA) for a format. See remarks.          
+          @remarks      For non-colour formats (dxt, depth) this returns [0,0,0,0].
+        */
+        static void getBitDepths(PixelFormat format, int rgba[4]);
+
+		/** Gives the masks for the R, G, B and A component
+		  @note			Only valid for native endian formats
+        */
+        static void getBitMasks(PixelFormat format, uint32 rgba[4]);
+
+		/** Gives the bit shifts for R, G, B and A component
+		@note			Only valid for native endian formats
+		*/
+		static void getBitShifts(PixelFormat format, unsigned char rgba[4]);
+
+        /** Gets the name of an image format
+        */
+        static String getFormatName(PixelFormat srcformat);
+
+        /** Returns wether the format can be packed or unpacked with the packColour()
+        and unpackColour() functions. This is generally not true for compressed and
+        depth formats as they are special. It can only be true for formats with a
+        fixed element size.
+          @returns 
+               true if yes, otherwise false
+        */
+        static bool isAccessible(PixelFormat srcformat);
+        
+        /** Returns the component type for a certain pixel format. Returns PCT_BYTE
+            in case there is no clear component type like with compressed formats.
+            This is one of PCT_BYTE, PCT_SHORT, PCT_FLOAT16, PCT_FLOAT32.
+        */
+        static PixelComponentType getComponentType(PixelFormat fmt);
+        
+        /** Returns the component count for a certain pixel format. Returns 3(no alpha) or 
+            4 (has alpha) in case there is no clear component type like with compressed formats.
+         */
+        static size_t getComponentCount(PixelFormat fmt);
+
+        /** Gets the format from given name.
+            @param  name            The string of format name
+            @param  accessibleOnly  If true, non-accessible format will treat as invalid format,
+                                    otherwise, all supported format are valid.
+            @param  caseSensitive   Should be set true if string match should use case sensitivity.
+            @returns                The format match the format name, or PF_UNKNOWN if is invalid name.
+        */
+        static PixelFormat getFormatFromName(const String& name, bool accessibleOnly = false, bool caseSensitive = false);
+
+        /** Gets the BNF expression of the pixel-formats.
+            @note                   The string returned by this function is intented to use as a BNF expression
+                                    to work with Compiler2Pass.
+            @param  accessibleOnly  If true, only accessible pixel format will take into account, otherwise all
+                                    pixel formats list in PixelFormat enumeration will being returned.
+            @returns                A string contains the BNF expression.
+        */
+        static String getBNFExpressionOfPixelFormats(bool accessibleOnly = false);
+
+        /** Returns the similar format but acoording with given bit depths.
+            @param fmt      The original foamt.
+            @param integerBits Preferred bit depth (pixel bits) for integer pixel format.
+                            Available values: 0, 16 and 32, where 0 (the default) means as it is.
+            @param floatBits Preferred bit depth (channel bits) for float pixel format.
+                            Available values: 0, 16 and 32, where 0 (the default) means as it is.
+            @returns        The format that similar original format with bit depth according
+                            with preferred bit depth, or original format if no convertion occuring.
+        */
+        static PixelFormat getFormatForBitDepths(PixelFormat fmt, ushort integerBits, ushort floatBits);
+
+        /** Pack a colour value to memory
+        	@param colour	The colour
+        	@param pf		Pixelformat in which to write the colour
+        	@param dest		Destination memory location
+        */
+        static void packColour(const ColourValue &colour, const PixelFormat pf,  void* dest);
+        /** Pack a colour value to memory
+        	@param r,g,b,a	The four colour components, range 0x00 to 0xFF
+        	@param pf		Pixelformat in which to write the colour
+        	@param dest		Destination memory location
+        */
+        static void packColour(const uint8 r, const uint8 g, const uint8 b, const uint8 a, const PixelFormat pf,  void* dest);
+         /** Pack a colour value to memory
+        	@param r,g,b,a	The four colour components, range 0.0f to 1.0f
+        					(an exception to this case exists for floating point pixel
+        					formats, which don't clamp to 0.0f..1.0f)
+        	@param pf		Pixelformat in which to write the colour
+        	@param dest		Destination memory location
+        */
+        static void packColour(const float r, const float g, const float b, const float a, const PixelFormat pf,  void* dest);
+
+        /** Unpack a colour value from memory
+        	@param colour	The colour is returned here
+        	@param pf		Pixelformat in which to read the colour
+        	@param src		Source memory location
+        */
+        static void unpackColour(ColourValue *colour, PixelFormat pf,  const void* src);
+        /** Unpack a colour value from memory
+        	@param r,g,b,a	The colour is returned here (as byte)
+        	@param pf		Pixelformat in which to read the colour
+        	@param src		Source memory location
+        	@remarks 	This function returns the colour components in 8 bit precision,
+        		this will lose precision when coming from PF_A2R10G10B10 or floating
+        		point formats.  
+        */
+        static void unpackColour(uint8 *r, uint8 *g, uint8 *b, uint8 *a, PixelFormat pf,  const void* src);
+        /** Unpack a colour value from memory
+        	@param r,g,b,a	The colour is returned here (as float)
+        	@param pf		Pixelformat in which to read the colour
+        	@param src		Source memory location
+        */
+        static void unpackColour(float *r, float *g, float *b, float *a, PixelFormat pf,  const void* src); 
+        
+        /** Convert consecutive pixels from one format to another. No dithering or filtering is being done. 
+         	Converting from RGB to luminance takes the R channel.  In case the source and destination format match,
+         	just a copy is done.
+         	@param	src			Pointer to source region
+         	@param	srcFormat	Pixel format of source region
+         	@param   dst			Pointer to destination region
+         	@param	dstFormat	Pixel format of destination region
+         */
+        static void bulkPixelConversion(void *src, PixelFormat srcFormat, void *dest, PixelFormat dstFormat, unsigned int count);
+
+      	/** Convert pixels from one format to another. No dithering or filtering is being done. Converting
+          	from RGB to luminance takes the R channel. 
+		 	@param	src			PixelBox containing the source pixels, pitches and format
+		 	@param	dst			PixelBox containing the destination pixels, pitches and format
+		 	@remarks The source and destination boxes must have the same
+         	dimensions. In case the source and destination format match, a plain copy is done.
+        */
+        static void bulkPixelConversion(const PixelBox &src, const PixelBox &dst);
+    };
+	/** @} */
+	/** @} */
+
+}
+
+#endif

+ 248 - 0
CamelotRenderer/OgreRenderTarget.cpp

@@ -0,0 +1,248 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+(Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+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 and this permission notice 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 THE
+AUTHORS OR COPYRIGHT HOLDERS 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.
+-----------------------------------------------------------------------------
+*/
+#include "OgreRenderTarget.h"
+#include "OgreStringConverter.h"
+
+#include "OgreViewport.h"
+#include "OgreException.h"
+
+namespace Ogre {
+
+    RenderTarget::RenderTarget()
+		:mPriority(OGRE_DEFAULT_RT_GROUP),
+		mActive(true),
+		mAutoUpdate(true),
+		mHwGamma(false), 
+		mFSAA(0)
+    {
+    }
+
+    RenderTarget::~RenderTarget()
+    {
+        // Delete viewports
+        for (ViewportList::iterator i = mViewportList.begin();
+            i != mViewportList.end(); ++i)
+        {
+            OGRE_DELETE (*i).second;
+        }
+    }
+
+    const String& RenderTarget::getName(void) const
+    {
+        return mName;
+    }
+
+
+    void RenderTarget::getMetrics(unsigned int& width, unsigned int& height, unsigned int& colourDepth)
+    {
+        width = mWidth;
+        height = mHeight;
+        colourDepth = mColourDepth;
+    }
+
+    unsigned int RenderTarget::getWidth(void) const
+    {
+        return mWidth;
+    }
+    unsigned int RenderTarget::getHeight(void) const
+    {
+        return mHeight;
+    }
+    unsigned int RenderTarget::getColourDepth(void) const
+    {
+        return mColourDepth;
+    }
+
+    void RenderTarget::updateImpl(void)
+    {
+		_beginUpdate();
+		_updateAutoUpdatedViewports(true);
+		_endUpdate();
+    }
+
+	void RenderTarget::_beginUpdate()
+	{
+	}
+
+	void RenderTarget::_updateAutoUpdatedViewports(bool updateStatistics)
+	{
+		// Go through viewports in Z-order
+        // Tell each to refresh
+		ViewportList::iterator it = mViewportList.begin();
+        while (it != mViewportList.end())
+        {
+			Viewport* viewport = (*it).second;
+			if(viewport->isAutoUpdated())
+			{
+				_updateViewport(viewport,updateStatistics);
+			}
+			++it;
+		}
+	}
+
+	void RenderTarget::_endUpdate()
+	{
+	}
+
+	void RenderTarget::_updateViewport(Viewport* viewport, bool updateStatistics)
+	{
+		assert(viewport->getTarget() == this &&
+				"RenderTarget::_updateViewport the requested viewport is "
+				"not bound to the rendertarget!");
+
+		viewport->update();
+	}
+
+	void RenderTarget::_updateViewport(int zorder, bool updateStatistics)
+	{
+		ViewportList::iterator it = mViewportList.find(zorder);
+        if (it != mViewportList.end())
+        {
+			_updateViewport((*it).second,updateStatistics);
+		}
+		else
+		{
+			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,"No viewport with given zorder : "
+				+ StringConverter::toString(zorder), "RenderTarget::_updateViewport");
+		}
+	}
+
+    Viewport* RenderTarget::addViewport(int ZOrder, float left, float top ,
+        float width , float height)
+    {
+        // Check no existing viewport with this Z-order
+        ViewportList::iterator it = mViewportList.find(ZOrder);
+
+        if (it != mViewportList.end())
+        {
+			StringUtil::StrStreamType str;
+			str << "Can't create another viewport for "
+				<< mName << " with Z-Order " << ZOrder
+				<< " because a viewport exists with this Z-Order already.";
+			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, str.str(), "RenderTarget::addViewport");
+        }
+        // Add viewport to list
+        // Order based on Z-Order
+        Viewport* vp = OGRE_NEW Viewport(this, left, top, width, height, ZOrder);
+
+        mViewportList.insert(ViewportList::value_type(ZOrder, vp));
+
+        return vp;
+    }
+	//-----------------------------------------------------------------------
+    void RenderTarget::removeViewport(int ZOrder)
+    {
+        ViewportList::iterator it = mViewportList.find(ZOrder);
+
+        if (it != mViewportList.end())
+        {
+            OGRE_DELETE (*it).second;
+            mViewportList.erase(ZOrder);
+        }
+    }
+
+    void RenderTarget::removeAllViewports(void)
+    {
+        for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it)
+        {
+            OGRE_DELETE (*it).second;
+        }
+
+        mViewportList.clear();
+
+    }
+
+    void RenderTarget::getCustomAttribute(const String& name, void* pData)
+    {
+        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attribute not found.", "RenderTarget::getCustomAttribute");
+    }
+    //-----------------------------------------------------------------------
+    unsigned short RenderTarget::getNumViewports(void) const
+    {
+        return (unsigned short)mViewportList.size();
+
+    }
+    //-----------------------------------------------------------------------
+    Viewport* RenderTarget::getViewport(unsigned short index)
+    {
+        assert (index < mViewportList.size() && "Index out of bounds");
+
+        ViewportList::iterator i = mViewportList.begin();
+        while (index--)
+            ++i;
+        return i->second;
+    }
+    //-----------------------------------------------------------------------
+    bool RenderTarget::isActive() const
+    {
+        return mActive;
+    }
+    //-----------------------------------------------------------------------
+    void RenderTarget::setActive( bool state )
+    {
+        mActive = state;
+    }
+    //-----------------------------------------------------------------------
+    void RenderTarget::setAutoUpdated(bool autoup)
+    {
+        mAutoUpdate = autoup;
+    }
+    //-----------------------------------------------------------------------
+    bool RenderTarget::isAutoUpdated(void) const
+    {
+        return mAutoUpdate;
+    }
+    //-----------------------------------------------------------------------
+    bool RenderTarget::isPrimary(void) const
+    {
+        // RenderWindow will override and return true for the primary window
+        return false;
+    }
+    //-----------------------------------------------------------------------
+    RenderTarget::Impl *RenderTarget::_getImpl()
+    {
+        return 0;
+    }
+    //-----------------------------------------------------------------------
+    void RenderTarget::update(bool swap)
+    {
+        // call implementation
+        updateImpl();
+
+
+		if (swap)
+		{
+			// Swap buffers
+			// TODO PORT - Make sure to enable this line and disable next line, once render system is ported
+    	    //swapBuffers(Root::getSingleton().getRenderSystem()->getWaitForVerticalBlank());
+			swapBuffers(false);
+		}
+    }
+	
+
+}        

+ 366 - 0
CamelotRenderer/OgreRenderTarget.h

@@ -0,0 +1,366 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+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 and this permission notice 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 THE
+AUTHORS OR COPYRIGHT HOLDERS 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.
+-----------------------------------------------------------------------------
+*/
+#ifndef __RenderTarget_H__
+#define __RenderTarget_H__
+
+#include "OgrePrerequisites.h"
+
+#include "OgreString.h"
+#include "OgrePixelFormat.h"
+#include "OgreViewport.h"
+
+/* Define the number of priority groups for the render system's render targets. */
+#ifndef OGRE_NUM_RENDERTARGET_GROUPS
+	#define OGRE_NUM_RENDERTARGET_GROUPS 10
+	#define OGRE_DEFAULT_RT_GROUP 4
+	#define OGRE_REND_TO_TEX_RT_GROUP 2
+#endif
+
+namespace Ogre {
+
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup RenderSystem
+	*  @{
+	*/
+	/** A 'canvas' which can receive the results of a rendering
+        operation.
+        @remarks
+            This abstract class defines a common root to all targets of rendering operations. A
+            render target could be a window on a screen, or another
+            offscreen surface like a texture or bump map etc.
+        @author
+            Steven Streeting
+        @version
+            1.0
+     */
+    class _OgreExport RenderTarget
+    {
+    public:
+		enum FrameBuffer
+		{
+			FB_FRONT,
+			FB_BACK,
+			FB_AUTO
+		};
+
+        RenderTarget();
+        virtual ~RenderTarget();
+
+        /// Retrieve target's name.
+        virtual const String& getName(void) const;
+
+        /// Retrieve information about the render target.
+        virtual void getMetrics(unsigned int& width, unsigned int& height, unsigned int& colourDepth);
+
+        virtual unsigned int getWidth(void) const;
+        virtual unsigned int getHeight(void) const;
+        virtual unsigned int getColourDepth(void) const;
+
+        /** Tells the target to update it's contents.
+            @remarks
+                If OGRE is not running in an automatic rendering loop
+                (started using Root::startRendering),
+                the user of the library is responsible for asking each render
+                target to refresh. This is the method used to do this. It automatically
+                re-renders the contents of the target using whatever cameras have been
+                pointed at it (using Camera::setRenderTarget).
+            @par
+                This allows OGRE to be used in multi-windowed utilities
+                and for contents to be refreshed only when required, rather than
+                constantly as with the automatic rendering loop.
+			@param swapBuffers For targets that support double-buffering, if set 
+				to true, the target will immediately
+				swap it's buffers after update. Otherwise, the buffers are
+				not swapped, and you have to call swapBuffers yourself sometime
+				later. You might want to do this on some rendersystems which 
+				pause for queued rendering commands to complete before accepting
+				swap buffers calls - so you could do other CPU tasks whilst the 
+				queued commands complete. Or, you might do this if you want custom
+				control over your windows, such as for externally created windows.
+        */
+        virtual void update(bool swapBuffers = true);
+        /** Swaps the frame buffers to display the next frame.
+            @remarks
+                For targets that are double-buffered so that no
+                'in-progress' versions of the scene are displayed
+                during rendering. Once rendering has completed (to
+                an off-screen version of the window) the buffers
+                are swapped to display the new frame.
+
+            @param
+                waitForVSync If true, the system waits for the
+                next vertical blank period (when the CRT beam turns off
+                as it travels from bottom-right to top-left at the
+                end of the pass) before flipping. If false, flipping
+                occurs no matter what the beam position. Waiting for
+                a vertical blank can be slower (and limits the
+                framerate to the monitor refresh rate) but results
+                in a steadier image with no 'tearing' (a flicker
+                resulting from flipping buffers when the beam is
+                in the progress of drawing the last frame).
+        */
+        virtual void swapBuffers(bool waitForVSync = true)
+        { (void)waitForVSync; }
+
+        /** Adds a viewport to the rendering target.
+            @remarks
+                A viewport is the rectangle into which rendering output is sent. This method adds
+                a viewport to the render target, rendering from the supplied camera. The
+                rest of the parameters are only required if you wish to add more than one viewport
+                to a single rendering target. Note that size information passed to this method is
+                passed as a parametric, i.e. it is relative rather than absolute. This is to allow
+                viewports to automatically resize along with the target.
+            @param
+                ZOrder The relative order of the viewport with others on the target (allows overlapping
+                viewports i.e. picture-in-picture). Higher ZOrders are on top of lower ones. The actual number
+                is irrelevant, only the relative ZOrder matters (you can leave gaps in the numbering)
+            @param
+                left The relative position of the left of the viewport on the target, as a value between 0 and 1.
+            @param
+                top The relative position of the top of the viewport on the target, as a value between 0 and 1.
+            @param
+                width The relative width of the viewport on the target, as a value between 0 and 1.
+            @param
+                height The relative height of the viewport on the target, as a value between 0 and 1.
+        */
+        virtual Viewport* addViewport(int ZOrder = 0, float left = 0.0f, float top = 0.0f ,
+            float width = 1.0f, float height = 1.0f);
+
+        /** Returns the number of viewports attached to this target.*/
+        virtual unsigned short getNumViewports(void) const;
+
+        /** Retrieves a pointer to the viewport with the given index. */
+        virtual Viewport* getViewport(unsigned short index);
+
+        /** Removes a viewport at a given ZOrder.
+        */
+        virtual void removeViewport(int ZOrder);
+
+        /** Removes all viewports on this target.
+        */
+        virtual void removeAllViewports(void);
+
+        /** Gets a custom (maybe platform-specific) attribute.
+            @remarks
+                This is a nasty way of satisfying any API's need to see platform-specific details.
+                It horrid, but D3D needs this kind of info. At least it's abstracted.
+            @param
+                name The name of the attribute.
+            @param
+                pData Pointer to memory of the right kind of structure to receive the info.
+        */
+        virtual void getCustomAttribute(const String& name, void* pData);
+
+		/** Sets the priority of this render target in relation to the others. 
+        @remarks
+            This can be used in order to schedule render target updates. Lower
+            priorities will be rendered first. Note that the priority must be set
+            at the time the render target is attached to the render system, changes
+            afterwards will not affect the ordering.
+        */
+        virtual void setPriority( uchar priority ) { mPriority = priority; }
+        /** Gets the priority of a render target. */
+		virtual uchar getPriority() const { return mPriority; }
+
+        /** Used to retrieve or set the active state of the render target.
+        */
+        virtual bool isActive() const;
+
+        /** Used to set the active state of the render target.
+        */
+        virtual void setActive( bool state );
+
+        /** Sets whether this target should be automatically updated if Ogre's rendering
+            loop or Root::_updateAllRenderTargets is being used.
+        @remarks
+            By default, if you use Ogre's own rendering loop (Root::startRendering)
+            or call Root::_updateAllRenderTargets, all render targets are updated 
+            automatically. This method allows you to control that behaviour, if 
+            for example you have a render target which you only want to update periodically.
+        @param autoupdate If true, the render target is updated during the automatic render
+            loop or when Root::_updateAllRenderTargets is called. If false, the 
+            target is only updated when its update() method is called explicitly.
+        */
+        virtual void setAutoUpdated(bool autoupdate);
+        /** Gets whether this target is automatically updated if Ogre's rendering
+            loop or Root::_updateAllRenderTargets is being used.
+        */
+        virtual bool isAutoUpdated(void) const;
+
+		/** Copies the current contents of the render target to a pixelbox. 
+		@remarks See suggestPixelFormat for a tip as to the best pixel format to
+			extract into, although you can use whatever format you like and the 
+			results will be converted.
+		*/
+		virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer = FB_AUTO) = 0;
+
+		/** Suggests a pixel format to use for extracting the data in this target, 
+			when calling copyContentsToMemory.
+		*/
+		virtual PixelFormat suggestPixelFormat() const { return PF_BYTE_RGBA; }
+
+		virtual bool requiresTextureFlipping() const = 0;
+
+        /** Indicates whether this target is the primary window. The
+            primary window is special in that it is destroyed when
+            ogre is shut down, and cannot be destroyed directly.
+            This is the case because it holds the context for vertex,
+            index buffers and textures.
+        */
+        virtual bool isPrimary(void) const;
+
+		/** Indicates whether on rendering, linear colour space is converted to 
+			sRGB gamma colour space. This is the exact opposite conversion of
+			what is indicated by Texture::isHardwareGammaEnabled, and can only
+			be enabled on creation of the render target. For render windows, it's
+			enabled through the 'gamma' creation misc parameter. For textures, 
+			it is enabled through the hwGamma parameter to the create call.
+		*/
+		virtual bool isHardwareGammaEnabled() const { return mHwGamma; }
+
+		/** Indicates whether multisampling is performed on rendering and at what level.
+		*/
+		virtual uint getFSAA() const { return mFSAA; }
+
+		/** Gets the FSAA hint (@see Root::createRenderWindow)
+		*/
+		virtual const String& getFSAAHint() const { return mFSAAHint; }
+
+        /** RenderSystem specific interface for a RenderTarget;
+            this should be subclassed by RenderSystems.
+        */
+        class Impl
+        {
+        protected:
+            ~Impl() { }
+        };
+        /** Get rendersystem specific interface for this RenderTarget.
+            This is used by the RenderSystem to (un)bind this target, 
+            and to get specific information like surfaces
+            and framebuffer objects.
+        */
+        virtual Impl *_getImpl();
+
+		/** Method for manual management of rendering : fires 'preRenderTargetUpdate'
+			and initialises statistics etc.
+		@remarks 
+		<ul>
+		<li>_beginUpdate resets statistics and fires 'preRenderTargetUpdate'.</li>
+		<li>_updateViewport renders the given viewport (even if it is not autoupdated),
+		fires preViewportUpdate and postViewportUpdate and manages statistics.</li>
+		<li>_updateAutoUpdatedViewports renders only viewports that are auto updated,
+		fires preViewportUpdate and postViewportUpdate and manages statistics.</li>
+		<li>_endUpdate() ends statistics calculation and fires postRenderTargetUpdate.</li>
+		</ul>
+		you can use it like this for example :
+		<pre>
+			renderTarget->_beginUpdate();
+			renderTarget->_updateViewport(1); // which is not auto updated
+			renderTarget->_updateViewport(2); // which is not auto updated
+			renderTarget->_updateAutoUpdatedViewports();
+			renderTarget->_endUpdate();
+			renderTarget->swapBuffers(true);
+		</pre>
+			Please note that in that case, the zorder may not work as you expect,
+			since you are responsible for calling _updateViewport in the correct order.
+        */
+		virtual void _beginUpdate();
+
+		/** Method for manual management of rendering - renders the given 
+		viewport (even if it is not autoupdated)
+		@remarks
+		This also fires preViewportUpdate and postViewportUpdate, and manages statistics.
+		You should call it between _beginUpdate() and _endUpdate().
+		@see _beginUpdate for more details.
+		@param zorder The zorder of the viewport to update.
+		@param updateStatistics Whether you want to update statistics or not.
+		*/
+		virtual void _updateViewport(int zorder, bool updateStatistics = true);
+
+		/** Method for manual management of rendering - renders the given viewport (even if it is not autoupdated)
+		@remarks
+		This also fires preViewportUpdate and postViewportUpdate, and manages statistics
+		if needed. You should call it between _beginUpdate() and _endUpdate().
+		@see _beginUpdate for more details.
+		@param viewport The viewport you want to update, it must be bound to the rendertarget.
+		@param updateStatistics Whether you want to update statistics or not.
+		*/
+		virtual void _updateViewport(Viewport* viewport, bool updateStatistics = true);
+
+		/** Method for manual management of rendering - renders only viewports that are auto updated
+		@remarks
+		This also fires preViewportUpdate and postViewportUpdate, and manages statistics.
+		You should call it between _beginUpdate() and _endUpdate().
+		See _beginUpdate for more details.
+		@param updateStatistics Whether you want to update statistics or not.
+		@see _beginUpdate()
+		*/
+		virtual void _updateAutoUpdatedViewports(bool updateStatistics = true);
+		
+		/** Method for manual management of rendering - finishes statistics calculation 
+			and fires 'postRenderTargetUpdate'.
+		@remarks
+		You should call it after a _beginUpdate
+		@see _beginUpdate for more details.
+		*/
+		virtual void _endUpdate();
+
+    protected:
+        /// The name of this target.
+        String mName;
+		/// The priority of the render target.
+		uchar mPriority;
+
+        unsigned int mWidth;
+        unsigned int mHeight;
+        unsigned int mColourDepth;
+        bool mIsDepthBuffered;
+
+        bool mActive;
+        bool mAutoUpdate;
+		// Hardware sRGB gamma conversion done on write?
+		bool mHwGamma;
+		// FSAA performed?
+		uint mFSAA;
+		String mFSAAHint;
+
+		typedef map<int, Viewport*>::type ViewportList;
+        /// List of viewports, map on Z-order
+        ViewportList mViewportList;
+			
+		/// Internal implementation of update()
+		virtual void updateImpl();
+    };
+	/** @} */
+	/** @} */
+
+} // Namespace
+
+#endif

+ 362 - 0
CamelotRenderer/OgreViewport.cpp

@@ -0,0 +1,362 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+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 and this permission notice 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 THE
+AUTHORS OR COPYRIGHT HOLDERS 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.
+-----------------------------------------------------------------------------
+*/
+#include "OgreViewport.h"
+
+#include "OgreException.h"
+#include "OgreRenderTarget.h"
+#include "OgreMath.h"
+//#include "OgreRenderWindow.h"
+
+namespace Ogre {
+    OrientationMode Viewport::mDefaultOrientationMode = OR_DEGREE_0;
+    //---------------------------------------------------------------------
+    Viewport::Viewport(RenderTarget* target, Real left, Real top, Real width, Real height, int ZOrder)
+         :mTarget(target)
+        , mRelLeft(left)
+        , mRelTop(top)
+        , mRelWidth(width)
+        , mRelHeight(height)
+        // Actual dimensions will update later
+        , mZOrder(ZOrder)
+        , mBackColour(ColourValue::Black)
+        , mClearEveryFrame(true)
+		, mClearBuffers(FBT_COLOUR | FBT_DEPTH)
+        , mUpdated(false)
+        , mShowOverlays(true)
+        , mShowSkies(true)
+		, mShowShadows(true)
+		, mVisibilityMask(0xFFFFFFFF)
+		, mRQSequence(0)
+		, mMaterialSchemeName("NotUsedInPort")
+		, mIsAutoUpdated(true)
+    {
+        // Set the default orientation mode
+        mOrientationMode = mDefaultOrientationMode;     
+
+        // Calculate actual dimensions
+        _updateDimensions();
+    }
+    //---------------------------------------------------------------------
+    Viewport::~Viewport()
+    {
+
+    }
+    //---------------------------------------------------------------------
+    bool Viewport::_isUpdated(void) const
+    {
+        return mUpdated;
+    }
+    //---------------------------------------------------------------------
+    void Viewport::_clearUpdatedFlag(void)
+    {
+        mUpdated = false;
+    }
+    //---------------------------------------------------------------------
+    void Viewport::_updateDimensions(void)
+    {
+        Real height = (Real) mTarget->getHeight();
+        Real width = (Real) mTarget->getWidth();
+
+        mActLeft = (int) (mRelLeft * width);
+        mActTop = (int) (mRelTop * height);
+        mActWidth = (int) (mRelWidth * width);
+        mActHeight = (int) (mRelHeight * height);
+
+        mUpdated = true;
+    }
+	//---------------------------------------------------------------------
+	int Viewport::getZOrder(void) const
+	{
+		return mZOrder;
+	}
+	//---------------------------------------------------------------------
+    RenderTarget* Viewport::getTarget(void) const
+    {
+        return mTarget;
+    }
+    //---------------------------------------------------------------------
+    Real Viewport::getLeft(void) const
+    {
+        return mRelLeft;
+    }
+    //---------------------------------------------------------------------
+    Real Viewport::getTop(void) const
+    {
+        return mRelTop;
+    }
+    //---------------------------------------------------------------------
+    Real Viewport::getWidth(void) const
+    {
+        return mRelWidth;
+    }
+    //---------------------------------------------------------------------
+    Real Viewport::getHeight(void) const
+    {
+        return mRelHeight;
+    }
+    //---------------------------------------------------------------------
+    int Viewport::getActualLeft(void) const
+    {
+        return mActLeft;
+    }
+    //---------------------------------------------------------------------
+    int Viewport::getActualTop(void) const
+    {
+        return mActTop;
+    }
+    //---------------------------------------------------------------------
+    int Viewport::getActualWidth(void) const
+    {
+        return mActWidth;
+    }
+    //---------------------------------------------------------------------
+    int Viewport::getActualHeight(void) const
+    {
+        return mActHeight;
+    }
+    //---------------------------------------------------------------------
+    void Viewport::setDimensions(Real left, Real top, Real width, Real height)
+    {
+        mRelLeft = left;
+        mRelTop = top;
+        mRelWidth = width;
+        mRelHeight = height;
+        _updateDimensions();
+    }
+    //---------------------------------------------------------------------
+    void Viewport::update(void)
+    {
+
+    }
+    //---------------------------------------------------------------------
+    void Viewport::setOrientationMode(OrientationMode orientationMode, bool setDefault)
+    {
+#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
+        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
+                    "Setting Viewport orientation mode is not supported",
+                    __FUNCTION__);
+#endif
+        mOrientationMode = orientationMode;
+
+        if (setDefault)
+        {
+            setDefaultOrientationMode(orientationMode);
+        }
+
+		// TODO PORT - Enable this once I port rendersystem
+	//// Update the render system config
+ //       RenderSystem* rs = Root::getSingleton().getRenderSystem();
+ //       if(mOrientationMode == OR_LANDSCAPELEFT)
+ //           rs->setConfigOption("Orientation", "Landscape Left");
+ //       else if(mOrientationMode == OR_LANDSCAPERIGHT)
+ //           rs->setConfigOption("Orientation", "Landscape Right");
+ //       else if(mOrientationMode == OR_PORTRAIT)
+ //           rs->setConfigOption("Orientation", "Portrait");
+    }
+    //---------------------------------------------------------------------
+    OrientationMode Viewport::getOrientationMode() const
+    {
+#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
+        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
+                    "Getting Viewport orientation mode is not supported",
+                    __FUNCTION__);
+#endif
+        return mOrientationMode;
+    }
+    //---------------------------------------------------------------------
+    void Viewport::setDefaultOrientationMode(OrientationMode orientationMode)
+    {
+#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
+        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
+                    "Setting default Viewport orientation mode is not supported",
+                    __FUNCTION__);
+#endif
+        mDefaultOrientationMode = orientationMode;
+    }
+    //---------------------------------------------------------------------
+    OrientationMode Viewport::getDefaultOrientationMode()
+    {
+#if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0
+        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
+                    "Getting default Viewport orientation mode is not supported",
+                    __FUNCTION__);
+#endif
+        return mDefaultOrientationMode;
+    }
+    //---------------------------------------------------------------------
+    void Viewport::setBackgroundColour(const ColourValue& colour)
+    {
+        mBackColour = colour;
+    }
+    //---------------------------------------------------------------------
+    const ColourValue& Viewport::getBackgroundColour(void) const
+    {
+        return mBackColour;
+    }
+    //---------------------------------------------------------------------
+    void Viewport::setClearEveryFrame(bool inClear, unsigned int inBuffers)
+    {
+        mClearEveryFrame = inClear;
+		mClearBuffers = inBuffers;
+    }
+    //---------------------------------------------------------------------
+    bool Viewport::getClearEveryFrame(void) const
+    {
+        return mClearEveryFrame;
+    }
+    //---------------------------------------------------------------------
+    unsigned int Viewport::getClearBuffers(void) const
+    {
+        return mClearBuffers;
+    }
+    //---------------------------------------------------------------------
+	void Viewport::clear(unsigned int buffers, const ColourValue& col,  
+						 Real depth, unsigned short stencil)
+	{
+		// TODO PORT - Enable this once I port rendersystem
+		//RenderSystem* rs = Root::getSingleton().getRenderSystem();
+		//if (rs)
+		//{
+		//	Viewport* currentvp = rs->_getViewport();
+		//	if (currentvp && currentvp == this)
+		//		rs->clearFrameBuffer(buffers, col, depth, stencil);
+		//	else if (currentvp)
+		//	{
+		//		rs->_setViewport(this);
+		//		rs->clearFrameBuffer(buffers, col, depth, stencil);
+		//		rs->_setViewport(currentvp);
+		//	}
+		//}
+	}
+    //---------------------------------------------------------------------
+    void Viewport::getActualDimensions(int &left, int&top, int &width, int &height) const
+    {
+        left = mActLeft;
+        top = mActTop;
+        width = mActWidth;
+        height = mActHeight;
+
+    }
+    //---------------------------------------------------------------------
+	void Viewport::setAutoUpdated(bool inAutoUpdated)
+	{
+		mIsAutoUpdated = inAutoUpdated;
+	}
+	//---------------------------------------------------------------------
+	bool Viewport::isAutoUpdated() const
+	{
+		return mIsAutoUpdated;
+	}
+	//---------------------------------------------------------------------
+    void Viewport::setOverlaysEnabled(bool enabled)
+    {
+        mShowOverlays = enabled;
+    }
+    //---------------------------------------------------------------------
+    bool Viewport::getOverlaysEnabled(void) const
+    {
+        return mShowOverlays;
+    }
+    //---------------------------------------------------------------------
+    void Viewport::setSkiesEnabled(bool enabled)
+    {
+        mShowSkies = enabled;
+    }
+    //---------------------------------------------------------------------
+    bool Viewport::getSkiesEnabled(void) const
+    {
+        return mShowSkies;
+    }
+    //---------------------------------------------------------------------
+    void Viewport::setShadowsEnabled(bool enabled)
+    {
+        mShowShadows = enabled;
+    }
+    //---------------------------------------------------------------------
+    bool Viewport::getShadowsEnabled(void) const
+    {
+        return mShowShadows;
+    }
+	//-----------------------------------------------------------------------
+	void Viewport::setRenderQueueInvocationSequenceName(const String& sequenceName)
+	{
+		mRQSequenceName = sequenceName;
+		if (mRQSequenceName.empty())
+		{
+			mRQSequence = 0;
+		}
+		else
+		{
+			// TODO PORT - Not sure if this is needed but I might need to enable it later once I have rendersystem running? (Probably not)
+			//mRQSequence =
+			//	Root::getSingleton().getRenderQueueInvocationSequence(mRQSequenceName);
+		}
+	}
+	//-----------------------------------------------------------------------
+	const String& Viewport::getRenderQueueInvocationSequenceName(void) const
+	{
+		return mRQSequenceName;
+	}
+	//-----------------------------------------------------------------------
+	RenderQueueInvocationSequence* Viewport::_getRenderQueueInvocationSequence(void)
+	{
+		return mRQSequence;
+	}
+	//-----------------------------------------------------------------------
+    void Viewport::pointOrientedToScreen(const Vector2 &v, int orientationMode, Vector2 &outv)
+    {
+        pointOrientedToScreen(v.x, v.y, orientationMode, outv.x, outv.y);
+    }
+	//-----------------------------------------------------------------------
+    void Viewport::pointOrientedToScreen(Real orientedX, Real orientedY, int orientationMode,
+                                         Real &screenX, Real &screenY)
+    {
+        Real orX = orientedX;
+        Real orY = orientedY;
+        switch (orientationMode)
+        {
+        case 1:
+            screenX = orY;
+            screenY = Real(1.0) - orX;
+            break;
+        case 2:
+            screenX = Real(1.0) - orX;
+            screenY = Real(1.0) - orY;
+            break;
+        case 3:
+            screenX = Real(1.0) - orY;
+            screenY = orX;
+            break;
+        default:
+            screenX = orX;
+            screenY = orY;
+            break;
+        }
+    }
+	//-----------------------------------------------------------------------
+}

+ 382 - 0
CamelotRenderer/OgreViewport.h

@@ -0,0 +1,382 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2011 Torus Knot Software Ltd
+
+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 and this permission notice 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 THE
+AUTHORS OR COPYRIGHT HOLDERS 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.
+-----------------------------------------------------------------------------
+*/
+#ifndef __Viewport_H__
+#define __Viewport_H__
+
+#include "OgrePrerequisites.h"
+#include "OgreCommon.h"
+#include "OgreColourValue.h"
+#include "OgreFrustum.h"
+
+namespace Ogre {
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup RenderSystem
+	*  @{
+	*/
+	/** An abstraction of a viewport, i.e. a rendering region on a render
+        target.
+        @remarks
+            A viewport is the meeting of a camera and a rendering surface -
+            the camera renders the scene from a viewpoint, and places its
+            results into some subset of a rendering target, which may be the
+            whole surface or just a part of the surface. Each viewport has a
+            single camera as source and a single target as destination. A
+            camera only has 1 viewport, but a render target may have several.
+            A viewport also has a Z-order, i.e. if there is more than one
+            viewport on a single render target and they overlap, one must
+            obscure the other in some predetermined way.
+    */
+	class _OgreExport Viewport
+    {
+    public:       
+        /** The usual constructor.
+            @param
+                cam Pointer to a camera to be the source for the image.
+            @param
+                target Pointer to the render target to be the destination
+                for the rendering.
+            @param
+                left
+            @param
+                top
+            @param
+                width
+            @param
+                height
+                Dimensions of the viewport, expressed as a value between
+                0 and 1. This allows the dimensions to apply irrespective of
+                changes in the target's size: e.g. to fill the whole area,
+                values of 0,0,1,1 are appropriate.
+            @param
+                ZOrder Relative Z-order on the target. Lower = further to
+                the front.
+        */
+        Viewport(
+            RenderTarget* target,
+            Real left, Real top,
+            Real width, Real height,
+            int ZOrder);
+
+        /** Default destructor.
+        */
+        virtual ~Viewport();
+
+        /** Notifies the viewport of a possible change in dimensions.
+            @remarks
+                Used by the target to update the viewport's dimensions
+                (usually the result of a change in target size).
+            @note
+                Internal use by Ogre only.
+        */
+        void _updateDimensions(void);
+
+        /** Instructs the viewport to updates its contents.
+        */
+        virtual void update(void);
+		
+		/** Instructs the viewport to clear itself, without performing an update.
+		 @remarks
+			You would not normally call this method when updating the viewport, 
+			since the viewport usually clears itself when updating anyway (@see 
+		    Viewport::setClearEveryFrame). However, if you wish you have the
+			option of manually clearing the frame buffer (or elements of it)
+		    using this method.
+		 @param buffers Bitmask identifying which buffer elements to clear
+		 @param colour The colour value to clear to, if FBT_COLOUR is included
+		 @param depth The depth value to clear to, if FBT_DEPTH is included
+		 @param stencil The stencil value to clear to, if FBT_STENCIL is included
+		*/
+		void clear(unsigned int buffers = FBT_COLOUR | FBT_DEPTH,
+				   const ColourValue& colour = ColourValue::Black, 
+				   Real depth = 1.0f, unsigned short stencil = 0);
+
+        /** Retrieves a pointer to the render target for this viewport.
+        */
+        RenderTarget* getTarget(void) const;
+
+        /** Gets the Z-Order of this viewport. */
+		int getZOrder(void) const;
+		/** Gets one of the relative dimensions of the viewport,
+            a value between 0.0 and 1.0.
+        */
+        Real getLeft(void) const;
+
+        /** Gets one of the relative dimensions of the viewport, a value
+            between 0.0 and 1.0.
+        */
+        Real getTop(void) const;
+
+        /** Gets one of the relative dimensions of the viewport, a value
+            between 0.0 and 1.0.
+        */
+
+        Real getWidth(void) const;
+        /** Gets one of the relative dimensions of the viewport, a value
+            between 0.0 and 1.0.
+        */
+
+        Real getHeight(void) const;
+        /** Gets one of the actual dimensions of the viewport, a value in
+            pixels.
+        */
+
+        int getActualLeft(void) const;
+        /** Gets one of the actual dimensions of the viewport, a value in
+            pixels.
+        */
+
+        int getActualTop(void) const;
+        /** Gets one of the actual dimensions of the viewport, a value in
+            pixels.
+        */
+        int getActualWidth(void) const;
+        /** Gets one of the actual dimensions of the viewport, a value in
+            pixels.
+        */
+
+        int getActualHeight(void) const;
+               
+        /** Sets the dimensions (after creation).
+            @param
+                left
+            @param
+                top
+            @param
+                width
+            @param
+                height Dimensions relative to the size of the target,
+                represented as real values between 0 and 1. i.e. the full
+                target area is 0, 0, 1, 1.
+        */
+        void setDimensions(Real left, Real top, Real width, Real height);
+
+        /** Set the orientation mode of the viewport.
+        */
+        void setOrientationMode(OrientationMode orientationMode, bool setDefault = true);
+
+        /** Get the orientation mode of the viewport.
+        */
+        OrientationMode getOrientationMode() const;
+
+        /** Set the initial orientation mode of viewports.
+        */
+        static void setDefaultOrientationMode(OrientationMode orientationMode);
+
+        /** Get the initial orientation mode of viewports.
+        */
+        static OrientationMode getDefaultOrientationMode();
+
+        /** Sets the initial background colour of the viewport (before
+            rendering).
+        */
+        void setBackgroundColour(const ColourValue& colour);
+
+        /** Gets the background colour.
+        */
+        const ColourValue& getBackgroundColour(void) const;
+
+        /** Determines whether to clear the viewport before rendering.
+		@remarks
+			You can use this method to set which buffers are cleared
+			(if any) before rendering every frame.
+        @param clear Whether or not to clear any buffers
+		@param buffers One or more values from FrameBufferType denoting
+			which buffers to clear, if clear is set to true. Note you should
+			not clear the stencil buffer here unless you know what you're doing.
+         */
+        void setClearEveryFrame(bool clear, unsigned int buffers = FBT_COLOUR | FBT_DEPTH);
+
+        /** Determines if the viewport is cleared before every frame.
+        */
+        bool getClearEveryFrame(void) const;
+
+		/** Gets which buffers are to be cleared each frame. */
+        unsigned int getClearBuffers(void) const;
+
+		/** Sets whether this viewport should be automatically updated 
+			if Ogre's rendering loop or RenderTarget::update is being used.
+        @remarks
+            By default, if you use Ogre's own rendering loop (Root::startRendering)
+            or call RenderTarget::update, all viewports are updated automatically.
+            This method allows you to control that behaviour, if for example you 
+			have a viewport which you only want to update periodically.
+        @param autoupdate If true, the viewport is updated during the automatic
+            render loop or when RenderTarget::update() is called. If false, the 
+            viewport is only updated when its update() method is called explicitly.
+        */
+		void setAutoUpdated(bool autoupdate);
+		/** Gets whether this viewport is automatically updated if 
+			Ogre's rendering loop or RenderTarget::update is being used.
+        */
+		bool isAutoUpdated() const;
+
+		/** Set the material scheme which the viewport should use.
+		@remarks
+			This allows you to tell the system to use a particular
+			material scheme when rendering this viewport, which can 
+			involve using different techniques to render your materials.
+		@see Technique::setSchemeName
+		*/
+		void setMaterialScheme(const String& schemeName)
+		{ mMaterialSchemeName = schemeName; }
+		
+		/** Get the material scheme which the viewport should use.
+		*/
+		const String& getMaterialScheme(void) const
+		{ return mMaterialSchemeName; }
+
+		/** Access to actual dimensions (based on target size).
+        */
+        void getActualDimensions(
+            int &left, int &top, int &width, int &height ) const;
+
+        bool _isUpdated(void) const;
+        void _clearUpdatedFlag(void);
+
+        /** Tells this viewport whether it should display Overlay objects.
+        @remarks
+            Overlay objects are layers which appear on top of the scene. They are created via
+            SceneManager::createOverlay and every viewport displays these by default.
+            However, you probably don't want this if you're using multiple viewports,
+            because one of them is probably a picture-in-picture which is not supposed to
+            have overlays of it's own. In this case you can turn off overlays on this viewport
+            by calling this method.
+        @param enabled If true, any overlays are displayed, if false they are not.
+        */
+        void setOverlaysEnabled(bool enabled);
+
+        /** Returns whether or not Overlay objects (created in the SceneManager) are displayed in this
+            viewport. */
+        bool getOverlaysEnabled(void) const;
+
+        /** Tells this viewport whether it should display skies.
+        @remarks
+            Skies are layers which appear on background of the scene. They are created via
+            SceneManager::setSkyBox, SceneManager::setSkyPlane and SceneManager::setSkyDome and
+            every viewport displays these by default. However, you probably don't want this if
+            you're using multiple viewports, because one of them is probably a picture-in-picture
+            which is not supposed to have skies of it's own. In this case you can turn off skies
+            on this viewport by calling this method.
+        @param enabled If true, any skies are displayed, if false they are not.
+        */
+        void setSkiesEnabled(bool enabled);
+
+        /** Returns whether or not skies (created in the SceneManager) are displayed in this
+            viewport. */
+        bool getSkiesEnabled(void) const;
+
+        /** Tells this viewport whether it should display shadows.
+        @remarks
+            This setting enables you to disable shadow rendering for a given viewport. The global
+			shadow technique set on SceneManager still controls the type and nature of shadows,
+			but this flag can override the setting so that no shadows are rendered for a given
+			viewport to save processing time where they are not required.
+        @param enabled If true, any shadows are displayed, if false they are not.
+        */
+        void setShadowsEnabled(bool enabled);
+
+        /** Returns whether or not shadows (defined in the SceneManager) are displayed in this
+            viewport. */
+        bool getShadowsEnabled(void) const;
+
+
+		/** Sets a per-viewport visibility mask.
+		@remarks
+			The visibility mask is a way to exclude objects from rendering for
+			a given viewport. For each object in the frustum, a check is made
+			between this mask and the objects visibility flags 
+			(@see MovableObject::setVisibilityFlags), and if a binary 'and'
+			returns zero, the object will not be rendered.
+		*/
+		void setVisibilityMask(uint32 mask) { mVisibilityMask = mask; }
+
+		/** Gets a per-viewport visibility mask.
+		@see Viewport::setVisibilityMask
+		*/
+		uint getVisibilityMask(void) const { return mVisibilityMask; }
+
+		/** Sets the use of a custom RenderQueueInvocationSequence for
+			rendering this target.
+		@remarks
+			RenderQueueInvocationSequence instances are managed through Root. By
+			setting this, you are indicating that you wish this RenderTarget to
+			be updated using a custom sequence of render queue invocations, with
+			potentially customised ordering and render state options. You should
+			create the named sequence through Root first, then set the name here.
+		@param The name of the RenderQueueInvocationSequence to use. If you
+			specify a blank string, behaviour will return to the default render
+			queue management.
+		*/
+		virtual void setRenderQueueInvocationSequenceName(const String& sequenceName);
+		/** Gets the name of the render queue invocation sequence for this target. */
+		virtual const String& getRenderQueueInvocationSequenceName(void) const;
+		/// Get the invocation sequence - will return null if using standard
+		RenderQueueInvocationSequence* _getRenderQueueInvocationSequence(void);
+
+        /** Convert oriented input point coordinates to screen coordinates. */
+        void pointOrientedToScreen(const Vector2 &v, int orientationMode, Vector2 &outv);
+        void pointOrientedToScreen(Real orientedX, Real orientedY, int orientationMode,
+                                   Real &screenX, Real &screenY);
+
+    protected:
+        RenderTarget* mTarget;
+        // Relative dimensions, irrespective of target dimensions (0..1)
+        float mRelLeft, mRelTop, mRelWidth, mRelHeight;
+        // Actual dimensions, based on target dimensions
+        int mActLeft, mActTop, mActWidth, mActHeight;
+        /// ZOrder
+        int mZOrder;
+        /// Background options
+        ColourValue mBackColour;
+        bool mClearEveryFrame;
+		unsigned int mClearBuffers;
+        bool mUpdated;
+        bool mShowOverlays;
+        bool mShowSkies;
+		bool mShowShadows;
+		uint32 mVisibilityMask;
+		// Render queue invocation sequence name
+		String mRQSequenceName;
+		RenderQueueInvocationSequence* mRQSequence;
+		/// Material scheme
+		String mMaterialSchemeName;
+        /// Viewport orientation mode
+        OrientationMode mOrientationMode;
+        static OrientationMode mDefaultOrientationMode;
+
+		/// Automatic rendering on/off
+		bool mIsAutoUpdated;
+    };
+	/** @} */
+	/** @} */
+
+}
+
+#endif