Przeglądaj źródła

RenderSystem ported

Marko Pintera 13 lat temu
rodzic
commit
3e580756f0

+ 7 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -84,6 +84,7 @@
     <ClInclude Include="OgreAlignedAllocator.h" />
     <ClInclude Include="OgreAxisAlignedBox.h" />
     <ClInclude Include="OgreBitwise.h" />
+    <ClInclude Include="OgreBlendMode.h" />
     <ClInclude Include="OgreBuildSettings.h" />
     <ClInclude Include="OgreColourValue.h" />
     <ClInclude Include="OgreCommon.h" />
@@ -118,6 +119,7 @@
     <ClInclude Include="OgreQuaternion.h" />
     <ClInclude Include="OgreRay.h" />
     <ClInclude Include="OgreRenderOperation.h" />
+    <ClInclude Include="OgreRenderSystem.h" />
     <ClInclude Include="OgreRenderSystemCapabilities.h" />
     <ClInclude Include="OgreRenderTarget.h" />
     <ClInclude Include="OgreRenderTexture.h" />
@@ -130,6 +132,8 @@
     <ClInclude Include="OgreStringConverter.h" />
     <ClInclude Include="OgreStringInterface.h" />
     <ClInclude Include="OgreStringVector.h" />
+    <ClInclude Include="OgreTexture.h" />
+    <ClInclude Include="OgreTextureUnitState.h" />
     <ClInclude Include="OgreThreadDefines.h" />
     <ClInclude Include="OgreVector2.h" />
     <ClInclude Include="OgreVector3.h" />
@@ -163,6 +167,7 @@
     <ClCompile Include="OgrePixelFormat.cpp" />
     <ClCompile Include="OgrePlane.cpp" />
     <ClCompile Include="OgreQuaternion.cpp" />
+    <ClCompile Include="OgreRenderSystem.cpp" />
     <ClCompile Include="OgreRenderSystemCapabilities.cpp" />
     <ClCompile Include="OgreRenderTarget.cpp" />
     <ClCompile Include="OgreRenderTexture.cpp" />
@@ -170,6 +175,8 @@
     <ClCompile Include="OgreString.cpp" />
     <ClCompile Include="OgreStringConverter.cpp" />
     <ClCompile Include="OgreStringInterface.cpp" />
+    <ClCompile Include="OgreTexture.cpp" />
+    <ClCompile Include="OgreTextureUnitState.cpp" />
     <ClCompile Include="OgreVector2.cpp" />
     <ClCompile Include="OgreVector3.cpp" />
     <ClCompile Include="OgreVector4.cpp" />

+ 21 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -210,6 +210,18 @@
     <ClInclude Include="OgreImageResampler.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="OgreRenderSystem.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="OgreBlendMode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="OgreTextureUnitState.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="OgreTexture.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="stdafx.cpp">
@@ -320,5 +332,14 @@
     <ClCompile Include="OgreHardwarePixelBuffer.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="OgreRenderSystem.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="OgreTextureUnitState.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="OgreTexture.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 266 - 0
CamelotRenderer/OgreBlendMode.h

@@ -0,0 +1,266 @@
+/*
+-----------------------------------------------------------------------------
+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 __BLENDMODE_H__
+#define __BLENDMODE_H__
+
+#include "OgrePrerequisites.h"
+#include "OgreColourValue.h"
+
+namespace Ogre {
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup Materials
+	*  @{
+	*/
+
+    /** Type of texture blend mode.
+    */
+    enum LayerBlendType
+    {
+        LBT_COLOUR,
+        LBT_ALPHA
+    };
+
+    /** List of valid texture blending operations, for use with TextureUnitState::setColourOperation.
+        @remarks
+            This list is a more limited list than LayerBlendOperationEx because it only
+            includes operations that are supportable in both multipass and multitexture
+            rendering and thus provides automatic fallback if multitexture hardware
+            is lacking or insufficient.
+    */
+    enum LayerBlendOperation {
+        /// Replace all colour with texture with no adjustment
+        LBO_REPLACE,
+        /// Add colour components together.
+        LBO_ADD,
+        /// Multiply colour components together.
+        LBO_MODULATE,
+        /// Blend based on texture alpha
+        LBO_ALPHA_BLEND
+
+    };
+
+    /** Expert list of valid texture blending operations, for use with TextureUnitState::setColourOperationEx
+        and TextureUnitState::setAlphaOperation, and internally in the LayerBlendModeEx class. It's worth
+        noting that these operations are for blending <i>between texture layers</i> and not between rendered objects
+        and the existing scene. Because all of these modes are only supported in multitexture hardware it may be
+        required to set up a fallback operation where this hardware is not available.
+    */
+    enum LayerBlendOperationEx {
+        /// use source1 without modification
+        LBX_SOURCE1,
+        /// use source2 without modification
+        LBX_SOURCE2,
+        /// multiply source1 and source2 together
+        LBX_MODULATE,
+        /// as LBX_MODULATE but brighten afterwards (x2)
+        LBX_MODULATE_X2,
+        /// as LBX_MODULATE but brighten more afterwards (x4)
+        LBX_MODULATE_X4,
+        /// add source1 and source2 together
+        LBX_ADD,
+        /// as LBX_ADD, but subtract 0.5 from the result
+        LBX_ADD_SIGNED,
+        /// as LBX_ADD, but subtract product from the sum
+        LBX_ADD_SMOOTH,
+        /// subtract source2 from source1
+        LBX_SUBTRACT,
+        /// use interpolated alpha value from vertices to scale source1, then add source2 scaled by (1-alpha)
+        LBX_BLEND_DIFFUSE_ALPHA,
+        /// as LBX_BLEND_DIFFUSE_ALPHA, but use alpha from texture
+        LBX_BLEND_TEXTURE_ALPHA,
+        /// as LBX_BLEND_DIFFUSE_ALPHA, but use current alpha from previous stages
+        LBX_BLEND_CURRENT_ALPHA,
+        /// as LBX_BLEND_DIFFUSE_ALPHA but use a constant manual blend value (0.0-1.0)
+        LBX_BLEND_MANUAL,
+        /// dot product of color1 and color2 
+        LBX_DOTPRODUCT,
+        /// use interpolated color values from vertices to scale source1, then add source2 scaled by (1-color)
+        LBX_BLEND_DIFFUSE_COLOUR
+    };
+
+    /** List of valid sources of values for blending operations used
+        in TextureUnitState::setColourOperation and TextureUnitState::setAlphaOperation,
+        and internally in the LayerBlendModeEx class.
+    */
+    enum LayerBlendSource
+    {
+        /// the colour as built up from previous stages
+        LBS_CURRENT,
+        /// the colour derived from the texture assigned to this layer
+        LBS_TEXTURE,
+        /// the interpolated diffuse colour from the vertices
+        LBS_DIFFUSE,
+        /// the interpolated specular colour from the vertices
+        LBS_SPECULAR,
+        /// a colour supplied manually as a separate argument
+        LBS_MANUAL
+    };
+    /** Class which manages blending of both colour and alpha components.
+        @remarks
+            This class is a utility class used by both TextureUnitState and
+            RenderSystem to wrap up the details of a blending operation. This blending
+            operation could be used for blending colour or alpha in a texture layer.
+            This class is really only for use by OGRE, since apps can deal with
+            blending modes through the TextureUnitState class methods
+            setColourOperation and setAlphaOperation.
+        @par
+            It's worth noting that these operations are for blending <i>between texture
+            layers</i> and not between rendered objects and the existing scene. If
+            you wish to make an object blend with others in the scene, e.g. to make
+            transparent objects etc, use the Material::setSceneBlending method.
+    */
+    class _OgreExport LayerBlendModeEx
+    {
+    public:
+        /// The type of blending (colour or alpha)
+        LayerBlendType blendType;
+        /// The operation to be applied
+        LayerBlendOperationEx operation;
+        /// The first source of colour/alpha
+        LayerBlendSource source1;
+        /// The second source of colour/alpha
+        LayerBlendSource source2;
+
+        /// Manual colour value for manual source1
+        ColourValue colourArg1;
+        /// Manual colour value for manual source2
+        ColourValue colourArg2;
+        /// Manual alpha value for manual source1
+        Real alphaArg1;
+        /// Manual alpha value for manual source2
+        Real alphaArg2;
+        /// Manual blending factor
+        Real factor;
+
+        bool operator==(const LayerBlendModeEx& rhs) const
+        {
+            if (blendType != rhs.blendType) return false;
+
+            if (blendType == LBT_COLOUR)
+            {
+
+                if (operation == rhs.operation &&
+                    source1 == rhs.source1 &&
+                    source2 == rhs.source2 &&
+                    colourArg1 == rhs.colourArg1 &&
+                    colourArg2 == rhs.colourArg2 &&
+                    factor == rhs.factor)
+                {
+                    return true;
+                }
+            }
+            else // if (blendType == LBT_ALPHA)
+            {
+                if (operation == rhs.operation &&
+                    source1 == rhs.source1 &&
+                    source2 == rhs.source2 &&
+                    alphaArg1 == rhs.alphaArg1 &&
+                    alphaArg2 == rhs.alphaArg2 &&
+                    factor == rhs.factor)
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        bool operator!=(const LayerBlendModeEx& rhs) const
+        {
+            return !(*this == rhs);
+        }
+
+
+
+    };
+
+    /** Types of blending that you can specify between an object and the existing contents of the scene.
+        @remarks
+            As opposed to the LayerBlendType, which classifies blends between texture layers, these blending
+            types blend between the output of the texture units and the pixels already in the viewport,
+            allowing for object transparency, glows, etc.
+        @par
+            These types are provided to give quick and easy access to common effects. You can also use
+            the more manual method of supplying source and destination blending factors.
+            See Material::setSceneBlending for more details.
+        @see
+            Material::setSceneBlending
+    */
+    enum SceneBlendType
+    {
+        /// Make the object transparent based on the final alpha values in the texture
+        SBT_TRANSPARENT_ALPHA,
+        /// Make the object transparent based on the colour values in the texture (brighter = more opaque)
+        SBT_TRANSPARENT_COLOUR,
+        /// Add the texture values to the existing scene content
+        SBT_ADD,
+		/// Multiply the 2 colours together
+		SBT_MODULATE,
+        /// The default blend mode where source replaces destination
+        SBT_REPLACE
+        // TODO : more
+    };
+
+    /** Blending factors for manually blending objects with the scene. If there isn't a predefined
+        SceneBlendType that you like, then you can specify the blending factors directly to affect the
+        combination of object and the existing scene. See Material::setSceneBlending for more details.
+    */
+    enum SceneBlendFactor
+    {
+        SBF_ONE,
+        SBF_ZERO,
+        SBF_DEST_COLOUR,
+        SBF_SOURCE_COLOUR,
+        SBF_ONE_MINUS_DEST_COLOUR,
+        SBF_ONE_MINUS_SOURCE_COLOUR,
+        SBF_DEST_ALPHA,
+        SBF_SOURCE_ALPHA,
+        SBF_ONE_MINUS_DEST_ALPHA,
+        SBF_ONE_MINUS_SOURCE_ALPHA
+
+    };
+
+	/** Blending operations controls how objects are blended into the scene. The default operation
+		is add (+) but by changing this you can change how drawn objects are blended into the
+		existing scene.
+	*/
+	enum SceneBlendOperation
+	{
+		SBO_ADD,
+		SBO_SUBTRACT,
+		SBO_REVERSE_SUBTRACT,
+		SBO_MIN,
+		SBO_MAX
+	};
+	/** @} */
+	/** @} */
+
+}
+
+#endif

+ 739 - 0
CamelotRenderer/OgreRenderSystem.cpp

@@ -0,0 +1,739 @@
+/*
+-----------------------------------------------------------------------------
+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.
+-----------------------------------------------------------------------------
+*/
+// RenderSystem implementation
+// Note that most of this class is abstract since
+//  we cannot know how to implement the behaviour without
+//  being aware of the 3D API. However there are a few
+//  simple functions which can have a base implementation
+
+#include "OgreRenderSystem.h"
+
+#include "OgreViewport.h"
+#include "OgreException.h"
+#include "OgreRenderTarget.h"
+#include "OgreRenderWindow.h"
+#include "OgreHardwarePixelBuffer.h"
+#include "OgreHardwareOcclusionQuery.h"
+
+namespace Ogre {
+
+    static const TexturePtr sNullTexPtr;
+
+    //-----------------------------------------------------------------------
+    RenderSystem::RenderSystem()
+        : mActiveRenderTarget(0)
+        , mTextureManager(0)
+        , mActiveViewport(0)
+        // This means CULL clockwise vertices, i.e. front of poly is counter-clockwise
+        // This makes it the same as OpenGL and other right-handed systems
+        , mCullingMode(CULL_CLOCKWISE)
+        , mVSync(true)
+		, mVSyncInterval(1)
+		, mWBuffer(false)
+        , mInvertVertexWinding(false)
+        , mDisabledTexUnitsFrom(0)
+        , mCurrentPassIterationCount(0)
+		, mDerivedDepthBias(false)
+        , mVertexProgramBound(false)
+		, mGeometryProgramBound(false)
+        , mFragmentProgramBound(false)
+		, mClipPlanesDirty(true)
+		, mRealCapabilities(0)
+		, mCurrentCapabilities(0)
+		, mUseCustomCapabilities(false)
+		, mTexProjRelative(false)
+		, mTexProjRelativeOrigin(Vector3::ZERO)
+    {
+    }
+
+    //-----------------------------------------------------------------------
+    RenderSystem::~RenderSystem()
+    {
+        shutdown();
+		OGRE_DELETE mRealCapabilities;
+		mRealCapabilities = 0;
+		// Current capabilities managed externally
+		mCurrentCapabilities = 0;
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::_initRenderTargets(void)
+    {
+
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::_updateAllRenderTargets(bool swapBuffers)
+    {
+        // Update all in order of priority
+        // This ensures render-to-texture targets get updated before render windows
+		RenderTargetPriorityMap::iterator itarg, itargend;
+		itargend = mPrioritisedRenderTargets.end();
+		for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
+		{
+			if( itarg->second->isActive() && itarg->second->isAutoUpdated())
+				itarg->second->update(swapBuffers);
+		}
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::_swapAllRenderTargetBuffers(bool waitForVSync)
+    {
+        // Update all in order of priority
+        // This ensures render-to-texture targets get updated before render windows
+		RenderTargetPriorityMap::iterator itarg, itargend;
+		itargend = mPrioritisedRenderTargets.end();
+		for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
+		{
+			if( itarg->second->isActive() && itarg->second->isAutoUpdated())
+				itarg->second->swapBuffers(waitForVSync);
+		}
+    }
+    //-----------------------------------------------------------------------
+    RenderWindow* RenderSystem::_initialise(bool autoCreateWindow, const String& windowTitle)
+    {
+        // Have I been registered by call to Root::setRenderSystem?
+		/** Don't do this anymore, just allow via Root
+        RenderSystem* regPtr = Root::getSingleton().getRenderSystem();
+        if (!regPtr || regPtr != this)
+            // Register self - library user has come to me direct
+            Root::getSingleton().setRenderSystem(this);
+		*/
+
+
+        // Subclasses should take it from here
+        // They should ALL call this superclass method from
+        //   their own initialise() implementations.
+        
+        mVertexProgramBound = false;
+		mGeometryProgramBound = false;
+        mFragmentProgramBound = false;
+
+        return 0;
+    }
+
+	//---------------------------------------------------------------------------------------------
+	void RenderSystem::useCustomRenderSystemCapabilities(RenderSystemCapabilities* capabilities)
+	{
+    if (mRealCapabilities != 0)
+    {
+      OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
+          "Custom render capabilities must be set before the RenderSystem is initialised.",
+          "RenderSystem::useCustomRenderSystemCapabilities");
+    }
+
+		mCurrentCapabilities = capabilities;
+		mUseCustomCapabilities = true;
+	}
+
+	//---------------------------------------------------------------------------------------------
+	bool RenderSystem::_createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, 
+		RenderWindowList& createdWindows)
+	{
+		unsigned int fullscreenWindowsCount = 0;
+
+		// Grab some information and avoid duplicate render windows.
+		for (unsigned int nWindow=0; nWindow < renderWindowDescriptions.size(); ++nWindow)
+		{
+			const RenderWindowDescription* curDesc = &renderWindowDescriptions[nWindow];
+
+			// Count full screen windows.
+			if (curDesc->useFullScreen)			
+				fullscreenWindowsCount++;	
+
+			bool renderWindowFound = false;
+
+			if (mRenderTargets.find(curDesc->name) != mRenderTargets.end())
+				renderWindowFound = true;
+			else
+			{
+				for (unsigned int nSecWindow = nWindow + 1 ; nSecWindow < renderWindowDescriptions.size(); ++nSecWindow)
+				{
+					if (curDesc->name == renderWindowDescriptions[nSecWindow].name)
+					{
+						renderWindowFound = true;
+						break;
+					}					
+				}
+			}
+
+			// Make sure we don't already have a render target of the 
+			// same name as the one supplied
+			if(renderWindowFound)
+			{
+				String msg;
+
+				msg = "A render target of the same name '" + String(curDesc->name) + "' already "
+					"exists.  You cannot create a new window with this name.";
+				OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, msg, "RenderSystem::createRenderWindow" );
+			}
+		}
+		
+		// Case we have to create some full screen rendering windows.
+		if (fullscreenWindowsCount > 0)
+		{
+			// Can not mix full screen and windowed rendering windows.
+			if (fullscreenWindowsCount != renderWindowDescriptions.size())
+			{
+				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
+					"Can not create mix of full screen and windowed rendering windows",
+					"RenderSystem::createRenderWindows");
+			}					
+		}
+
+		return true;
+	}
+
+    //---------------------------------------------------------------------------------------------
+    void RenderSystem::destroyRenderWindow(const String& name)
+    {
+        destroyRenderTarget(name);
+    }
+    //---------------------------------------------------------------------------------------------
+    void RenderSystem::destroyRenderTexture(const String& name)
+    {
+        destroyRenderTarget(name);
+    }
+    //---------------------------------------------------------------------------------------------
+    void RenderSystem::destroyRenderTarget(const String& name)
+    {
+        RenderTarget* rt = detachRenderTarget(name);
+        OGRE_DELETE rt;
+    }
+    //---------------------------------------------------------------------------------------------
+    void RenderSystem::attachRenderTarget( RenderTarget &target )
+    {
+		assert( target.getPriority() < OGRE_NUM_RENDERTARGET_GROUPS );
+
+        mRenderTargets.insert( RenderTargetMap::value_type( target.getName(), &target ) );
+        mPrioritisedRenderTargets.insert(
+            RenderTargetPriorityMap::value_type(target.getPriority(), &target ));
+    }
+
+    //---------------------------------------------------------------------------------------------
+    RenderTarget * RenderSystem::getRenderTarget( const String &name )
+    {
+        RenderTargetMap::iterator it = mRenderTargets.find( name );
+        RenderTarget *ret = NULL;
+
+        if( it != mRenderTargets.end() )
+        {
+            ret = it->second;
+        }
+
+        return ret;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    RenderTarget * RenderSystem::detachRenderTarget( const String &name )
+    {
+        RenderTargetMap::iterator it = mRenderTargets.find( name );
+        RenderTarget *ret = NULL;
+
+        if( it != mRenderTargets.end() )
+        {
+            ret = it->second;
+			
+			/* Remove the render target from the priority groups. */
+            RenderTargetPriorityMap::iterator itarg, itargend;
+            itargend = mPrioritisedRenderTargets.end();
+			for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg )
+            {
+				if( itarg->second == ret ) {
+					mPrioritisedRenderTargets.erase( itarg );
+					break;
+				}
+            }
+
+            mRenderTargets.erase( it );
+        }
+        /// If detached render target is the active render target, reset active render target
+        if(ret == mActiveRenderTarget)
+            mActiveRenderTarget = 0;
+
+        return ret;
+    }
+    //-----------------------------------------------------------------------
+    Viewport* RenderSystem::_getViewport(void)
+    {
+        return mActiveViewport;
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::_setTextureUnitSettings(size_t texUnit, TextureUnitState& tl)
+    {
+        // This method is only ever called to set a texture unit to valid details
+        // The method _disableTextureUnit is called to turn a unit off
+
+        const TexturePtr& tex = tl._getTexturePtr();
+		// Vertex texture binding?
+		if (mCurrentCapabilities->hasCapability(RSC_VERTEX_TEXTURE_FETCH) &&
+			!mCurrentCapabilities->getVertexTextureUnitsShared())
+		{
+			if (tl.getBindingType() == TextureUnitState::BT_VERTEX)
+			{
+				// Bind vertex texture
+				_setVertexTexture(texUnit, tex);
+				// bind nothing to fragment unit (hardware isn't shared but fragment
+				// unit can't be using the same index
+				_setTexture(texUnit, true, sNullTexPtr);
+			}
+			else
+			{
+				// vice versa
+				_setVertexTexture(texUnit, sNullTexPtr);
+				_setTexture(texUnit, true, tex);
+			}
+		}
+		else
+		{
+			// Shared vertex / fragment textures or no vertex texture support
+			// Bind texture (may be blank)
+			_setTexture(texUnit, true, tex);
+		}
+
+        // Set texture coordinate set
+        _setTextureCoordSet(texUnit, tl.getTextureCoordSet());
+
+        // Set texture layer filtering
+        _setTextureUnitFiltering(texUnit, 
+            tl.getTextureFiltering(FT_MIN), 
+            tl.getTextureFiltering(FT_MAG), 
+            tl.getTextureFiltering(FT_MIP));
+
+        // Set texture layer filtering
+        _setTextureLayerAnisotropy(texUnit, tl.getTextureAnisotropy());
+
+		// Set mipmap biasing
+		_setTextureMipmapBias(texUnit, tl.getTextureMipmapBias());
+
+		// Set blend modes
+		// Note, colour before alpha is important
+        _setTextureBlendMode(texUnit, tl.getColourBlendMode());
+        _setTextureBlendMode(texUnit, tl.getAlphaBlendMode());
+
+        // Texture addressing mode
+        const TextureUnitState::UVWAddressingMode& uvw = tl.getTextureAddressingMode();
+        _setTextureAddressingMode(texUnit, uvw);
+        // Set texture border colour only if required
+        if (uvw.u == TextureUnitState::TAM_BORDER ||
+            uvw.v == TextureUnitState::TAM_BORDER ||
+            uvw.w == TextureUnitState::TAM_BORDER)
+        {
+            _setTextureBorderColour(texUnit, tl.getTextureBorderColour());
+        }
+
+        // Set texture effects
+        TextureUnitState::EffectMap::iterator effi;
+        // Iterate over new effects
+        bool anyCalcs = false;
+        for (effi = tl.mEffects.begin(); effi != tl.mEffects.end(); ++effi)
+        {
+            switch (effi->second.type)
+            {
+            case TextureUnitState::ET_ENVIRONMENT_MAP:
+                if (effi->second.subtype == TextureUnitState::ENV_CURVED)
+                {
+                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP);
+                    anyCalcs = true;
+                }
+                else if (effi->second.subtype == TextureUnitState::ENV_PLANAR)
+                {
+                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_PLANAR);
+                    anyCalcs = true;
+                }
+                else if (effi->second.subtype == TextureUnitState::ENV_REFLECTION)
+                {
+                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_REFLECTION);
+                    anyCalcs = true;
+                }
+                else if (effi->second.subtype == TextureUnitState::ENV_NORMAL)
+                {
+                    _setTextureCoordCalculation(texUnit, TEXCALC_ENVIRONMENT_MAP_NORMAL);
+                    anyCalcs = true;
+                }
+                break;
+            case TextureUnitState::ET_UVSCROLL:
+			case TextureUnitState::ET_USCROLL:
+			case TextureUnitState::ET_VSCROLL:
+            case TextureUnitState::ET_ROTATE:
+            case TextureUnitState::ET_TRANSFORM:
+                break;
+            case TextureUnitState::ET_PROJECTIVE_TEXTURE:
+                _setTextureCoordCalculation(texUnit, TEXCALC_PROJECTIVE_TEXTURE, 
+                    effi->second.frustum);
+                anyCalcs = true;
+                break;
+            }
+        }
+        // Ensure any previous texcoord calc settings are reset if there are now none
+        if (!anyCalcs)
+        {
+            _setTextureCoordCalculation(texUnit, TEXCALC_NONE);
+        }
+
+        // Change tetxure matrix 
+        _setTextureMatrix(texUnit, tl.getTextureTransform());
+
+
+    }
+	//-----------------------------------------------------------------------
+	void RenderSystem::_setVertexTexture(size_t unit, const TexturePtr& tex)
+	{
+		OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 
+			"This rendersystem does not support separate vertex texture samplers, "
+			"you should use the regular texture samplers which are shared between "
+			"the vertex and fragment units.", 
+			"RenderSystem::_setVertexTexture");
+	}
+    //-----------------------------------------------------------------------
+    void RenderSystem::_disableTextureUnit(size_t texUnit)
+    {
+        _setTexture(texUnit, false, sNullTexPtr);
+    }
+    //---------------------------------------------------------------------
+    void RenderSystem::_disableTextureUnitsFrom(size_t texUnit)
+    {
+        size_t disableTo = OGRE_MAX_TEXTURE_LAYERS;
+        if (disableTo > mDisabledTexUnitsFrom)
+            disableTo = mDisabledTexUnitsFrom;
+        mDisabledTexUnitsFrom = texUnit;
+        for (size_t i = texUnit; i < disableTo; ++i)
+        {
+            _disableTextureUnit(i);
+        }
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::_setTextureUnitFiltering(size_t unit, FilterOptions minFilter,
+            FilterOptions magFilter, FilterOptions mipFilter)
+    {
+        _setTextureUnitFiltering(unit, FT_MIN, minFilter);
+        _setTextureUnitFiltering(unit, FT_MAG, magFilter);
+        _setTextureUnitFiltering(unit, FT_MIP, mipFilter);
+    }
+    //-----------------------------------------------------------------------
+    CullingMode RenderSystem::_getCullingMode(void) const
+    {
+        return mCullingMode;
+    }
+    //-----------------------------------------------------------------------
+    bool RenderSystem::getWaitForVerticalBlank(void) const
+    {
+        return mVSync;
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::setWaitForVerticalBlank(bool enabled)
+    {
+        mVSync = enabled;
+    }
+    bool RenderSystem::getWBufferEnabled(void) const
+    {
+        return mWBuffer;
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::setWBufferEnabled(bool enabled)
+    {
+        mWBuffer = enabled;
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::shutdown(void)
+    {
+		// Remove occlusion queries
+		for (HardwareOcclusionQueryList::iterator i = mHwOcclusionQueries.begin();
+			i != mHwOcclusionQueries.end(); ++i)
+		{
+			OGRE_DELETE *i;
+		}
+		mHwOcclusionQueries.clear();
+
+        // Remove all the render targets.
+		// (destroy primary target last since others may depend on it)
+		RenderTarget* primary = 0;
+		for (RenderTargetMap::iterator it = mRenderTargets.begin(); it != mRenderTargets.end(); ++it)
+		{
+			if (!primary && it->second->isPrimary())
+				primary = it->second;
+			else
+				OGRE_DELETE it->second;
+		}
+		OGRE_DELETE primary;
+		mRenderTargets.clear();
+
+		mPrioritisedRenderTargets.clear();
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::_beginGeometryCount(void)
+    {
+        mBatchCount = mFaceCount = mVertexCount = 0;
+
+    }
+    //-----------------------------------------------------------------------
+    unsigned int RenderSystem::_getFaceCount(void) const
+    {
+        return static_cast< unsigned int >( mFaceCount );
+    }
+    //-----------------------------------------------------------------------
+    unsigned int RenderSystem::_getBatchCount(void) const
+    {
+        return static_cast< unsigned int >( mBatchCount );
+    }
+    //-----------------------------------------------------------------------
+    unsigned int RenderSystem::_getVertexCount(void) const
+    {
+        return static_cast< unsigned int >( mVertexCount );
+    }
+    //-----------------------------------------------------------------------
+	void RenderSystem::convertColourValue(const ColourValue& colour, uint32* pDest)
+	{
+		*pDest = VertexElement::convertColourValue(colour, getColourVertexElementType());
+
+	}
+    //-----------------------------------------------------------------------
+    void RenderSystem::_setWorldMatrices(const Matrix4* m, unsigned short count)
+    {
+        // Do nothing with these matrices here, it never used for now,
+		// derived class should take care with them if required.
+
+        // Set hardware matrix to nothing
+        _setWorldMatrix(Matrix4::IDENTITY);
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::_render(const RenderOperation& op)
+    {
+        // Update stats
+        size_t val;
+
+        if (op.useIndexes)
+            val = op.indexData->indexCount;
+        else
+            val = op.vertexData->vertexCount;
+
+        // account for a pass having multiple iterations
+        if (mCurrentPassIterationCount > 1)
+            val *= mCurrentPassIterationCount;
+		mCurrentPassIterationNum = 0;
+
+        switch(op.operationType)
+        {
+		case RenderOperation::OT_TRIANGLE_LIST:
+            mFaceCount += val / 3;
+            break;
+        case RenderOperation::OT_TRIANGLE_STRIP:
+        case RenderOperation::OT_TRIANGLE_FAN:
+            mFaceCount += val - 2;
+            break;
+	    case RenderOperation::OT_POINT_LIST:
+	    case RenderOperation::OT_LINE_LIST:
+	    case RenderOperation::OT_LINE_STRIP:
+	        break;
+	    }
+
+        mVertexCount += op.vertexData->vertexCount;
+        mBatchCount += mCurrentPassIterationCount;
+
+		// sort out clip planes
+		// have to do it here in case of matrix issues
+		if (mClipPlanesDirty)
+		{
+			setClipPlanesImpl(mClipPlanes);
+			mClipPlanesDirty = false;
+		}
+    }
+    //-----------------------------------------------------------------------
+    void RenderSystem::setInvertVertexWinding(bool invert)
+    {
+        mInvertVertexWinding = invert;
+    }
+	//-----------------------------------------------------------------------
+	bool RenderSystem::getInvertVertexWinding(void) const
+	{
+		return mInvertVertexWinding;
+	}
+	//---------------------------------------------------------------------
+	void RenderSystem::addClipPlane (const Plane &p)
+	{
+		mClipPlanes.push_back(p);
+		mClipPlanesDirty = true;
+	}
+	//---------------------------------------------------------------------
+	void RenderSystem::addClipPlane (Real A, Real B, Real C, Real D)
+	{
+		addClipPlane(Plane(A, B, C, D));
+	}
+	//---------------------------------------------------------------------
+	void RenderSystem::setClipPlanes(const PlaneList& clipPlanes)
+	{
+		if (clipPlanes != mClipPlanes)
+		{
+			mClipPlanes = clipPlanes;
+			mClipPlanesDirty = true;
+		}
+	}
+	//---------------------------------------------------------------------
+	void RenderSystem::resetClipPlanes()
+	{
+		if (!mClipPlanes.empty())
+		{
+			mClipPlanes.clear();
+			mClipPlanesDirty = true;
+		}
+	}
+    //-----------------------------------------------------------------------
+    void RenderSystem::_notifyCameraRemoved(const Camera* cam)
+    {
+		// TODO PORT - Not used in the port. Should probably be removed
+    }
+
+	//---------------------------------------------------------------------
+    bool RenderSystem::updatePassIterationRenderState(void)
+    {
+        if (mCurrentPassIterationCount <= 1)
+            return false;
+
+        --mCurrentPassIterationCount;
+		++mCurrentPassIterationNum;
+        if (!mActiveVertexGpuProgramParameters.isNull())
+        {
+            mActiveVertexGpuProgramParameters->incPassIterationNumber();
+            bindGpuProgramPassIterationParameters(GPT_VERTEX_PROGRAM);
+        }
+        if (!mActiveGeometryGpuProgramParameters.isNull())
+        {
+            mActiveGeometryGpuProgramParameters->incPassIterationNumber();
+            bindGpuProgramPassIterationParameters(GPT_GEOMETRY_PROGRAM);
+        }
+        if (!mActiveFragmentGpuProgramParameters.isNull())
+        {
+            mActiveFragmentGpuProgramParameters->incPassIterationNumber();
+            bindGpuProgramPassIterationParameters(GPT_FRAGMENT_PROGRAM);
+        }
+        return true;
+    }
+
+	//-----------------------------------------------------------------------
+	void RenderSystem::addListener(Listener* l)
+	{
+		mEventListeners.push_back(l);
+	}
+	//-----------------------------------------------------------------------
+	void RenderSystem::removeListener(Listener* l)
+	{
+		mEventListeners.remove(l);
+	}
+	//-----------------------------------------------------------------------
+	void RenderSystem::fireEvent(const String& name, const NameValuePairList* params)
+	{
+		for(ListenerList::iterator i = mEventListeners.begin(); 
+			i != mEventListeners.end(); ++i)
+		{
+			(*i)->eventOccurred(name, params);
+		}
+	}
+	//-----------------------------------------------------------------------
+	void RenderSystem::destroyHardwareOcclusionQuery( HardwareOcclusionQuery *hq)
+	{
+		HardwareOcclusionQueryList::iterator i =
+			std::find(mHwOcclusionQueries.begin(), mHwOcclusionQueries.end(), hq);
+		if (i != mHwOcclusionQueries.end())
+		{
+			mHwOcclusionQueries.erase(i);
+			OGRE_DELETE hq;
+		}
+	}
+	//-----------------------------------------------------------------------
+	void RenderSystem::bindGpuProgram(GpuProgram* prg)
+	{
+	    switch(prg->getType())
+	    {
+        case GPT_VERTEX_PROGRAM:
+			// mark clip planes dirty if changed (programmable can change space)
+			if (!mVertexProgramBound && !mClipPlanes.empty())
+				mClipPlanesDirty = true;
+
+            mVertexProgramBound = true;
+	        break;
+        case GPT_GEOMETRY_PROGRAM:
+			mGeometryProgramBound = true;
+			break;
+        case GPT_FRAGMENT_PROGRAM:
+            mFragmentProgramBound = true;
+	        break;
+	    }
+	}
+	//-----------------------------------------------------------------------
+	void RenderSystem::unbindGpuProgram(GpuProgramType gptype)
+	{
+	    switch(gptype)
+	    {
+        case GPT_VERTEX_PROGRAM:
+			// mark clip planes dirty if changed (programmable can change space)
+			if (mVertexProgramBound && !mClipPlanes.empty())
+				mClipPlanesDirty = true;
+            mVertexProgramBound = false;
+	        break;
+        case GPT_GEOMETRY_PROGRAM:
+			mGeometryProgramBound = false;
+			break;
+        case GPT_FRAGMENT_PROGRAM:
+            mFragmentProgramBound = false;
+	        break;
+	    }
+	}
+	//-----------------------------------------------------------------------
+	bool RenderSystem::isGpuProgramBound(GpuProgramType gptype)
+	{
+	    switch(gptype)
+	    {
+        case GPT_VERTEX_PROGRAM:
+            return mVertexProgramBound;
+        case GPT_GEOMETRY_PROGRAM:
+            return mGeometryProgramBound;
+        case GPT_FRAGMENT_PROGRAM:
+            return mFragmentProgramBound;
+	    }
+        // Make compiler happy
+        return false;
+	}
+	//---------------------------------------------------------------------
+	void RenderSystem::_setTextureProjectionRelativeTo(bool enabled, const Vector3& pos)
+	{
+		mTexProjRelative = enabled;
+		mTexProjRelativeOrigin = pos;
+
+	}
+	//---------------------------------------------------------------------
+	RenderSystem::RenderSystemContext* RenderSystem::_pauseFrame(void)
+	{
+		_endFrame();
+		return new RenderSystem::RenderSystemContext;
+	}
+	//---------------------------------------------------------------------
+	void RenderSystem::_resumeFrame(RenderSystemContext* context)
+	{
+		_beginFrame();
+		delete context;
+	}
+
+}
+

+ 1409 - 0
CamelotRenderer/OgreRenderSystem.h

@@ -0,0 +1,1409 @@
+/*
+-----------------------------------------------------------------------------
+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 __RenderSystem_H_
+#define __RenderSystem_H_
+
+// Precompiler options
+#include "OgrePrerequisites.h"
+
+#include "OgreString.h"
+
+#include "OgreTextureUnitState.h"
+#include "OgreCommon.h"
+
+#include "OgreRenderOperation.h"
+#include "OgreRenderSystemCapabilities.h"
+#include "OgreRenderTarget.h"
+#include "OgreRenderTexture.h"
+#include "OgreGpuProgram.h"
+#include "OgrePlane.h"
+
+namespace Ogre
+{
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup RenderSystem
+	*  @{
+	*/
+
+	typedef map< String, RenderTarget * >::type RenderTargetMap;
+	typedef multimap<uchar, RenderTarget * >::type RenderTargetPriorityMap;
+
+	class TextureManager;
+	/// Enum describing the ways to generate texture coordinates
+	enum TexCoordCalcMethod
+	{
+		/// No calculated texture coordinates
+		TEXCALC_NONE,
+		/// Environment map based on vertex normals
+		TEXCALC_ENVIRONMENT_MAP,
+		/// Environment map based on vertex positions
+		TEXCALC_ENVIRONMENT_MAP_PLANAR,
+		TEXCALC_ENVIRONMENT_MAP_REFLECTION,
+		TEXCALC_ENVIRONMENT_MAP_NORMAL,
+		/// Projective texture
+		TEXCALC_PROJECTIVE_TEXTURE
+	};
+	/// Enum describing the various actions which can be taken onthe stencil buffer
+	enum StencilOperation
+	{
+		/// Leave the stencil buffer unchanged
+		SOP_KEEP,
+		/// Set the stencil value to zero
+		SOP_ZERO,
+		/// Set the stencil value to the reference value
+		SOP_REPLACE,
+		/// Increase the stencil value by 1, clamping at the maximum value
+		SOP_INCREMENT,
+		/// Decrease the stencil value by 1, clamping at 0
+		SOP_DECREMENT,
+		/// Increase the stencil value by 1, wrapping back to 0 when incrementing the maximum value
+		SOP_INCREMENT_WRAP,
+		/// Decrease the stencil value by 1, wrapping when decrementing 0
+		SOP_DECREMENT_WRAP,
+		/// Invert the bits of the stencil buffer
+		SOP_INVERT
+	};
+
+
+	/** Defines the functionality of a 3D API
+	@remarks
+	The RenderSystem class provides a base interface
+	which abstracts the general functionality of the 3D API
+	e.g. Direct3D or OpenGL. Whilst a few of the general
+	methods have implementations, most of this class is
+	abstract, requiring a subclass based on a specific API
+	to be constructed to provide the full functionality.
+	Note there are 2 levels to the interface - one which
+	will be used often by the caller of the Ogre library,
+	and one which is at a lower level and will be used by the
+	other classes provided by Ogre. These lower level
+	methods are prefixed with '_' to differentiate them.
+	The advanced user of the library may use these lower
+	level methods to access the 3D API at a more fundamental
+	level (dealing direct with render states and rendering
+	primitives), but still benefiting from Ogre's abstraction
+	of exactly which 3D API is in use.
+	@author
+	Steven Streeting
+	@version
+	1.0
+	*/
+	class _OgreExport RenderSystem
+	{
+	public:
+		/** Default Constructor.
+		*/
+		RenderSystem();
+
+		/** Destructor.
+		*/
+		virtual ~RenderSystem();
+
+		/** Returns the name of the rendering system.
+		*/
+		virtual const String& getName(void) const = 0;
+
+		/** Sets an option for this API
+		@remarks
+		Used to confirm the settings (normally chosen by the user) in
+		order to make the renderer able to initialise with the settings as required.
+		This may be video mode, D3D driver, full screen / windowed etc.
+		Called automatically by the default configuration
+		dialog, and by the restoration of saved settings.
+		These settings are stored and only activated when
+		RenderSystem::initialise or RenderSystem::reinitialise
+		are called.
+		@par
+		If using a custom configuration dialog, it is advised that the
+		caller calls RenderSystem::getConfigOptions
+		again, since some options can alter resulting from a selection.
+		@param
+		name The name of the option to alter.
+		@param
+		value The value to set the option to.
+		*/
+		virtual void setConfigOption(const String &name, const String &value) = 0;
+
+		/** Create an object for performing hardware occlusion queries. 
+		*/
+		virtual HardwareOcclusionQuery* createHardwareOcclusionQuery(void) = 0;
+
+		/** Destroy a hardware occlusion query object. 
+		*/
+		virtual void destroyHardwareOcclusionQuery(HardwareOcclusionQuery *hq);
+
+		/** Validates the options set for the rendering system, returning a message if there are problems.
+		@note
+		If the returned string is empty, there are no problems.
+		*/
+		virtual String validateConfigOptions(void) = 0;
+
+		/** Start up the renderer using the settings selected (Or the defaults if none have been selected).
+		@remarks
+		Called by Root::setRenderSystem. Shouldn't really be called
+		directly, although  this can be done if the app wants to.
+		@param
+		autoCreateWindow If true, creates a render window
+		automatically, based on settings chosen so far. This saves
+		an extra call to _createRenderWindow
+		for the main render window.
+		@par
+		If an application has more specific window requirements,
+		however (e.g. a level design app), it should specify false
+		for this parameter and do it manually.
+		@returns
+		A pointer to the automatically created window, if requested, otherwise null.
+		*/
+		virtual RenderWindow* _initialise(bool autoCreateWindow, const String& windowTitle = "OGRE Render Window");
+
+
+		/** Query the real capabilities of the GPU and driver in the RenderSystem*/
+		virtual RenderSystemCapabilities* createRenderSystemCapabilities() const = 0;
+
+		/** Force the render system to use the special capabilities. Can only be called
+		*    before the render system has been fully initializer (before createWindow is called) 
+		*	@param
+		*		 capabilities has to be a subset of the real capabilities and the caller is 
+		*		 responsible for deallocating capabilities.
+		*/
+		virtual void useCustomRenderSystemCapabilities(RenderSystemCapabilities* capabilities);
+
+		/** Restart the renderer (normally following a change in settings).
+		*/
+		virtual void reinitialise(void) = 0;
+
+		/** Shutdown the renderer and cleanup resources.
+		*/
+		virtual void shutdown(void);
+
+
+		/** Sets the colour & strength of the ambient (global directionless) light in the world.
+		*/
+		virtual void setAmbientLight(float r, float g, float b) = 0;
+
+		/** Sets the type of light shading required (default = Gouraud).
+		*/
+		virtual void setShadingType(ShadeOptions so) = 0;
+
+		/** Sets whether or not dynamic lighting is enabled.
+		@param
+		enabled If true, dynamic lighting is performed on geometry with normals supplied, geometry without
+		normals will not be displayed. If false, no lighting is applied and all geometry will be full brightness.
+		*/
+		virtual void setLightingEnabled(bool enabled) = 0;
+
+		/** Sets whether or not W-buffers are enabled if they are available for this renderer.
+		@param
+		enabled If true and the renderer supports them W-buffers will be used.  If false 
+		W-buffers will not be used even if available.  W-buffers are enabled by default 
+		for 16bit depth buffers and disabled for all other depths.
+		*/
+		void setWBufferEnabled(bool enabled);
+
+		/** Returns true if the renderer will try to use W-buffers when avalible.
+		*/
+		bool getWBufferEnabled(void) const;
+
+		/** Creates a new rendering window.
+		@remarks
+		This method creates a new rendering window as specified
+		by the paramteters. The rendering system could be
+		responible for only a single window (e.g. in the case
+		of a game), or could be in charge of multiple ones (in the
+		case of a level editor). The option to create the window
+		as a child of another is therefore given.
+		This method will create an appropriate subclass of
+		RenderWindow depending on the API and platform implementation.
+		@par
+		After creation, this window can be retrieved using getRenderTarget().
+		@param
+		name The name of the window. Used in other methods
+		later like setRenderTarget and getRenderTarget.
+		@param
+		width The width of the new window.
+		@param
+		height The height of the new window.
+		@param
+		fullScreen Specify true to make the window full screen
+		without borders, title bar or menu bar.
+		@param
+		miscParams A NameValuePairList describing the other parameters for the new rendering window. 
+		Options are case sensitive. Unrecognised parameters will be ignored silently.
+		These values might be platform dependent, but these are present for all platforms unless
+		indicated otherwise:
+		<table>
+		<tr>
+			<td><b>Key</b></td>
+			<td><b>Type/Values</b></td>
+			<td><b>Default</b></td>
+			<td><b>Description</b></td>
+			<td><b>Notes</b></td>
+		</tr>
+		<tr>
+			<td>title</td>
+			<td>Any string</td>
+			<td>RenderTarget name</td>
+			<td>The title of the window that will appear in the title bar</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>colourDepth</td>
+			<td>16, 32</td>
+			<td>Desktop depth</td>
+			<td>Colour depth of the resulting rendering window; only applies if fullScreen</td>
+			<td>Win32 Specific</td>
+		</tr>
+		<tr>
+			<td>left</td>
+			<td>Positive integers</td>
+			<td>Centred</td>
+			<td>Screen x coordinate from left</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>top</td>
+			<td>Positive integers</td>
+			<td>Centred</td>
+			<td>Screen y coordinate from left</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>depthBuffer</td>
+			<td>true, false</td>
+			<td>true</td>
+			<td>Use depth buffer</td>
+			<td>DirectX9 specific</td>
+		</tr>
+		<tr>
+			<td>externalWindowHandle</td>
+			<td>Win32: HWND as integer<br/>
+			    GLX: poslong:posint:poslong (display*:screen:windowHandle) or poslong:posint:poslong:poslong (display*:screen:windowHandle:XVisualInfo*)</td>
+			<td>0 (none)</td>
+			<td>External window handle, for embedding the OGRE render in an existing window</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>externalGLControl</td>
+			<td>true, false</td>
+			<td>false</td>
+			<td>Let the external window control OpenGL i.e. don't select a pixel format for the window,
+			do not change v-sync and do not swap buffer. When set to true, the calling application
+			is responsible of OpenGL initialization and buffer swapping. It should also create an
+			OpenGL context for its own rendering, Ogre will create one for its use. Then the calling
+			application must also enable Ogre OpenGL context before calling any Ogre function and
+			restore its OpenGL context after these calls.</td>
+			<td>OpenGL specific</td>
+		</tr>
+		<tr>
+			<td>externalGLContext</td>
+			<td>Context as Unsigned Long</td>
+			<td>0 (create own context)</td>
+			<td>Use an externally created GL context</td>
+			<td>OpenGL Specific</td>
+		</tr>
+		<tr>
+			<td>parentWindowHandle</td>
+			<td>Win32: HWND as integer<br/>
+			    GLX: poslong:posint:poslong (display*:screen:windowHandle) or poslong:posint:poslong:poslong (display*:screen:windowHandle:XVisualInfo*)</td>
+			<td>0 (none)</td>
+			<td>Parent window handle, for embedding the OGRE in a child of an external window</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>macAPI</td>
+			<td>String: "cocoa" or "carbon"</td>
+			<td>"carbon"</td>
+			<td>Specifies the type of rendering window on the Mac Platform.</td>
+			<td>&nbsp;</td>
+		 </tr>
+		 <tr>
+			<td>macAPICocoaUseNSView</td>
+			<td>bool "true" or "false"</td>
+			<td>"false"</td>
+			<td>On the Mac platform the most diffused method to embed OGRE in a custom application is to use Interface Builder
+				and add to the interface an instance of OgreView.
+				The pointer to this instance is then used as "externalWindowHandle".
+				However, there are cases where you are NOT using Interface Builder and you get the Cocoa NSView* of an existing interface.
+				For example, this is happens when you want to render into a Java/AWT interface.
+				In short, by setting this flag to "true" the Ogre::Root::createRenderWindow interprets the "externalWindowHandle" as a NSView*
+				instead of an OgreView*. See OgreOSXCocoaView.h/mm.
+			</td>
+			<td>&nbsp;</td>
+		 </tr>
+         <tr>
+             <td>contentScalingFactor</td>
+             <td>Positive Float greater than 1.0</td>
+             <td>The default content scaling factor of the screen</td>
+             <td>Specifies the CAEAGLLayer content scaling factor.  Only supported on iOS 4 or greater.
+                 This can be useful to limit the resolution of the OpenGL ES backing store.  For example, the iPhone 4's
+                 native resolution is 960 x 640.  Windows are always 320 x 480, if you would like to limit the display
+                 to 720 x 480, specify 1.5 as the scaling factor.
+             </td>
+             <td>&nbsp;</td>
+		 </tr>
+         <tr>
+			<td>FSAA</td>
+			<td>Positive integer (usually 0, 2, 4, 8, 16)</td>
+			<td>0</td>
+			<td>Full screen antialiasing factor</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>FSAAHint</td>
+			<td>Depends on RenderSystem and hardware. Currently supports:<br/>
+			"Quality": on systems that have an option to prefer higher AA quality over speed, use it</td>
+			<td>Blank</td>
+			<td>Full screen antialiasing hint</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>displayFrequency</td>
+			<td>Refresh rate in Hertz (e.g. 60, 75, 100)</td>
+			<td>Desktop vsync rate</td>
+			<td>Display frequency rate, for fullscreen mode</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>vsync</td>
+			<td>true, false</td>
+			<td>false</td>
+			<td>Synchronize buffer swaps to monitor vsync, eliminating tearing at the expense of a fixed frame rate</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>vsyncInterval</td>
+			<td>1, 2, 3, 4</td>
+			<td>1</td>
+			<td>If vsync is enabled, the minimum number of vertical blanks that should occur between renders. 
+			For example if vsync is enabled, the refresh rate is 60 and this is set to 2, then the
+			frame rate will be locked at 30.</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>border</td>
+			<td>none, fixed, resize</td>
+			<td>resize</td>
+			<td>The type of window border (in windowed mode)</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>outerDimensions</td>
+			<td>true, false</td>
+			<td>false</td>
+			<td>Whether the width/height is expressed as the size of the 
+			outer window, rather than the content area</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>useNVPerfHUD</td>
+			<td>true, false</td>
+			<td>false</td>
+			<td>Enable the use of nVidia NVPerfHUD</td>
+			<td>&nbsp;</td>
+		</tr>
+		<tr>
+			<td>gamma</td>
+			<td>true, false</td>
+			<td>false</td>
+			<td>Enable hardware conversion from linear colour space to gamma
+			colour space on rendering to the window.</td>
+			<td>&nbsp;</td>
+		</tr>
+		*/
+		virtual RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, 
+			bool fullScreen, const NameValuePairList *miscParams = 0) = 0;
+
+		/** Creates multiple rendering windows.		
+		@param
+		renderWindowDescriptions Array of structures containing the descriptions of each render window.
+		The structure's members are the same as the parameters of _createRenderWindow:
+		* name
+		* width
+		* height
+		* fullScreen
+		* miscParams
+		See _createRenderWindow for details about each member.		
+		@param
+		createdWindows This array will hold the created render windows.
+		@returns
+		true on success.		
+		*/
+		virtual bool _createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, 
+			RenderWindowList& createdWindows);
+
+		
+		/**	Create a MultiRenderTarget, which is a render target that renders to multiple RenderTextures
+		at once. Surfaces can be bound and unbound at will.
+		This fails if mCapabilities->getNumMultiRenderTargets() is smaller than 2.
+		*/
+		virtual MultiRenderTarget * createMultiRenderTarget(const String & name) = 0; 
+
+		/** Destroys a render window */
+		virtual void destroyRenderWindow(const String& name);
+		/** Destroys a render texture */
+		virtual void destroyRenderTexture(const String& name);
+		/** Destroys a render target of any sort */
+		virtual void destroyRenderTarget(const String& name);
+
+		/** Attaches the passed render target to the render system.
+		*/
+		virtual void attachRenderTarget( RenderTarget &target );
+		/** Returns a pointer to the render target with the passed name, or NULL if that
+		render target cannot be found.
+		*/
+		virtual RenderTarget * getRenderTarget( const String &name );
+		/** Detaches the render target with the passed name from the render system and
+		returns a pointer to it.
+		@note
+		If the render target cannot be found, NULL is returned.
+		*/
+		virtual RenderTarget * detachRenderTarget( const String &name );
+
+		/// Iterator over RenderTargets
+		typedef Ogre::RenderTargetMap::iterator RenderTargetIterator;
+
+		/** Returns a specialised MapIterator over all render targets attached to the RenderSystem. */
+		virtual RenderTargetIterator getRenderTargetIterator(void) {
+			return mRenderTargets.begin();
+		}
+		/** Returns a description of an error code.
+		*/
+		virtual String getErrorDescription(long errorNumber) const = 0;
+
+		/** Defines whether or now fullscreen render windows wait for the vertical blank before flipping buffers.
+		@remarks
+		By default, all rendering windows wait for a vertical blank (when the CRT beam turns off briefly to move
+		from the bottom right of the screen back to the top left) before flipping the screen buffers. This ensures
+		that the image you see on the screen is steady. However it restricts the frame rate to the refresh rate of
+		the monitor, and can slow the frame rate down. You can speed this up by not waiting for the blank, but
+		this has the downside of introducing 'tearing' artefacts where part of the previous frame is still displayed
+		as the buffers are switched. Speed vs quality, you choose.
+		@note
+		Has NO effect on windowed mode render targets. Only affects fullscreen mode.
+		@param
+		enabled If true, the system waits for vertical blanks - quality over speed. If false it doesn't - speed over quality.
+		*/
+		void setWaitForVerticalBlank(bool enabled);
+
+		/** Returns true if the system is synchronising frames with the monitor vertical blank.
+		*/
+		bool getWaitForVerticalBlank(void) const;
+
+		// ------------------------------------------------------------------------
+		//                     Internal Rendering Access
+		// All methods below here are normally only called by other OGRE classes
+		// They can be called by library user if required
+		// ------------------------------------------------------------------------
+
+
+		/** Tells the rendersystem to use the attached set of lights (and no others) 
+		up to the number specified (this allows the same list to be used with different
+		count limits) */
+		virtual void _useLights(const LightList& lights, unsigned short limit) = 0;
+		/** Are fixed-function lights provided in view space? Affects optimisation. 
+		*/
+		virtual bool areFixedFunctionLightsInViewSpace() const { return false; }
+		/** Sets the world transform matrix. */
+		virtual void _setWorldMatrix(const Matrix4 &m) = 0;
+		/** Sets multiple world matrices (vertex blending). */
+		virtual void _setWorldMatrices(const Matrix4* m, unsigned short count);
+		/** Sets the view transform matrix */
+		virtual void _setViewMatrix(const Matrix4 &m) = 0;
+		/** Sets the projection transform matrix */
+		virtual void _setProjectionMatrix(const Matrix4 &m) = 0;
+		/** Utility function for setting all the properties of a texture unit at once.
+		This method is also worth using over the individual texture unit settings because it
+		only sets those settings which are different from the current settings for this
+		unit, thus minimising render state changes.
+		*/
+		virtual void _setTextureUnitSettings(size_t texUnit, TextureUnitState& tl);
+		/** Turns off a texture unit. */
+		virtual void _disableTextureUnit(size_t texUnit);
+		/** Disables all texture units from the given unit upwards */
+		virtual void _disableTextureUnitsFrom(size_t texUnit);
+		/** Sets the surface properties to be used for future rendering.
+
+		This method sets the the properties of the surfaces of objects
+		to be rendered after it. In this context these surface properties
+		are the amount of each type of light the object reflects (determining
+		it's colour under different types of light), whether it emits light
+		itself, and how shiny it is. Textures are not dealt with here,
+		see the _setTetxure method for details.
+		This method is used by _setMaterial so does not need to be called
+		direct if that method is being used.
+
+		@param ambient The amount of ambient (sourceless and directionless)
+		light an object reflects. Affected by the colour/amount of ambient light in the scene.
+		@param diffuse The amount of light from directed sources that is
+		reflected (affected by colour/amount of point, directed and spot light sources)
+		@param specular The amount of specular light reflected. This is also
+		affected by directed light sources but represents the colour at the
+		highlights of the object.
+		@param emissive The colour of light emitted from the object. Note that
+		this will make an object seem brighter and not dependent on lights in
+		the scene, but it will not act as a light, so will not illuminate other
+		objects. Use a light attached to the same SceneNode as the object for this purpose.
+		@param shininess A value which only has an effect on specular highlights (so
+		specular must be non-black). The higher this value, the smaller and crisper the
+		specular highlights will be, imitating a more highly polished surface.
+		This value is not constrained to 0.0-1.0, in fact it is likely to
+		be more (10.0 gives a modest sheen to an object).
+		@param tracking A bit field that describes which of the ambient, diffuse, specular
+		and emissive colours follow the vertex colour of the primitive. When a bit in this field is set
+		its ColourValue is ignored. This is a combination of TVC_AMBIENT, TVC_DIFFUSE, TVC_SPECULAR(note that the shininess value is still
+		taken from shininess) and TVC_EMISSIVE. TVC_NONE means that there will be no material property
+		tracking the vertex colours.
+		*/
+		virtual void _setSurfaceParams(const ColourValue &ambient,
+			const ColourValue &diffuse, const ColourValue &specular,
+			const ColourValue &emissive, Real shininess,
+			TrackVertexColourType tracking = TVC_NONE) = 0;
+
+		/** Sets whether or not rendering points using OT_POINT_LIST will 
+		render point sprites (textured quads) or plain points.
+		@param enabled True enables point sprites, false returns to normal
+		point rendering.
+		*/	
+		virtual void _setPointSpritesEnabled(bool enabled) = 0;
+
+		/** Sets the size of points and how they are attenuated with distance.
+		@remarks
+		When performing point rendering or point sprite rendering,
+		point size can be attenuated with distance. The equation for
+		doing this is attenuation = 1 / (constant + linear * dist + quadratic * d^2) .
+		@par
+		For example, to disable distance attenuation (constant screensize) 
+		you would set constant to 1, and linear and quadratic to 0. A
+		standard perspective attenuation would be 0, 1, 0 respectively.
+		*/
+		virtual void _setPointParameters(Real size, bool attenuationEnabled, 
+			Real constant, Real linear, Real quadratic, Real minSize, Real maxSize) = 0;
+
+
+		/**
+		Sets the texture to bind to a given texture unit.
+
+		User processes would not normally call this direct unless rendering
+		primitives themselves.
+
+		@param unit The index of the texture unit to modify. Multitexturing 
+		hardware can support multiple units (see 
+		RenderSystemCapabilites::getNumTextureUnits)
+		@param enabled Boolean to turn the unit on/off
+		@param texPtr Pointer to the texture to use.
+		*/
+		virtual void _setTexture(size_t unit, bool enabled, 
+			const TexturePtr &texPtr) = 0;
+
+		/** Binds a texture to a vertex sampler.
+		@remarks
+		Not all rendersystems support separate vertex samplers. For those that
+		do, you can set a texture for them, separate to the regular texture
+		samplers, using this method. For those that don't, you should use the
+		regular texture samplers which are shared between the vertex and
+		fragment units; calling this method will throw an exception.
+		@see RenderSystemCapabilites::getVertexTextureUnitsShared
+		*/
+		virtual void _setVertexTexture(size_t unit, const TexturePtr& tex);
+
+		/**
+		Sets the texture coordinate set to use for a texture unit.
+
+		Meant for use internally - not generally used directly by apps - the Material and TextureUnitState
+		classes let you manage textures far more easily.
+
+		@param unit Texture unit as above
+		@param index The index of the texture coordinate set to use.
+		*/
+		virtual void _setTextureCoordSet(size_t unit, size_t index) = 0;
+
+		/**
+		Sets a method for automatically calculating texture coordinates for a stage.
+		Should not be used by apps - for use by Ogre only.
+		@param unit Texture unit as above
+		@param m Calculation method to use
+		@param frustum Optional Frustum param, only used for projective effects
+		*/
+		virtual void _setTextureCoordCalculation(size_t unit, TexCoordCalcMethod m, 
+			const Frustum* frustum = 0) = 0;
+
+		/** Sets the texture blend modes from a TextureUnitState record.
+		Meant for use internally only - apps should use the Material
+		and TextureUnitState classes.
+		@param unit Texture unit as above
+		@param bm Details of the blending mode
+		*/
+		virtual void _setTextureBlendMode(size_t unit, const LayerBlendModeEx& bm) = 0;
+
+		/** Sets the filtering options for a given texture unit.
+		@param unit The texture unit to set the filtering options for
+		@param minFilter The filter used when a texture is reduced in size
+		@param magFilter The filter used when a texture is magnified
+		@param mipFilter The filter used between mipmap levels, FO_NONE disables mipmapping
+		*/
+		virtual void _setTextureUnitFiltering(size_t unit, FilterOptions minFilter,
+			FilterOptions magFilter, FilterOptions mipFilter);
+
+		/** Sets a single filter for a given texture unit.
+		@param unit The texture unit to set the filtering options for
+		@param ftype The filter type
+		@param filter The filter to be used
+		*/
+		virtual void _setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter) = 0;
+
+		/** Sets the maximal anisotropy for the specified texture unit.*/
+		virtual void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) = 0;
+
+		/** Sets the texture addressing mode for a texture unit.*/
+		virtual void _setTextureAddressingMode(size_t unit, const TextureUnitState::UVWAddressingMode& uvw) = 0;
+
+		/** Sets the texture border colour for a texture unit.*/
+		virtual void _setTextureBorderColour(size_t unit, const ColourValue& colour) = 0;
+
+		/** Sets the mipmap bias value for a given texture unit.
+		@remarks
+		This allows you to adjust the mipmap calculation up or down for a
+		given texture unit. Negative values force a larger mipmap to be used, 
+		positive values force a smaller mipmap to be used. Units are in numbers
+		of levels, so +1 forces the mipmaps to one smaller level.
+		@note Only does something if render system has capability RSC_MIPMAP_LOD_BIAS.
+		*/
+		virtual void _setTextureMipmapBias(size_t unit, float bias) = 0;
+
+		/** Sets the texture coordinate transformation matrix for a texture unit.
+		@param unit Texture unit to affect
+		@param xform The 4x4 matrix
+		*/
+		virtual void _setTextureMatrix(size_t unit, const Matrix4& xform) = 0;
+
+		/** Sets the global blending factors for combining subsequent renders with the existing frame contents.
+		The result of the blending operation is:</p>
+		<p align="center">final = (texture * sourceFactor) + (pixel * destFactor)</p>
+		Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor
+		enumerated type.
+		By changing the operation you can change addition between the source and destination pixels to a different operator.
+		@param sourceFactor The source factor in the above calculation, i.e. multiplied by the texture colour components.
+		@param destFactor The destination factor in the above calculation, i.e. multiplied by the pixel colour components.
+		@param op The blend operation mode for combining pixels
+		*/
+		virtual void _setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op = SBO_ADD) = 0;
+
+		/** Sets the global blending factors for combining subsequent renders with the existing frame contents.
+		The result of the blending operation is:</p>
+		<p align="center">final = (texture * sourceFactor) + (pixel * destFactor)</p>
+		Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor
+		enumerated type.
+		@param sourceFactor The source factor in the above calculation, i.e. multiplied by the texture colour components.
+		@param destFactor The destination factor in the above calculation, i.e. multiplied by the pixel colour components.
+		@param sourceFactorAlpha The source factor in the above calculation for the alpha channel, i.e. multiplied by the texture alpha components.
+		@param destFactorAlpha The destination factor in the above calculation for the alpha channel, i.e. multiplied by the pixel alpha components.
+		@param op The blend operation mode for combining pixels
+		@param alphaOp The blend operation mode for combining pixel alpha values
+		*/
+		virtual void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, 
+			SceneBlendFactor destFactorAlpha, SceneBlendOperation op = SBO_ADD, SceneBlendOperation alphaOp = SBO_ADD) = 0;
+
+		/** Sets the global alpha rejection approach for future renders.
+		By default images are rendered regardless of texture alpha. This method lets you change that.
+		@param func The comparison function which must pass for a pixel to be written.
+		@param val The value to compare each pixels alpha value to (0-255)
+		@param alphaToCoverage Whether to enable alpha to coverage, if supported
+		*/
+		virtual void _setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) = 0;
+
+		/** Notify the rendersystem that it should adjust texture projection to be 
+			relative to a different origin.
+		*/
+		virtual void _setTextureProjectionRelativeTo(bool enabled, const Vector3& pos);
+		/**
+		* Signifies the beginning of a frame, i.e. the start of rendering on a single viewport. Will occur
+		* several times per complete frame if multiple viewports exist.
+		*/
+		virtual void _beginFrame(void) = 0;
+		
+		//Dummy structure for render system contexts - implementing RenderSystems can extend
+		//as needed
+		struct RenderSystemContext { };
+		/**
+		* Pause rendering for a frame. This has to be called after _beginFrame and before _endFrame.
+		* Will usually be called by the SceneManager, don't use this manually unless you know what
+		* you are doing.
+		*/
+		virtual RenderSystemContext* _pauseFrame(void);
+		/**
+		* Resume rendering for a frame. This has to be called after a _pauseFrame call
+		* Will usually be called by the SceneManager, don't use this manually unless you know what
+		* you are doing.
+		* @param context the render system context, as returned by _pauseFrame
+		*/
+		virtual void _resumeFrame(RenderSystemContext* context);
+
+		/**
+		* Ends rendering of a frame to the current viewport.
+		*/
+		virtual void _endFrame(void) = 0;
+		/**
+		Sets the provided viewport as the active one for future
+		rendering operations. This viewport is aware of it's own
+		camera and render target. Must be implemented by subclass.
+
+		@param target Pointer to the appropriate viewport.
+		*/
+		virtual void _setViewport(Viewport *vp) = 0;
+		/** Get the current active viewport for rendering. */
+		virtual Viewport* _getViewport(void);
+
+		/** Sets the culling mode for the render system based on the 'vertex winding'.
+		A typical way for the rendering engine to cull triangles is based on the
+		'vertex winding' of triangles. Vertex winding refers to the direction in
+		which the vertices are passed or indexed to in the rendering operation as viewed
+		from the camera, and will wither be clockwise or anticlockwise (that's 'counterclockwise' for
+		you Americans out there ;) The default is CULL_CLOCKWISE i.e. that only triangles whose vertices
+		are passed/indexed in anticlockwise order are rendered - this is a common approach and is used in 3D studio models
+		for example. You can alter this culling mode if you wish but it is not advised unless you know what you are doing.
+		You may wish to use the CULL_NONE option for mesh data that you cull yourself where the vertex
+		winding is uncertain.
+		*/
+		virtual void _setCullingMode(CullingMode mode) = 0;
+
+		virtual CullingMode _getCullingMode(void) const;
+
+		/** Sets the mode of operation for depth buffer tests from this point onwards.
+		Sometimes you may wish to alter the behaviour of the depth buffer to achieve
+		special effects. Because it's unlikely that you'll set these options for an entire frame,
+		but rather use them to tweak settings between rendering objects, this is an internal
+		method (indicated by the '_' prefix) which will be used by a SceneManager implementation
+		rather than directly from the client application.
+		If this method is never called the settings are automatically the same as the default parameters.
+		@param depthTest If true, the depth buffer is tested for each pixel and the frame buffer is only updated
+		if the depth function test succeeds. If false, no test is performed and pixels are always written.
+		@param depthWrite If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
+		If false, the depth buffer is left unchanged even if a new pixel is written.
+		@param depthFunction Sets the function required for the depth test.
+		*/
+		virtual void _setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL) = 0;
+
+		/** Sets whether or not the depth buffer check is performed before a pixel write.
+		@param enabled If true, the depth buffer is tested for each pixel and the frame buffer is only updated
+		if the depth function test succeeds. If false, no test is performed and pixels are always written.
+		*/
+		virtual void _setDepthBufferCheckEnabled(bool enabled = true) = 0;
+		/** Sets whether or not the depth buffer is updated after a pixel write.
+		@param enabled If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds.
+		If false, the depth buffer is left unchanged even if a new pixel is written.
+		*/
+		virtual void _setDepthBufferWriteEnabled(bool enabled = true) = 0;
+		/** Sets the comparison function for the depth buffer check.
+		Advanced use only - allows you to choose the function applied to compare the depth values of
+		new and existing pixels in the depth buffer. Only an issue if the deoth buffer check is enabled
+		(see _setDepthBufferCheckEnabled)
+		@param  func The comparison between the new depth and the existing depth which must return true
+		for the new pixel to be written.
+		*/
+		virtual void _setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL) = 0;
+		/** Sets whether or not colour buffer writing is enabled, and for which channels. 
+		@remarks
+		For some advanced effects, you may wish to turn off the writing of certain colour
+		channels, or even all of the colour channels so that only the depth buffer is updated
+		in a rendering pass. However, the chances are that you really want to use this option
+		through the Material class.
+		@param red, green, blue, alpha Whether writing is enabled for each of the 4 colour channels. */
+		virtual void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha) = 0;
+		/** Sets the depth bias, NB you should use the Material version of this. 
+		@remarks
+		When polygons are coplanar, you can get problems with 'depth fighting' where
+		the pixels from the two polys compete for the same screen pixel. This is particularly
+		a problem for decals (polys attached to another surface to represent details such as
+		bulletholes etc.).
+		@par
+		A way to combat this problem is to use a depth bias to adjust the depth buffer value
+		used for the decal such that it is slightly higher than the true value, ensuring that
+		the decal appears on top.
+		@note
+		The final bias value is a combination of a constant bias and a bias proportional
+		to the maximum depth slope of the polygon being rendered. The final bias
+		is constantBias + slopeScaleBias * maxslope. Slope scale biasing is
+		generally preferable but is not available on older hardware.
+		@param constantBias The constant bias value, expressed as a value in 
+		homogeneous depth coordinates.
+		@param slopeScaleBias The bias value which is factored by the maximum slope
+		of the polygon, see the description above. This is not supported by all
+		cards.
+
+		*/
+		virtual void _setDepthBias(float constantBias, float slopeScaleBias = 0.0f) = 0;
+		/** Sets the fogging mode for future geometry.
+		@param mode Set up the mode of fog as described in the FogMode enum, or set to FOG_NONE to turn off.
+		@param colour The colour of the fog. Either set this to the same as your viewport background colour,
+		or to blend in with a skydome or skybox.
+		@param expDensity The density of the fog in FOG_EXP or FOG_EXP2 mode, as a value between 0 and 1. The default is 1. i.e. completely opaque, lower values can mean
+		that fog never completely obscures the scene.
+		@param linearStart Distance at which linear fog starts to encroach. The distance must be passed
+		as a parametric value between 0 and 1, with 0 being the near clipping plane, and 1 being the far clipping plane. Only applicable if mode is FOG_LINEAR.
+		@param linearEnd Distance at which linear fog becomes completely opaque.The distance must be passed
+		as a parametric value between 0 and 1, with 0 being the near clipping plane, and 1 being the far clipping plane. Only applicable if mode is FOG_LINEAR.
+		*/
+		virtual void _setFog(FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 1.0, Real linearStart = 0.0, Real linearEnd = 1.0) = 0;
+
+
+		/** The RenderSystem will keep a count of tris rendered, this resets the count. */
+		virtual void _beginGeometryCount(void);
+		/** Reports the number of tris rendered since the last _beginGeometryCount call. */
+		virtual unsigned int _getFaceCount(void) const;
+		/** Reports the number of batches rendered since the last _beginGeometryCount call. */
+		virtual unsigned int _getBatchCount(void) const;
+		/** Reports the number of vertices passed to the renderer since the last _beginGeometryCount call. */
+		virtual unsigned int _getVertexCount(void) const;
+
+		/** Generates a packed data version of the passed in ColourValue suitable for
+		use as with this RenderSystem.
+		@remarks
+		Since different render systems have different colour data formats (eg
+		RGBA for GL, ARGB for D3D) this method allows you to use 1 method for all.
+		@param colour The colour to convert
+		@param pDest Pointer to location to put the result.
+		*/
+		virtual void convertColourValue(const ColourValue& colour, uint32* pDest);
+		/** Get the native VertexElementType for a compact 32-bit colour value
+		for this rendersystem.
+		*/
+		virtual VertexElementType getColourVertexElementType(void) const = 0;
+
+		/** Converts a uniform projection matrix to suitable for this render system.
+		@remarks
+		Because different APIs have different requirements (some incompatible) for the
+		projection matrix, this method allows each to implement their own correctly and pass
+		back a generic OGRE matrix for storage in the engine.
+		*/
+		virtual void _convertProjectionMatrix(const Matrix4& matrix,
+			Matrix4& dest, bool forGpuProgram = false) = 0;
+
+		/** Builds a perspective projection matrix suitable for this render system.
+		@remarks
+		Because different APIs have different requirements (some incompatible) for the
+		projection matrix, this method allows each to implement their own correctly and pass
+		back a generic OGRE matrix for storage in the engine.
+		*/
+		virtual void _makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, 
+			Matrix4& dest, bool forGpuProgram = false) = 0;
+
+		/** Builds a perspective projection matrix for the case when frustum is
+		not centered around camera.
+		@remarks
+		Viewport coordinates are in camera coordinate frame, i.e. camera is 
+		at the origin.
+		*/
+		virtual void _makeProjectionMatrix(Real left, Real right, Real bottom, Real top, 
+			Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false) = 0;
+		/** Builds an orthographic projection matrix suitable for this render system.
+		@remarks
+		Because different APIs have different requirements (some incompatible) for the
+		projection matrix, this method allows each to implement their own correctly and pass
+		back a generic OGRE matrix for storage in the engine.
+		*/
+		virtual void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, 
+			Matrix4& dest, bool forGpuProgram = false) = 0;
+
+		/** Update a perspective projection matrix to use 'oblique depth projection'.
+		@remarks
+		This method can be used to change the nature of a perspective 
+		transform in order to make the near plane not perpendicular to the 
+		camera view direction, but to be at some different orientation. 
+		This can be useful for performing arbitrary clipping (e.g. to a 
+		reflection plane) which could otherwise only be done using user
+		clip planes, which are more expensive, and not necessarily supported
+		on all cards.
+		@param matrix The existing projection matrix. Note that this must be a
+		perspective transform (not orthographic), and must not have already
+		been altered by this method. The matrix will be altered in-place.
+		@param plane The plane which is to be used as the clipping plane. This
+		plane must be in CAMERA (view) space.
+		@param forGpuProgram Is this for use with a Gpu program or fixed-function
+		*/
+		virtual void _applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, 
+			bool forGpuProgram) = 0;
+
+		/** Sets how to rasterise triangles, as points, wireframe or solid polys. */
+		virtual void _setPolygonMode(PolygonMode level) = 0;
+
+		/** Turns stencil buffer checking on or off. 
+		@remarks
+		Stencilling (masking off areas of the rendering target based on the stencil 
+		buffer) can be turned on or off using this method. By default, stencilling is
+		disabled.
+		*/
+		virtual void setStencilCheckEnabled(bool enabled) = 0;
+		/** Determines if this system supports hardware accelerated stencil buffer. 
+		@remarks
+		Note that the lack of this function doesn't mean you can't do stencilling, but
+		the stencilling operations will be provided in software, which will NOT be
+		fast.
+		@par
+		Generally hardware stencils are only supported in 32-bit colour modes, because
+		the stencil buffer shares the memory of the z-buffer, and in most cards the 
+		z-buffer has to be the same depth as the colour buffer. This means that in 32-bit
+		mode, 24 bits of the z-buffer are depth and 8 bits are stencil. In 16-bit mode there
+		is no room for a stencil (although some cards support a 15:1 depth:stencil option,
+		this isn't useful for very much) so 8 bits of stencil are provided in software.
+		This can mean that if you use stencilling, your applications may be faster in 
+		32-but colour than in 16-bit, which may seem odd to some people.
+		*/
+		/*virtual bool hasHardwareStencil(void) = 0;*/
+
+		/** This method allows you to set all the stencil buffer parameters in one call.
+		@remarks
+		The stencil buffer is used to mask out pixels in the render target, allowing
+		you to do effects like mirrors, cut-outs, stencil shadows and more. Each of
+		your batches of rendering is likely to ignore the stencil buffer, 
+		update it with new values, or apply it to mask the output of the render.
+		The stencil test is:<PRE>
+		(Reference Value & Mask) CompareFunction (Stencil Buffer Value & Mask)</PRE>
+		The result of this will cause one of 3 actions depending on whether the test fails,
+		succeeds but with the depth buffer check still failing, or succeeds with the
+		depth buffer check passing too.
+		@par
+		Unlike other render states, stencilling is left for the application to turn
+		on and off when it requires. This is because you are likely to want to change
+		parameters between batches of arbitrary objects and control the ordering yourself.
+		In order to batch things this way, you'll want to use OGRE's separate render queue
+		groups (see RenderQueue) and register a RenderQueueListener to get notifications
+		between batches.
+		@par
+		There are individual state change methods for each of the parameters set using 
+		this method. 
+		Note that the default values in this method represent the defaults at system 
+		start up too.
+		@param func The comparison function applied.
+		@param refValue The reference value used in the comparison
+		@param mask The bitmask applied to both the stencil value and the reference value 
+		before comparison
+		@param stencilFailOp The action to perform when the stencil check fails
+		@param depthFailOp The action to perform when the stencil check passes, but the
+		depth buffer check still fails
+		@param passOp The action to take when both the stencil and depth check pass.
+		@param twoSidedOperation If set to true, then if you render both back and front faces 
+		(you'll have to turn off culling) then these parameters will apply for front faces, 
+		and the inverse of them will happen for back faces (keep remains the same).
+		*/
+		virtual void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, 
+			uint32 refValue = 0, uint32 mask = 0xFFFFFFFF, 
+			StencilOperation stencilFailOp = SOP_KEEP, 
+			StencilOperation depthFailOp = SOP_KEEP,
+			StencilOperation passOp = SOP_KEEP, 
+			bool twoSidedOperation = false) = 0;
+
+
+
+		/** Sets the current vertex declaration, ie the source of vertex data. */
+		virtual void setVertexDeclaration(VertexDeclaration* decl) = 0;
+		/** Sets the current vertex buffer binding state. */
+		virtual void setVertexBufferBinding(VertexBufferBinding* binding) = 0;
+
+		/** Sets whether or not normals are to be automatically normalised.
+		@remarks
+		This is useful when, for example, you are scaling SceneNodes such that
+		normals may not be unit-length anymore. Note though that this has an
+		overhead so should not be turn on unless you really need it.
+		@par
+		You should not normally call this direct unless you are rendering
+		world geometry; set it on the Renderable because otherwise it will be
+		overridden by material settings. 
+		*/
+		virtual void setNormaliseNormals(bool normalise) = 0;
+
+		/**
+		Render something to the active viewport.
+
+		Low-level rendering interface to perform rendering
+		operations. Unlikely to be used directly by client
+		applications, since the SceneManager and various support
+		classes will be responsible for calling this method.
+		Can only be called between _beginScene and _endScene
+
+		@param op A rendering operation instance, which contains
+		details of the operation to be performed.
+		*/
+		virtual void _render(const RenderOperation& op);
+
+		/** Gets the capabilities of the render system. */
+		const RenderSystemCapabilities* getCapabilities(void) const { return mCurrentCapabilities; }
+
+
+		/** Returns the driver version.
+		*/
+		virtual const DriverVersion& getDriverVersion(void) const { return mDriverVersion; }
+
+		/** Binds a given GpuProgram (but not the parameters). 
+		@remarks Only one GpuProgram of each type can be bound at once, binding another
+		one will simply replace the existing one.
+		*/
+		virtual void bindGpuProgram(GpuProgram* prg);
+
+		/** Bind Gpu program parameters.
+		@param gptype The type of program to bind the parameters to
+		@param params The parameters to bind
+		@param variabilityMask A mask of GpuParamVariability identifying which params need binding
+		*/
+		virtual void bindGpuProgramParameters(GpuProgramType gptype, 
+			GpuProgramParametersSharedPtr params, uint16 variabilityMask) = 0;
+
+		/** Only binds Gpu program parameters used for passes that have more than one iteration rendering
+		*/
+		virtual void bindGpuProgramPassIterationParameters(GpuProgramType gptype) = 0;
+		/** Unbinds GpuPrograms of a given GpuProgramType.
+		@remarks
+		This returns the pipeline to fixed-function processing for this type.
+		*/
+		virtual void unbindGpuProgram(GpuProgramType gptype);
+
+		/** Returns whether or not a Gpu program of the given type is currently bound. */
+		virtual bool isGpuProgramBound(GpuProgramType gptype);
+
+		/** Sets the user clipping region.
+		*/
+		virtual void setClipPlanes(const PlaneList& clipPlanes);
+
+		/** Add a user clipping plane. */
+		virtual void addClipPlane (const Plane &p);
+		/** Add a user clipping plane. */
+		virtual void addClipPlane (Real A, Real B, Real C, Real D);
+
+		/** Clears the user clipping region.
+		*/
+		virtual void resetClipPlanes();
+
+		/** Utility method for initialising all render targets attached to this rendering system. */
+		virtual void _initRenderTargets(void);
+
+		/** Utility method to notify all render targets that a camera has been removed, 
+		in case they were referring to it as their viewer. 
+		*/
+		virtual void _notifyCameraRemoved(const Camera* cam);
+
+		/** Internal method for updating all render targets attached to this rendering system. */
+		virtual void _updateAllRenderTargets(bool swapBuffers = true);
+		/** Internal method for swapping all the buffers on all render targets,
+		if _updateAllRenderTargets was called with a 'false' parameter. */
+		virtual void _swapAllRenderTargetBuffers(bool waitForVsync = true);
+
+		/** Sets whether or not vertex windings set should be inverted; this can be important
+		for rendering reflections. */
+		virtual void setInvertVertexWinding(bool invert);
+
+		/** Indicates whether or not the vertex windings set will be inverted for the current render (e.g. reflections)
+		@see RenderSystem::setInvertVertexWinding
+		*/
+		virtual bool getInvertVertexWinding(void) const;
+
+		/** Sets the 'scissor region' ie the region of the target in which rendering can take place.
+		@remarks
+		This method allows you to 'mask off' rendering in all but a given rectangular area
+		as identified by the parameters to this method.
+		@note
+		Not all systems support this method. Check the RenderSystemCapabilities for the
+		RSC_SCISSOR_TEST capability to see if it is supported.
+		@param enabled True to enable the scissor test, false to disable it.
+		@param left, top, right, bottom The location of the corners of the rectangle, expressed in
+		<i>pixels</i>.
+		*/
+		virtual void setScissorTest(bool enabled, size_t left = 0, size_t top = 0, 
+			size_t right = 800, size_t bottom = 600) = 0;
+
+		/** Clears one or more frame buffers on the active render target. 
+		@param buffers Combination of one or more elements of FrameBufferType
+		denoting which buffers are to be cleared
+		@param colour The colour to clear the colour buffer with, if enabled
+		@param depth The value to initialise the depth buffer with, if enabled
+		@param stencil The value to initialise the stencil buffer with, if enabled.
+		*/
+		virtual void clearFrameBuffer(unsigned int buffers, 
+			const ColourValue& colour = ColourValue::Black, 
+			Real depth = 1.0f, unsigned short stencil = 0) = 0;
+		/** Returns the horizontal texel offset value required for mapping 
+		texel origins to pixel origins in this rendersystem.
+		@remarks
+		Since rendersystems sometimes disagree on the origin of a texel, 
+		mapping from texels to pixels can sometimes be problematic to 
+		implement generically. This method allows you to retrieve the offset
+		required to map the origin of a texel to the origin of a pixel in
+		the horizontal direction.
+		*/
+		virtual Real getHorizontalTexelOffset(void) = 0;
+		/** Returns the vertical texel offset value required for mapping 
+		texel origins to pixel origins in this rendersystem.
+		@remarks
+		Since rendersystems sometimes disagree on the origin of a texel, 
+		mapping from texels to pixels can sometimes be problematic to 
+		implement generically. This method allows you to retrieve the offset
+		required to map the origin of a texel to the origin of a pixel in
+		the vertical direction.
+		*/
+		virtual Real getVerticalTexelOffset(void) = 0;
+
+		/** Gets the minimum (closest) depth value to be used when rendering
+		using identity transforms.
+		@remarks
+		When using identity transforms you can manually set the depth
+		of a vertex; however the input values required differ per
+		rendersystem. This method lets you retrieve the correct value.
+		@see Renderable::getUseIdentityView, Renderable::getUseIdentityProjection
+		*/
+		virtual Real getMinimumDepthInputValue(void) = 0;
+		/** Gets the maximum (farthest) depth value to be used when rendering
+		using identity transforms.
+		@remarks
+		When using identity transforms you can manually set the depth
+		of a vertex; however the input values required differ per
+		rendersystem. This method lets you retrieve the correct value.
+		@see Renderable::getUseIdentityView, Renderable::getUseIdentityProjection
+		*/
+		virtual Real getMaximumDepthInputValue(void) = 0;
+		/** set the current multi pass count value.  This must be set prior to 
+		calling _render() if multiple renderings of the same pass state are 
+		required.
+		@param count Number of times to render the current state.
+		*/
+		virtual void setCurrentPassIterationCount(const size_t count) { mCurrentPassIterationCount = count; }
+
+		/** Tell the render system whether to derive a depth bias on its own based on 
+		the values passed to it in setCurrentPassIterationCount.
+		The depth bias set will be baseValue + iteration * multiplier
+		@param derive True to tell the RS to derive this automatically
+		@param baseValue The base value to which the multiplier should be
+		added
+		@param multiplier The amount of depth bias to apply per iteration
+		@param slopeScale The constant slope scale bias for completeness
+		*/
+		virtual void setDeriveDepthBias(bool derive, float baseValue = 0.0f,
+			float multiplier = 0.0f, float slopeScale = 0.0f)
+		{
+			mDerivedDepthBias = derive;
+			mDerivedDepthBiasBase = baseValue;
+			mDerivedDepthBiasMultiplier = multiplier;
+			mDerivedDepthBiasSlopeScale = slopeScale;
+		}
+
+		/**
+         * Set current render target to target, enabling its device context if needed
+         */
+        virtual void _setRenderTarget(RenderTarget *target) = 0;
+
+		/** Defines a listener on the custom events that this render system 
+		can raise.
+		@see RenderSystem::addListener
+		*/
+		class _OgreExport Listener
+		{
+		public:
+			Listener() {}
+			virtual ~Listener() {}
+
+			/** A rendersystem-specific event occurred.
+			@param eventName The name of the event which has occurred
+			@param parameters A list of parameters that may belong to this event,
+			may be null if there are no parameters
+			*/
+			virtual void eventOccurred(const String& eventName, 
+				const NameValuePairList* parameters = 0) = 0;
+		};
+		/** Adds a listener to the custom events that this render system can raise.
+		@remarks
+		Some render systems have quite specific, internally generated events 
+		that the application may wish to be notified of. Many applications
+		don't have to worry about these events, and can just trust OGRE to 
+		handle them, but if you want to know, you can add a listener here.
+		@par
+		Events are raised very generically by string name. Perhaps the most 
+		common example of a render system specific event is the loss and 
+		restoration of a device in DirectX; which OGRE deals with, but you 
+		may wish to know when it happens. 
+		@see RenderSystem::getRenderSystemEvents
+		*/
+		virtual void addListener(Listener* l);
+		/** Remove a listener to the custom events that this render system can raise.
+		*/
+		virtual void removeListener(Listener* l);
+
+		/** Gets a list of the rendersystem specific events that this rendersystem
+		can raise.
+		@see RenderSystem::addListener
+		*/
+		virtual const StringVector& getRenderSystemEvents(void) const { return mEventNames; }
+
+		/** Tell the rendersystem to perform any prep tasks it needs to directly
+		before other threads which might access the rendering API are registered.
+		@remarks
+		Call this from your main thread before starting your other threads
+		(which themselves should call registerThread()). Note that if you
+		start your own threads, there is a specific startup sequence which 
+		must be respected and requires synchronisation between the threads:
+		<ol>
+		<li>[Main thread]Call preExtraThreadsStarted</li>
+		<li>[Main thread]Start other thread, wait</li>
+		<li>[Other thread]Call registerThread, notify main thread & continue</li>
+		<li>[Main thread]Wake up & call postExtraThreadsStarted</li>
+		</ol>
+		Once this init sequence is completed the threads are independent but
+		this startup sequence must be respected.
+		*/
+		virtual void preExtraThreadsStarted() = 0;
+
+		/* Tell the rendersystem to perform any tasks it needs to directly
+		after other threads which might access the rendering API are registered.
+		@see RenderSystem::preExtraThreadsStarted
+		*/
+		virtual void postExtraThreadsStarted() = 0;
+
+		/** Register the an additional thread which may make calls to rendersystem-related 
+		objects.
+		@remarks
+		This method should only be called by additional threads during their
+		initialisation. If they intend to use hardware rendering system resources 
+		they should call this method before doing anything related to the render system.
+		Some rendering APIs require a per-thread setup and this method will sort that
+		out. It is also necessary to call unregisterThread before the thread shuts down.
+		@note
+		This method takes no parameters - it must be called from the thread being
+		registered and that context is enough.
+		*/
+		virtual void registerThread() = 0;
+
+		/** Unregister an additional thread which may make calls to rendersystem-related objects.
+		@see RenderSystem::registerThread
+		*/
+		virtual void unregisterThread() = 0;
+
+		/**
+		* Gets the number of display monitors.
+		@see Root::getDisplayMonitorCount
+		*/
+		virtual unsigned int getDisplayMonitorCount() const = 0;
+	protected:
+
+
+		/** The render targets. */
+		RenderTargetMap mRenderTargets;
+		/** The render targets, ordered by priority. */
+		RenderTargetPriorityMap mPrioritisedRenderTargets;
+		/** The Active render target. */
+		RenderTarget * mActiveRenderTarget;
+		/** The Active GPU programs and gpu program parameters*/
+		GpuProgramParametersSharedPtr mActiveVertexGpuProgramParameters;
+		GpuProgramParametersSharedPtr mActiveGeometryGpuProgramParameters;
+		GpuProgramParametersSharedPtr mActiveFragmentGpuProgramParameters;
+
+		// Texture manager
+		// A concrete class of this will be created and
+		// made available under the TextureManager singleton,
+		// managed by the RenderSystem
+		TextureManager* mTextureManager;
+
+		// Active viewport (dest for future rendering operations)
+		Viewport* mActiveViewport;
+
+		CullingMode mCullingMode;
+
+		bool mVSync;
+		unsigned int mVSyncInterval;
+		bool mWBuffer;
+
+		size_t mBatchCount;
+		size_t mFaceCount;
+		size_t mVertexCount;
+
+		/// Saved manual colour blends
+		ColourValue mManualBlendColours[OGRE_MAX_TEXTURE_LAYERS][2];
+
+		bool mInvertVertexWinding;
+
+		/// Texture units from this upwards are disabled
+		size_t mDisabledTexUnitsFrom;
+
+		/// number of times to render the current state
+		size_t mCurrentPassIterationCount;
+		size_t mCurrentPassIterationNum;
+		/// Whether to update the depth bias per render call
+		bool mDerivedDepthBias;
+		float mDerivedDepthBiasBase;
+		float mDerivedDepthBiasMultiplier;
+		float mDerivedDepthBiasSlopeScale;
+
+		/** updates pass iteration rendering state including bound gpu program parameter
+		pass iteration auto constant entry
+		@returns True if more iterations are required
+		*/
+		bool updatePassIterationRenderState(void);
+
+		/// List of names of events this rendersystem may raise
+		StringVector mEventNames;
+
+		/// Internal method for firing a rendersystem event
+		virtual void fireEvent(const String& name, const NameValuePairList* params = 0);
+
+		typedef list<Listener*>::type ListenerList;
+		ListenerList mEventListeners;
+
+		typedef list<HardwareOcclusionQuery*>::type HardwareOcclusionQueryList;
+		HardwareOcclusionQueryList mHwOcclusionQueries;
+
+		bool mVertexProgramBound;
+		bool mGeometryProgramBound;
+		bool mFragmentProgramBound;
+
+		// Recording user clip planes
+		PlaneList mClipPlanes;
+		// Indicator that we need to re-set the clip planes on next render call
+		bool mClipPlanesDirty;
+
+		/// Used to store the capabilities of the graphics card
+		RenderSystemCapabilities* mRealCapabilities;
+		RenderSystemCapabilities* mCurrentCapabilities;
+		bool mUseCustomCapabilities;
+
+		/// Internal method used to set the underlying clip planes when needed
+		virtual void setClipPlanesImpl(const PlaneList& clipPlanes) = 0;
+
+		/** Initialize the render system from the capabilities*/
+		virtual void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary) = 0;
+
+
+		DriverVersion mDriverVersion;
+
+		bool mTexProjRelative;
+		Vector3 mTexProjRelativeOrigin;
+
+
+
+	};
+	/** @} */
+	/** @} */
+}
+
+#endif

+ 167 - 0
CamelotRenderer/OgreTexture.cpp

@@ -0,0 +1,167 @@
+/*
+-----------------------------------------------------------------------------
+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 "OgreHardwarePixelBuffer.h"
+#include "OgreTexture.h"
+#include "OgreException.h"
+
+namespace Ogre {
+	//--------------------------------------------------------------------------
+    Texture::Texture()
+        : // init defaults; can be overridden before load()
+            mHeight(512),
+            mWidth(512),
+            mDepth(1),
+			mNumRequestedMipmaps(0),
+            mNumMipmaps(0),
+			mMipmapsHardwareGenerated(false),
+            mGamma(1.0f),
+			mHwGamma(false),
+			mFSAA(0),
+            mTextureType(TEX_TYPE_2D),            
+            mFormat(PF_UNKNOWN),
+            mUsage(TU_DEFAULT),
+            mSrcFormat(PF_UNKNOWN),
+            mSrcWidth(0),
+            mSrcHeight(0), 
+            mSrcDepth(0),
+            mDesiredFormat(PF_UNKNOWN),
+            mDesiredIntegerBitDepth(0),
+            mDesiredFloatBitDepth(0),
+            mTreatLuminanceAsAlpha(false),
+            mInternalResourcesCreated(false)
+    {
+        
+    }
+    //--------------------------------------------------------------------------
+    void Texture::setFormat(PixelFormat pf)
+    {
+        mFormat = pf;
+        mDesiredFormat = pf;
+        mSrcFormat = pf;
+    }
+    //--------------------------------------------------------------------------
+    bool Texture::hasAlpha(void) const
+    {
+        return PixelUtil::hasAlpha(mFormat);
+    }
+    //--------------------------------------------------------------------------
+    void Texture::setDesiredIntegerBitDepth(ushort bits)
+    {
+        mDesiredIntegerBitDepth = bits;
+    }
+    //--------------------------------------------------------------------------
+    ushort Texture::getDesiredIntegerBitDepth(void) const
+    {
+        return mDesiredIntegerBitDepth;
+    }
+    //--------------------------------------------------------------------------
+    void Texture::setDesiredFloatBitDepth(ushort bits)
+    {
+        mDesiredFloatBitDepth = bits;
+    }
+    //--------------------------------------------------------------------------
+    ushort Texture::getDesiredFloatBitDepth(void) const
+    {
+        return mDesiredFloatBitDepth;
+    }
+    //--------------------------------------------------------------------------
+    void Texture::setDesiredBitDepths(ushort integerBits, ushort floatBits)
+    {
+        mDesiredIntegerBitDepth = integerBits;
+        mDesiredFloatBitDepth = floatBits;
+    }
+    //--------------------------------------------------------------------------
+    void Texture::setTreatLuminanceAsAlpha(bool asAlpha)
+    {
+        mTreatLuminanceAsAlpha = asAlpha;
+    }
+    //--------------------------------------------------------------------------
+    bool Texture::getTreatLuminanceAsAlpha(void) const
+    {
+        return mTreatLuminanceAsAlpha;
+    }
+    //--------------------------------------------------------------------------
+	size_t Texture::calculateSize(void) const
+	{
+        return getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
+	}
+	//--------------------------------------------------------------------------
+	size_t Texture::getNumFaces(void) const
+	{
+		return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
+	}
+	//-----------------------------------------------------------------------------
+	void Texture::createInternalResources(void)
+	{
+		if (!mInternalResourcesCreated)
+		{
+			createInternalResourcesImpl();
+			mInternalResourcesCreated = true;
+		}
+	}
+	//-----------------------------------------------------------------------------
+	void Texture::freeInternalResources(void)
+	{
+		if (mInternalResourcesCreated)
+		{
+			freeInternalResourcesImpl();
+			mInternalResourcesCreated = false;
+		}
+	}
+	//-----------------------------------------------------------------------------
+	void Texture::unloadImpl(void)
+	{
+		freeInternalResources();
+	}
+    //-----------------------------------------------------------------------------   
+    void Texture::copyToTexture( TexturePtr& target )
+    {
+        if(target->getNumFaces() != getNumFaces())
+        {
+            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
+                "Texture types must match",
+                "Texture::copyToTexture");
+        }
+        size_t numMips = std::min(getNumMipmaps(), target->getNumMipmaps());
+        if((mUsage & TU_AUTOMIPMAP) || (target->getUsage()&TU_AUTOMIPMAP))
+            numMips = 0;
+        for(unsigned int face=0; face<getNumFaces(); face++)
+        {
+            for(unsigned int mip=0; mip<=numMips; mip++)
+            {
+                target->getBuffer(face, mip)->blit(getBuffer(face, mip));
+            }
+        }
+    }
+	//---------------------------------------------------------------------
+	String Texture::getSourceFileType() const
+	{
+		// TODO PORT - This requires Resource specific stuff I don't have
+		return StringUtil::BLANK;
+	}
+}

+ 413 - 0
CamelotRenderer/OgreTexture.h

@@ -0,0 +1,413 @@
+/*
+-----------------------------------------------------------------------------
+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 _Texture_H__
+#define _Texture_H__
+
+#include "OgrePrerequisites.h"
+#include "OgreSharedPtr.h"
+#include "OgreHardwareBuffer.h"
+
+namespace Ogre {
+
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup Resources
+	*  @{
+	*/
+	/** Enum identifying the texture usage
+    */
+    enum TextureUsage
+    {
+		/// @copydoc HardwareBuffer::Usage
+		TU_STATIC = HardwareBuffer::HBU_STATIC,
+		TU_DYNAMIC = HardwareBuffer::HBU_DYNAMIC,
+		TU_WRITE_ONLY = HardwareBuffer::HBU_WRITE_ONLY,
+		TU_STATIC_WRITE_ONLY = HardwareBuffer::HBU_STATIC_WRITE_ONLY, 
+		TU_DYNAMIC_WRITE_ONLY = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY,
+		TU_DYNAMIC_WRITE_ONLY_DISCARDABLE = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
+		/// mipmaps will be automatically generated for this texture
+		TU_AUTOMIPMAP = 0x100,
+		/// this texture will be a render target, i.e. used as a target for render to texture
+		/// setting this flag will ignore all other texture usages except TU_AUTOMIPMAP
+		TU_RENDERTARGET = 0x200,
+		/// default to automatic mipmap generation static textures
+		TU_DEFAULT = TU_AUTOMIPMAP | TU_STATIC_WRITE_ONLY
+        
+    };
+
+    /** Enum identifying the texture type
+    */
+    enum TextureType
+    {
+        /// 1D texture, used in combination with 1D texture coordinates
+        TEX_TYPE_1D = 1,
+        /// 2D texture, used in combination with 2D texture coordinates (default)
+        TEX_TYPE_2D = 2,
+        /// 3D volume texture, used in combination with 3D texture coordinates
+        TEX_TYPE_3D = 3,
+        /// 3D cube map, used in combination with 3D texture coordinates
+        TEX_TYPE_CUBE_MAP = 4
+    };
+
+	/** Enum identifying special mipmap numbers
+    */
+	enum TextureMipmap
+	{
+		/// Generate mipmaps up to 1x1
+		MIP_UNLIMITED = 0x7FFFFFFF,
+		/// Use TextureManager default
+		MIP_DEFAULT = -1
+	};
+
+    // Forward declaration
+    class TexturePtr;
+
+    /** Abstract class representing a Texture resource.
+        @remarks
+            The actual concrete subclass which will exist for a texture
+            is dependent on the rendering system in use (Direct3D, OpenGL etc).
+            This class represents the commonalities, and is the one 'used'
+            by programmers even though the real implementation could be
+            different in reality. Texture objects are created through
+            the 'create' method of the TextureManager concrete subclass.
+     */
+    class _OgreExport Texture
+    {
+    public:
+        Texture();
+
+        /** Sets the type of texture; can only be changed before load() 
+        */
+        virtual void setTextureType(TextureType ttype ) { mTextureType = ttype; }
+
+        /** Gets the type of texture 
+        */
+        virtual TextureType getTextureType(void) const { return mTextureType; }
+
+        /** Gets the number of mipmaps to be used for this texture.
+        */
+        virtual size_t getNumMipmaps(void) const {return mNumMipmaps;}
+
+		/** Sets the number of mipmaps to be used for this texture.
+            @note
+                Must be set before calling any 'load' method.
+        */
+        virtual void setNumMipmaps(size_t num) {mNumRequestedMipmaps = mNumMipmaps = num;}
+
+		/** Are mipmaps hardware generated?
+		@remarks
+			Will only be accurate after texture load, or createInternalResources
+		*/
+		virtual bool getMipmapsHardwareGenerated(void) const { return mMipmapsHardwareGenerated; }
+
+        /** Returns the gamma adjustment factor applied to this texture on loading.
+        */
+        virtual float getGamma(void) const { return mGamma; }
+
+        /** Sets the gamma adjustment factor applied to this texture on loading the
+			data.
+            @note
+                Must be called before any 'load' method. This gamma factor will
+				be premultiplied in and may reduce the precision of your textures.
+				You can use setHardwareGamma if supported to apply gamma on 
+				sampling the texture instead.
+        */
+        virtual void setGamma(float g) { mGamma = g; }
+
+		/** Sets whether this texture will be set up so that on sampling it, 
+			hardware gamma correction is applied.
+		@remarks
+			24-bit textures are often saved in gamma colour space; this preserves
+			precision in the 'darks'. However, if you're performing blending on 
+			the sampled colours, you really want to be doing it in linear space. 
+			One way is to apply a gamma correction value on loading (see setGamma),
+			but this means you lose precision in those dark colours. An alternative
+			is to get the hardware to do the gamma correction when reading the 
+			texture and converting it to a floating point value for the rest of
+			the pipeline. This option allows you to do that; it's only supported
+			in relatively recent hardware (others will ignore it) but can improve
+			the quality of colour reproduction.
+		@note
+			Must be called before any 'load' method since it may affect the
+			construction of the underlying hardware resources.
+			Also note this only useful on textures using 8-bit colour channels.
+		*/
+		virtual void setHardwareGammaEnabled(bool enabled) { mHwGamma = enabled; }
+
+		/** Gets whether this texture will be set up so that on sampling it, 
+		hardware gamma correction is applied.
+		*/
+		virtual bool isHardwareGammaEnabled() const { return mHwGamma; }
+
+		/** Set the level of multisample AA to be used if this texture is a 
+			rendertarget.
+		@note This option will be ignored if TU_RENDERTARGET is not part of the
+			usage options on this texture, or if the hardware does not support it. 
+		@param fsaa The number of samples
+		@param fsaaHint Any hinting text (@see Root::createRenderWindow)
+		*/
+		virtual void setFSAA(uint fsaa, const String& fsaaHint) { mFSAA = fsaa; mFSAAHint = fsaaHint; }
+
+		/** Get the level of multisample AA to be used if this texture is a 
+		rendertarget.
+		*/
+		virtual uint getFSAA() const { return mFSAA; }
+
+		/** Get the multisample AA hint if this texture is a rendertarget.
+		*/
+		virtual const String& getFSAAHint() const { return mFSAAHint; }
+
+		/** Returns the height of the texture.
+        */
+        virtual size_t getHeight(void) const { return mHeight; }
+
+        /** Returns the width of the texture.
+        */
+        virtual size_t getWidth(void) const { return mWidth; }
+
+        /** Returns the depth of the texture (only applicable for 3D textures).
+        */
+        virtual size_t getDepth(void) const { return mDepth; }
+
+        /** Returns the height of the original input texture (may differ due to hardware requirements).
+        */
+        virtual size_t getSrcHeight(void) const { return mSrcHeight; }
+
+        /** Returns the width of the original input texture (may differ due to hardware requirements).
+        */
+        virtual size_t getSrcWidth(void) const { return mSrcWidth; }
+
+        /** Returns the original depth of the input texture (only applicable for 3D textures).
+        */
+        virtual size_t getSrcDepth(void) const { return mSrcDepth; }
+
+        /** Set the height of the texture; can only do this before load();
+        */
+        virtual void setHeight(size_t h) { mHeight = mSrcHeight = h; }
+
+        /** Set the width of the texture; can only do this before load();
+        */
+        virtual void setWidth(size_t w) { mWidth = mSrcWidth = w; }
+
+        /** Set the depth of the texture (only applicable for 3D textures);
+            ; can only do this before load();
+        */
+        virtual void setDepth(size_t d)  { mDepth = mSrcDepth = d; }
+
+        /** Returns the TextureUsage indentifier for this Texture
+        */
+        virtual int getUsage() const
+        {
+            return mUsage;
+        }
+
+        /** Sets the TextureUsage indentifier for this Texture; only useful before load()
+			
+			@param u is a combination of TU_STATIC, TU_DYNAMIC, TU_WRITE_ONLY 
+				TU_AUTOMIPMAP and TU_RENDERTARGET (see TextureUsage enum). You are
+            	strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to 
+            	update regularly, consider HBU_DYNAMIC_WRITE_ONLY.
+        */
+        virtual void setUsage(int u) { mUsage = u; }
+
+        /** Creates the internal texture resources for this texture. 
+        @remarks
+            This method creates the internal texture resources (pixel buffers, 
+            texture surfaces etc) required to begin using this texture. You do
+            not need to call this method directly unless you are manually creating
+            a texture, in which case something must call it, after having set the
+            size and format of the texture (e.g. the ManualResourceLoader might
+            be the best one to call it). If you are not defining a manual texture,
+            or if you use one of the self-contained load...() methods, then it will be
+            called for you.
+        */
+        virtual void createInternalResources(void);
+
+        /** Frees internal texture resources for this texture. 
+        */
+        virtual void freeInternalResources(void);
+        
+		/** Copies (and maybe scales to fit) the contents of this texture to
+			another texture. */
+		virtual void copyToTexture( TexturePtr& target );
+
+		/** Returns the pixel format for the texture surface. */
+		virtual PixelFormat getFormat() const
+		{
+			return mFormat;
+		}
+
+        /** Returns the desired pixel format for the texture surface. */
+        virtual PixelFormat getDesiredFormat(void) const
+        {
+            return mDesiredFormat;
+        }
+
+        /** Returns the pixel format of the original input texture (may differ due to
+            hardware requirements and pixel format convertion).
+        */
+        virtual PixelFormat getSrcFormat(void) const
+        {
+            return mSrcFormat;
+        }
+
+        /** Sets the pixel format for the texture surface; can only be set before load(). */
+        virtual void setFormat(PixelFormat pf);
+
+        /** Returns true if the texture has an alpha layer. */
+        virtual bool hasAlpha(void) const;
+
+        /** Sets desired bit depth for integer pixel format textures.
+        @note
+            Available values: 0, 16 and 32, where 0 (the default) means keep original format
+            as it is. This value is number of bits for the pixel.
+        */
+        virtual void setDesiredIntegerBitDepth(ushort bits);
+
+        /** gets desired bit depth for integer pixel format textures.
+        */
+        virtual ushort getDesiredIntegerBitDepth(void) const;
+
+        /** Sets desired bit depth for float pixel format textures.
+        @note
+            Available values: 0, 16 and 32, where 0 (the default) means keep original format
+            as it is. This value is number of bits for a channel of the pixel.
+        */
+        virtual void setDesiredFloatBitDepth(ushort bits);
+
+        /** gets desired bit depth for float pixel format textures.
+        */
+        virtual ushort getDesiredFloatBitDepth(void) const;
+
+        /** Sets desired bit depth for integer and float pixel format.
+        */
+        virtual void setDesiredBitDepths(ushort integerBits, ushort floatBits);
+
+        /** Sets whether luminace pixel format will treated as alpha format when load this texture.
+        */
+        virtual void setTreatLuminanceAsAlpha(bool asAlpha);
+
+        /** Gets whether luminace pixel format will treated as alpha format when load this texture.
+        */
+        virtual bool getTreatLuminanceAsAlpha(void) const;
+
+        /** Return the number of faces this texture has. This will be 6 for a cubemap
+        	texture and 1 for a 1D, 2D or 3D one.
+        */
+        virtual size_t getNumFaces() const;
+
+		/** Return hardware pixel buffer for a surface. This buffer can then
+			be used to copy data from and to a particular level of the texture.
+			@param face 	Face number, in case of a cubemap texture. Must be 0
+							for other types of textures.
+                            For cubemaps, this is one of 
+                            +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5)
+			@param mipmap	Mipmap level. This goes from 0 for the first, largest
+							mipmap level to getNumMipmaps()-1 for the smallest.
+			@returns	A shared pointer to a hardware pixel buffer
+			@remarks	The buffer is invalidated when the resource is unloaded or destroyed.
+						Do not use it after the lifetime of the containing texture.
+		*/
+		virtual HardwarePixelBufferSharedPtr getBuffer(size_t face=0, size_t mipmap=0) = 0;
+		
+		/** Retrieve a platform or API-specific piece of information from this texture.
+		 This method of retrieving information should only be used if you know what you're doing.
+		 @param name The name of the attribute to retrieve
+		 @param pData Pointer to memory matching the type of data you want to retrieve.
+		*/
+		virtual void getCustomAttribute(const String& name, void* pData) {}
+		
+    protected:
+        size_t mHeight;
+        size_t mWidth;
+        size_t mDepth;
+
+        size_t mNumRequestedMipmaps;
+		size_t mNumMipmaps;
+		bool mMipmapsHardwareGenerated;
+        float mGamma;
+		bool mHwGamma;
+		uint mFSAA;
+		String mFSAAHint;
+
+        TextureType mTextureType;
+		PixelFormat mFormat;
+        int mUsage; // Bit field, so this can't be TextureUsage
+
+        PixelFormat mSrcFormat;
+        size_t mSrcWidth, mSrcHeight, mSrcDepth;
+
+        PixelFormat mDesiredFormat;
+        unsigned short mDesiredIntegerBitDepth;
+        unsigned short mDesiredFloatBitDepth;
+        bool mTreatLuminanceAsAlpha;
+
+		bool mInternalResourcesCreated;
+
+		/// @copydoc Resource::calculateSize
+		size_t calculateSize(void) const;
+		
+
+		/** Implementation of creating internal texture resources 
+		*/
+		virtual void createInternalResourcesImpl(void) = 0;
+
+		/** Implementation of freeing internal texture resources 
+		*/
+		virtual void freeInternalResourcesImpl(void) = 0;
+
+		/** Default implementation of unload which calls freeInternalResources */
+		void unloadImpl(void);
+
+		/** Identify the source file type as a string, either from the extension
+			or from a magic number.
+		*/
+		String getSourceFileType() const;
+
+    };
+
+    /** Specialisation of SharedPtr to allow SharedPtr to be assigned to TexturePtr 
+    @note Has to be a subclass since we need operator=.
+    We could templatise this instead of repeating per Resource subclass, 
+    except to do so requires a form VC6 does not support i.e.
+    ResourceSubclassPtr<T> : public SharedPtr<T>
+    */
+    class _OgreExport TexturePtr : public SharedPtr<Texture> 
+    {
+    public:
+        TexturePtr() : SharedPtr<Texture>() {}
+        explicit TexturePtr(Texture* rep) : SharedPtr<Texture>(rep) {}
+        TexturePtr(const TexturePtr& r) : SharedPtr<Texture>(r) {} 
+    };
+	/** @} */
+	/** @} */
+
+}
+
+#endif

+ 1070 - 0
CamelotRenderer/OgreTextureUnitState.cpp

@@ -0,0 +1,1070 @@
+/*
+-----------------------------------------------------------------------------
+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 "OgreTextureUnitState.h"
+#include "OgreException.h"
+
+namespace Ogre {
+
+    //-----------------------------------------------------------------------
+    TextureUnitState::TextureUnitState(Pass* parent)
+        : mCurrentFrame(0)
+		, mAnimDuration(0)
+		, mCubic(false)
+		, mTextureType(TEX_TYPE_2D)
+        , mDesiredFormat(PF_UNKNOWN)
+		, mTextureSrcMipmaps(MIP_DEFAULT)
+		, mTextureCoordSetIndex(0)
+		, mBorderColour(ColourValue::Black)
+		, mTextureLoadFailed(false)
+		, mIsAlpha(false)
+		, mHwGamma(false)
+		, mRecalcTexMatrix(false)
+		, mUMod(0)
+		, mVMod(0)
+		, mUScale(1)
+		, mVScale(1)
+		, mRotate(0)
+		, mTexModMatrix(Matrix4::IDENTITY)
+		, mMinFilter(FO_LINEAR)
+		, mMagFilter(FO_LINEAR)
+		, mMipFilter(FO_POINT)
+		, mMaxAniso(0)
+		, mMipmapBias(0)
+		, mIsDefaultAniso(true)
+		, mIsDefaultFiltering(true)
+		, mBindingType(BT_FRAGMENT)
+		, mContentType(CONTENT_NAMED)
+		, mParent(parent)
+		, mAnimController(0)
+    {
+		mColourBlendMode.blendType = LBT_COLOUR;
+		mAlphaBlendMode.operation = LBX_MODULATE;
+		mAlphaBlendMode.blendType = LBT_ALPHA;
+		mAlphaBlendMode.source1 = LBS_TEXTURE;
+		mAlphaBlendMode.source2 = LBS_CURRENT;
+		setColourOperation(LBO_MODULATE);
+		setTextureAddressingMode(TAM_WRAP);
+    }
+
+    //-----------------------------------------------------------------------
+    TextureUnitState::TextureUnitState(Pass* parent, const TextureUnitState& oth )
+    {
+        mParent = parent;
+        mAnimController = 0;
+        *this = oth;
+    }
+
+    //-----------------------------------------------------------------------
+    TextureUnitState::TextureUnitState( Pass* parent, const String& texName, unsigned int texCoordSet)
+		: mCurrentFrame(0)
+		, mAnimDuration(0)
+		, mCubic(false)
+		, mTextureType(TEX_TYPE_2D)
+        , mDesiredFormat(PF_UNKNOWN)
+		, mTextureSrcMipmaps(MIP_DEFAULT)
+		, mTextureCoordSetIndex(0)
+		, mBorderColour(ColourValue::Black)
+		, mTextureLoadFailed(false)
+		, mIsAlpha(false)
+		, mHwGamma(false)
+		, mRecalcTexMatrix(false)
+		, mUMod(0)
+		, mVMod(0)
+		, mUScale(1)
+		, mVScale(1)
+		, mRotate(0)
+		, mTexModMatrix(Matrix4::IDENTITY)
+		, mMinFilter(FO_LINEAR)
+		, mMagFilter(FO_LINEAR)
+		, mMipFilter(FO_POINT)
+		, mMaxAniso(0)
+		, mMipmapBias(0)
+		, mIsDefaultAniso(true)
+		, mIsDefaultFiltering(true)
+		, mBindingType(BT_FRAGMENT)
+		, mContentType(CONTENT_NAMED)
+		, mParent(parent)
+		, mAnimController(0)
+    {
+		mColourBlendMode.blendType = LBT_COLOUR;
+		mAlphaBlendMode.operation = LBX_MODULATE;
+		mAlphaBlendMode.blendType = LBT_ALPHA;
+		mAlphaBlendMode.source1 = LBS_TEXTURE;
+		mAlphaBlendMode.source2 = LBS_CURRENT;
+		setColourOperation(LBO_MODULATE);
+		setTextureAddressingMode(TAM_WRAP);
+
+        setTextureName(texName);
+        setTextureCoordSet(texCoordSet);
+    }
+    //-----------------------------------------------------------------------
+    TextureUnitState::~TextureUnitState()
+    {
+        // Unload ensure all controllers destroyed
+        _unload();
+    }
+    //-----------------------------------------------------------------------
+    TextureUnitState & TextureUnitState::operator = ( 
+        const TextureUnitState &oth )
+    {
+        assert(mAnimController == 0);
+        assert(mEffects.empty());
+
+        // copy basic members (int's, real's)
+        memcpy( this, &oth, (uchar *)(&oth.mFrames) - (uchar *)(&oth) );
+        // copy complex members
+        mFrames  = oth.mFrames;
+		mFramePtrs = oth.mFramePtrs;
+        mName    = oth.mName;
+        mEffects = oth.mEffects;
+
+        mTextureNameAlias = oth.mTextureNameAlias;
+		mCompositorRefName = oth.mCompositorRefName;
+		mCompositorRefTexName = oth.mCompositorRefTexName;
+        // Can't sharing controllers with other TUS, reset to null to avoid potential bug.
+        for (EffectMap::iterator j = mEffects.begin(); j != mEffects.end(); ++j)
+        {
+            j->second.controller = 0;
+        }
+
+        // Load immediately if Material loaded
+        if (isLoaded())
+        {
+            _load();
+        }
+
+        return *this;
+    }
+    //-----------------------------------------------------------------------
+    const String& TextureUnitState::getTextureName(void) const
+    {
+        // Return name of current frame
+        if (mCurrentFrame < mFrames.size())
+            return mFrames[mCurrentFrame];
+        else
+            return StringUtil::BLANK;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureName( const String& name, TextureType texType)
+    {
+		setContentType(CONTENT_NAMED);
+		mTextureLoadFailed = false;
+
+		if (texType == TEX_TYPE_CUBE_MAP)
+        {
+            // delegate to cubic texture implementation
+            setCubicTextureName(name, true);
+        }
+        else
+        {
+            mFrames.resize(1);
+			mFramePtrs.resize(1);
+            mFrames[0] = name;
+			mFramePtrs[0].setNull();
+			// defer load until used, so don't grab pointer yet
+            mCurrentFrame = 0;
+            mCubic = false;
+            mTextureType = texType;
+            if (name.empty())
+            {
+                return;
+            }
+
+            
+            // Load immediately ?
+            if (isLoaded())
+            {
+                _load(); // reload
+            }
+        }
+
+    }
+	//-----------------------------------------------------------------------
+	void TextureUnitState::setBindingType(TextureUnitState::BindingType bt)
+	{
+		mBindingType = bt;
+
+	}
+	//-----------------------------------------------------------------------
+	TextureUnitState::BindingType TextureUnitState::getBindingType(void) const
+	{
+		return mBindingType;
+	}
+	//-----------------------------------------------------------------------
+	void TextureUnitState::setContentType(TextureUnitState::ContentType ct)
+	{
+		mContentType = ct;
+		if (ct == CONTENT_SHADOW || ct == CONTENT_COMPOSITOR)
+		{
+			// Clear out texture frames, not applicable
+			mFrames.clear();
+			// One reference space, set manually through _setTexturePtr
+			mFramePtrs.resize(1);
+			mFramePtrs[0].setNull();
+		}
+	}
+	//-----------------------------------------------------------------------
+	TextureUnitState::ContentType TextureUnitState::getContentType(void) const
+	{
+		return mContentType;
+	}
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setCubicTextureName( const String& name, bool forUVW)
+    {
+        if (forUVW)
+        {
+            setCubicTextureName(&name, forUVW);
+        }
+        else
+        {
+			setContentType(CONTENT_NAMED);
+			mTextureLoadFailed = false;
+            String ext;
+            String suffixes[6] = {"_fr", "_bk", "_lf", "_rt", "_up", "_dn"};
+            String baseName;
+            String fullNames[6];
+
+            size_t pos = name.find_last_of(".");
+			if( pos != String::npos )
+			{
+				baseName = name.substr(0, pos);
+				ext = name.substr(pos);
+			}
+			else
+				baseName = name;
+
+            for (int i = 0; i < 6; ++i)
+            {
+                fullNames[i] = baseName + suffixes[i] + ext;
+            }
+
+            setCubicTextureName(fullNames, forUVW);
+        }
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setCubicTextureName(const String* const names, bool forUVW)
+    {
+		setContentType(CONTENT_NAMED);
+		mTextureLoadFailed = false;
+        mFrames.resize(forUVW ? 1 : 6);
+		// resize pointers, but don't populate until asked for
+        mFramePtrs.resize(forUVW ? 1 : 6);
+		mAnimDuration = 0;
+        mCurrentFrame = 0;
+        mCubic = true;
+        mTextureType = forUVW ? TEX_TYPE_CUBE_MAP : TEX_TYPE_2D;
+
+        for (unsigned int i = 0; i < mFrames.size(); ++i)
+        {
+            mFrames[i] = names[i];
+			mFramePtrs[i].setNull();
+        }
+    }
+    //-----------------------------------------------------------------------
+    bool TextureUnitState::isCubic(void) const
+    {
+        return mCubic;
+    }
+    //-----------------------------------------------------------------------
+    bool TextureUnitState::is3D(void) const
+    {
+        return mTextureType == TEX_TYPE_CUBE_MAP;
+    }
+    //-----------------------------------------------------------------------
+    TextureType TextureUnitState::getTextureType(void) const
+    {
+        return mTextureType;
+
+    }
+
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setFrameTextureName(const String& name, unsigned int frameNumber)
+    {
+		mTextureLoadFailed = false;
+        if (frameNumber < mFrames.size())
+        {
+            mFrames[frameNumber] = name;
+			// reset pointer (don't populate until requested)
+			mFramePtrs[frameNumber].setNull();	
+
+            if (isLoaded())
+            {
+                _load(); // reload
+            }
+        }
+        else // raise exception for frameNumber out of bounds
+        {
+            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "frameNumber paramter value exceeds number of stored frames.",
+                "TextureUnitState::setFrameTextureName");
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    void TextureUnitState::addFrameTextureName(const String& name)
+    {
+		setContentType(CONTENT_NAMED);
+		mTextureLoadFailed = false;
+
+        mFrames.push_back(name);
+		// Add blank pointer, load on demand
+		mFramePtrs.push_back(TexturePtr());
+
+        // Load immediately if Material loaded
+        if (isLoaded())
+        {
+            _load();
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    void TextureUnitState::deleteFrameTextureName(const size_t frameNumber)
+    {
+		mTextureLoadFailed = false;
+        if (frameNumber < mFrames.size())
+        {
+            mFrames.erase(mFrames.begin() + frameNumber);
+            mFramePtrs.erase(mFramePtrs.begin() + frameNumber);
+
+            if (isLoaded())
+            {
+                _load();
+            }
+        }
+        else
+        {
+            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "frameNumber paramter value exceeds number of stored frames.",
+                "TextureUnitState::deleteFrameTextureName");
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setAnimatedTextureName( const String& name, unsigned int numFrames, Real duration)
+    {
+		setContentType(CONTENT_NAMED);
+		mTextureLoadFailed = false;
+
+		String ext;
+        String baseName;
+
+        size_t pos = name.find_last_of(".");
+        baseName = name.substr(0, pos);
+        ext = name.substr(pos);
+
+        mFrames.resize(numFrames);
+		// resize pointers, but don't populate until needed
+        mFramePtrs.resize(numFrames);
+        mAnimDuration = duration;
+        mCurrentFrame = 0;
+        mCubic = false;
+
+        for (unsigned int i = 0; i < mFrames.size(); ++i)
+        {
+			StringUtil::StrStreamType str;
+            str << baseName << "_" << i << ext;
+            mFrames[i] = str.str();
+			mFramePtrs[i].setNull();
+        }
+
+        // Load immediately if Material loaded
+        if (isLoaded())
+        {
+            _load();
+        }
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setAnimatedTextureName(const String* const names, unsigned int numFrames, Real duration)
+    {
+		setContentType(CONTENT_NAMED);
+		mTextureLoadFailed = false;
+
+		mFrames.resize(numFrames);
+		// resize pointers, but don't populate until needed
+        mFramePtrs.resize(numFrames);
+        mAnimDuration = duration;
+        mCurrentFrame = 0;
+        mCubic = false;
+
+        for (unsigned int i = 0; i < mFrames.size(); ++i)
+        {
+            mFrames[i] = names[i];
+			mFramePtrs[i].setNull();
+        }
+
+        // Load immediately if Material loaded
+        if (isLoaded())
+        {
+            _load();
+        }
+    }
+    //-----------------------------------------------------------------------
+    std::pair< size_t, size_t > TextureUnitState::getTextureDimensions( unsigned int frame ) const
+    {
+		
+		TexturePtr tex = _getTexturePtr(frame);
+	    if (tex.isNull())
+		    OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find texture " + mFrames[ frame ],
+		    "TextureUnitState::getTextureDimensions" );
+
+		return std::pair< size_t, size_t >( tex->getWidth(), tex->getHeight() );
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setCurrentFrame(unsigned int frameNumber)
+    {
+        if (frameNumber < mFrames.size())
+        {
+            mCurrentFrame = frameNumber;
+        }
+        else
+        {
+            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "frameNumber paramter value exceeds number of stored frames.",
+                "TextureUnitState::setCurrentFrame");
+        }
+
+    }
+    //-----------------------------------------------------------------------
+    unsigned int TextureUnitState::getCurrentFrame(void) const
+    {
+        return mCurrentFrame;
+    }
+    //-----------------------------------------------------------------------
+    unsigned int TextureUnitState::getNumFrames(void) const
+    {
+        return (unsigned int)mFrames.size();
+    }
+    //-----------------------------------------------------------------------
+    const String& TextureUnitState::getFrameTextureName(unsigned int frameNumber) const
+    {
+        if (frameNumber >= mFrames.size())
+        {
+            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "frameNumber paramter value exceeds number of stored frames.",
+                "TextureUnitState::getFrameTextureName");
+        }
+
+        return mFrames[frameNumber];
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setDesiredFormat(PixelFormat desiredFormat)
+    {
+        mDesiredFormat = desiredFormat;
+    }
+    //-----------------------------------------------------------------------
+    PixelFormat TextureUnitState::getDesiredFormat(void) const
+    {
+        return mDesiredFormat;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setNumMipmaps(int numMipmaps)
+    {
+        mTextureSrcMipmaps = numMipmaps;
+    }
+    //-----------------------------------------------------------------------
+    int TextureUnitState::getNumMipmaps(void) const
+    {
+        return mTextureSrcMipmaps;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setIsAlpha(bool isAlpha)
+    {
+        mIsAlpha = isAlpha;
+    }
+    //-----------------------------------------------------------------------
+    bool TextureUnitState::getIsAlpha(void) const
+    {
+        return mIsAlpha;
+    }
+	//-----------------------------------------------------------------------
+	void TextureUnitState::setHardwareGammaEnabled(bool g)
+	{
+		mHwGamma = g;
+	}
+	//-----------------------------------------------------------------------
+	bool TextureUnitState::isHardwareGammaEnabled() const
+	{
+		return mHwGamma;
+	}
+    //-----------------------------------------------------------------------
+    unsigned int TextureUnitState::getTextureCoordSet(void) const
+    {
+        return mTextureCoordSetIndex;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureCoordSet(unsigned int set)
+    {
+        mTextureCoordSetIndex = set;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setColourOperationEx(LayerBlendOperationEx op,
+        LayerBlendSource source1,
+        LayerBlendSource source2,
+        const ColourValue& arg1,
+        const ColourValue& arg2,
+        Real manualBlend)
+    {
+        mColourBlendMode.operation = op;
+        mColourBlendMode.source1 = source1;
+        mColourBlendMode.source2 = source2;
+        mColourBlendMode.colourArg1 = arg1;
+        mColourBlendMode.colourArg2 = arg2;
+        mColourBlendMode.factor = manualBlend;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setColourOperation(LayerBlendOperation op)
+    {
+        // Set up the multitexture and multipass blending operations
+        switch (op)
+        {
+        case LBO_REPLACE:
+            setColourOperationEx(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT);
+            setColourOpMultipassFallback(SBF_ONE, SBF_ZERO);
+            break;
+        case LBO_ADD:
+            setColourOperationEx(LBX_ADD, LBS_TEXTURE, LBS_CURRENT);
+            setColourOpMultipassFallback(SBF_ONE, SBF_ONE);
+            break;
+        case LBO_MODULATE:
+            setColourOperationEx(LBX_MODULATE, LBS_TEXTURE, LBS_CURRENT);
+            setColourOpMultipassFallback(SBF_DEST_COLOUR, SBF_ZERO);
+            break;
+        case LBO_ALPHA_BLEND:
+            setColourOperationEx(LBX_BLEND_TEXTURE_ALPHA, LBS_TEXTURE, LBS_CURRENT);
+            setColourOpMultipassFallback(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
+            break;
+        }
+
+
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setColourOpMultipassFallback(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor)
+    {
+        mColourBlendFallbackSrc = sourceFactor;
+        mColourBlendFallbackDest = destFactor;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setAlphaOperation(LayerBlendOperationEx op,
+        LayerBlendSource source1,
+        LayerBlendSource source2,
+        Real arg1,
+        Real arg2,
+        Real manualBlend)
+    {
+        mAlphaBlendMode.operation = op;
+        mAlphaBlendMode.source1 = source1;
+        mAlphaBlendMode.source2 = source2;
+        mAlphaBlendMode.alphaArg1 = arg1;
+        mAlphaBlendMode.alphaArg2 = arg2;
+        mAlphaBlendMode.factor = manualBlend;
+    }
+    //-----------------------------------------------------------------------
+    bool TextureUnitState::isBlank(void) const
+    {
+		if (mFrames.empty())
+			return true;
+		else
+			return mFrames[0].empty() || mTextureLoadFailed;
+    }
+
+    //-----------------------------------------------------------------------
+    SceneBlendFactor TextureUnitState::getColourBlendFallbackSrc(void) const
+    {
+        return mColourBlendFallbackSrc;
+    }
+    //-----------------------------------------------------------------------
+    SceneBlendFactor TextureUnitState::getColourBlendFallbackDest(void) const
+    {
+        return mColourBlendFallbackDest;
+    }
+    //-----------------------------------------------------------------------
+    const LayerBlendModeEx& TextureUnitState::getColourBlendMode(void) const
+    {
+        return mColourBlendMode;
+    }
+    //-----------------------------------------------------------------------
+    const LayerBlendModeEx& TextureUnitState::getAlphaBlendMode(void) const
+    {
+        return mAlphaBlendMode;
+    }
+    //-----------------------------------------------------------------------
+    const TextureUnitState::UVWAddressingMode& 
+	TextureUnitState::getTextureAddressingMode(void) const
+    {
+        return mAddressMode;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureAddressingMode(
+		TextureUnitState::TextureAddressingMode tam)
+    {
+        mAddressMode.u = tam;
+        mAddressMode.v = tam;
+        mAddressMode.w = tam;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureAddressingMode(
+		TextureUnitState::TextureAddressingMode u, 
+		TextureUnitState::TextureAddressingMode v,
+		TextureUnitState::TextureAddressingMode w)
+    {
+        mAddressMode.u = u;
+        mAddressMode.v = v;
+        mAddressMode.w = w;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureAddressingMode(
+		const TextureUnitState::UVWAddressingMode& uvw)
+    {
+        mAddressMode = uvw;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureBorderColour(const ColourValue& colour)
+    {
+        mBorderColour = colour;
+    }
+    //-----------------------------------------------------------------------
+    const ColourValue& TextureUnitState::getTextureBorderColour(void) const
+    {
+        return mBorderColour;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setBlank(void)
+    {
+		setTextureName(StringUtil::BLANK);
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureTransform(const Matrix4& xform)
+    {
+        mTexModMatrix = xform;
+        mRecalcTexMatrix = false;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureScroll(Real u, Real v)
+    {
+        mUMod = u;
+        mVMod = v;
+        mRecalcTexMatrix = true;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureScale(Real uScale, Real vScale)
+    {
+        mUScale = uScale;
+        mVScale = vScale;
+        mRecalcTexMatrix = true;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureRotate(const Radian& angle)
+    {
+        mRotate = angle;
+        mRecalcTexMatrix = true;
+    }
+    //-----------------------------------------------------------------------
+    const Matrix4& TextureUnitState::getTextureTransform() const
+    {
+        if (mRecalcTexMatrix)
+            recalcTextureMatrix();
+        return mTexModMatrix;
+
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::recalcTextureMatrix() const
+    {
+        // Assumption: 2D texture coords
+        Matrix4 xform;
+
+        xform = Matrix4::IDENTITY;
+        if (mUScale != 1 || mVScale != 1)
+        {
+            // Offset to center of texture
+            xform[0][0] = 1/mUScale;
+            xform[1][1] = 1/mVScale;
+            // Skip matrix concat since first matrix update
+            xform[0][3] = (-0.5f * xform[0][0]) + 0.5f;
+            xform[1][3] = (-0.5f * xform[1][1]) + 0.5f;
+        }
+
+        if (mUMod || mVMod)
+        {
+            Matrix4 xlate = Matrix4::IDENTITY;
+
+            xlate[0][3] = mUMod;
+            xlate[1][3] = mVMod;
+
+            xform = xlate * xform;
+        }
+
+        if (mRotate != Radian(0))
+        {
+            Matrix4 rot = Matrix4::IDENTITY;
+            Radian theta ( mRotate );
+            Real cosTheta = Math::Cos(theta);
+            Real sinTheta = Math::Sin(theta);
+
+            rot[0][0] = cosTheta;
+            rot[0][1] = -sinTheta;
+            rot[1][0] = sinTheta;
+            rot[1][1] = cosTheta;
+            // Offset center of rotation to center of texture
+            rot[0][3] = 0.5f + ( (-0.5f * cosTheta) - (-0.5f * sinTheta) );
+            rot[1][3] = 0.5f + ( (-0.5f * sinTheta) + (-0.5f * cosTheta) );
+
+            xform = rot * xform;
+        }
+
+        mTexModMatrix = xform;
+        mRecalcTexMatrix = false;
+
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureUScroll(Real value)
+    {
+        mUMod = value;
+        mRecalcTexMatrix = true;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureVScroll(Real value)
+    {
+        mVMod = value;
+        mRecalcTexMatrix = true;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureUScale(Real value)
+    {
+        mUScale = value;
+        mRecalcTexMatrix = true;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureVScale(Real value)
+    {
+        mVScale = value;
+        mRecalcTexMatrix = true;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::_prepare(void)
+    {
+        // Unload first
+        //_unload();
+
+        // Load textures
+		for (unsigned int i = 0; i < mFrames.size(); ++i)
+		{
+			ensurePrepared(i);
+		}
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::_load(void)
+    {
+
+        // Load textures
+		for (unsigned int i = 0; i < mFrames.size(); ++i)
+		{
+			ensureLoaded(i);
+		}
+    }
+    //-----------------------------------------------------------------------
+	const TexturePtr& TextureUnitState::_getTexturePtr(void) const
+	{
+		return _getTexturePtr(mCurrentFrame);
+	}
+    //-----------------------------------------------------------------------
+	const TexturePtr& TextureUnitState::_getTexturePtr(size_t frame) const
+	{
+		if (mContentType == CONTENT_NAMED)
+		{
+			if (frame < mFrames.size() && !mTextureLoadFailed)
+			{
+				ensureLoaded(frame);
+				return mFramePtrs[frame];
+			}
+			else
+			{
+				// Silent fail with empty texture for internal method
+				static TexturePtr nullTexPtr;
+				return nullTexPtr;
+			}
+		}
+		else
+		{
+			// Manually bound texture, no name or loading
+			assert(frame < mFramePtrs.size());
+			return mFramePtrs[frame];
+
+		}
+		
+	}
+	//-----------------------------------------------------------------------
+	void TextureUnitState::_setTexturePtr(const TexturePtr& texptr)
+	{
+		_setTexturePtr(texptr, mCurrentFrame);
+	}
+	//-----------------------------------------------------------------------
+	void TextureUnitState::_setTexturePtr(const TexturePtr& texptr, size_t frame)
+	{
+		assert(frame < mFramePtrs.size());
+		mFramePtrs[frame] = texptr;
+	}
+    //-----------------------------------------------------------------------
+	void TextureUnitState::ensurePrepared(size_t frame) const
+	{
+	}
+    //-----------------------------------------------------------------------
+	void TextureUnitState::ensureLoaded(size_t frame) const
+	{
+	}
+    //-----------------------------------------------------------------------
+	Real TextureUnitState::getTextureUScroll(void) const
+    {
+		return mUMod;
+    }
+
+	//-----------------------------------------------------------------------
+	Real TextureUnitState::getTextureVScroll(void) const
+    {
+		return mVMod;
+    }
+
+	//-----------------------------------------------------------------------
+	Real TextureUnitState::getTextureUScale(void) const
+    {
+		return mUScale;
+    }
+
+	//-----------------------------------------------------------------------
+	Real TextureUnitState::getTextureVScale(void) const
+    {
+		return mVScale;
+    }
+
+	//-----------------------------------------------------------------------
+	const Radian& TextureUnitState::getTextureRotate(void) const
+    {
+		return mRotate;
+    }
+	
+	//-----------------------------------------------------------------------
+	Real TextureUnitState::getAnimationDuration(void) const
+	{
+		return mAnimDuration;
+	}
+
+	//-----------------------------------------------------------------------
+	const TextureUnitState::EffectMap& TextureUnitState::getEffects(void) const
+	{
+		return mEffects;
+	}
+
+	//-----------------------------------------------------------------------
+	void TextureUnitState::setTextureFiltering(TextureFilterOptions filterType)
+	{
+        switch (filterType)
+        {
+        case TFO_NONE:
+            setTextureFiltering(FO_POINT, FO_POINT, FO_NONE);
+            break;
+        case TFO_BILINEAR:
+            setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_POINT);
+            break;
+        case TFO_TRILINEAR:
+            setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_LINEAR);
+            break;
+        case TFO_ANISOTROPIC:
+            setTextureFiltering(FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR);
+            break;
+        }
+        mIsDefaultFiltering = false;
+	}
+	//-----------------------------------------------------------------------
+    void TextureUnitState::setTextureFiltering(FilterType ft, FilterOptions fo)
+    {
+        switch (ft)
+        {
+        case FT_MIN:
+            mMinFilter = fo;
+            break;
+        case FT_MAG:
+            mMagFilter = fo;
+            break;
+        case FT_MIP:
+            mMipFilter = fo;
+            break;
+        }
+        mIsDefaultFiltering = false;
+    }
+	//-----------------------------------------------------------------------
+    void TextureUnitState::setTextureFiltering(FilterOptions minFilter, 
+        FilterOptions magFilter, FilterOptions mipFilter)
+    {
+        mMinFilter = minFilter;
+        mMagFilter = magFilter;
+        mMipFilter = mipFilter;
+        mIsDefaultFiltering = false;
+    }
+	//-----------------------------------------------------------------------
+	FilterOptions TextureUnitState::getTextureFiltering(FilterType ft) const
+	{
+        switch (ft)
+        {
+        case FT_MIN:
+            return mMinFilter;
+        case FT_MAG:
+            return mMagFilter;
+        case FT_MIP:
+            return mMipFilter;
+        }
+		// to keep compiler happy
+		return mMinFilter;
+	}
+
+	//-----------------------------------------------------------------------
+	void TextureUnitState::setTextureAnisotropy(unsigned int maxAniso)
+	{
+		mMaxAniso = maxAniso;
+        mIsDefaultAniso = false;
+	}
+	//-----------------------------------------------------------------------
+	unsigned int TextureUnitState::getTextureAnisotropy() const
+	{
+        return mMaxAniso;
+	}
+
+	//-----------------------------------------------------------------------
+    void TextureUnitState::_unprepare(void)
+    {
+        // Unreference textures
+        vector<TexturePtr>::type::iterator ti, tiend;
+        tiend = mFramePtrs.end();
+        for (ti = mFramePtrs.begin(); ti != tiend; ++ti)
+        {
+            ti->setNull();
+        }
+    }
+	//-----------------------------------------------------------------------
+    void TextureUnitState::_unload(void)
+    {
+        // Unreference but don't unload textures. may be used elsewhere
+        vector<TexturePtr>::type::iterator ti, tiend;
+        tiend = mFramePtrs.end();
+        for (ti = mFramePtrs.begin(); ti != tiend; ++ti)
+        {
+            ti->setNull();
+        }
+    }
+    //-----------------------------------------------------------------------------
+    bool TextureUnitState::isLoaded(void) const
+    {
+        return true;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::_notifyNeedsRecompile(void)
+    {
+
+    }
+    //-----------------------------------------------------------------------
+    bool TextureUnitState::hasViewRelativeTextureCoordinateGeneration(void) const
+    {
+        // Right now this only returns true for reflection maps
+
+        EffectMap::const_iterator i, iend;
+        iend = mEffects.end();
+        
+        for(i = mEffects.find(ET_ENVIRONMENT_MAP); i != iend; ++i)
+        {
+            if (i->second.subtype == ENV_REFLECTION)
+                return true;
+        }
+        for(i = mEffects.find(ET_PROJECTIVE_TEXTURE); i != iend; ++i)
+        {
+            return true;
+        }
+
+        return false;
+    }
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setName(const String& name)
+    {
+        mName = name;
+		if (mTextureNameAlias.empty())
+			mTextureNameAlias = mName;
+    }
+
+    //-----------------------------------------------------------------------
+    void TextureUnitState::setTextureNameAlias(const String& name)
+    {
+        mTextureNameAlias = name;
+    }
+
+    //-----------------------------------------------------------------------
+    bool TextureUnitState::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply)
+    {
+        bool testResult = false;
+        // if TUS has an alias see if its in the alias container
+        if (!mTextureNameAlias.empty())
+        {
+            AliasTextureNamePairList::const_iterator aliasEntry =
+                aliasList.find(mTextureNameAlias);
+
+            if (aliasEntry != aliasList.end())
+            {
+                // match was found so change the texture name in mFrames
+                testResult = true;
+
+                if (apply)
+                {
+                    // currently assumes animated frames are sequentially numbered
+                    // cubic, 1d, 2d, and 3d textures are determined from current TUS state
+                    
+                    // if cubic or 3D
+                    if (mCubic)
+                    {
+                        setCubicTextureName(aliasEntry->second, mTextureType == TEX_TYPE_CUBE_MAP);
+                    }
+                    else
+                    {
+                        // if more than one frame then assume animated frames
+                        if (mFrames.size() > 1)
+                            setAnimatedTextureName(aliasEntry->second, 
+								static_cast<unsigned int>(mFrames.size()), mAnimDuration);
+                        else
+                            setTextureName(aliasEntry->second, mTextureType);
+                    }
+                }
+                
+            }
+        }
+
+        return testResult;
+    }
+	//-----------------------------------------------------------------------------
+	void TextureUnitState::_notifyParent(Pass* parent)
+	{
+		mParent = parent;
+	}
+	//-----------------------------------------------------------------------------
+	void TextureUnitState::setCompositorReference(const String& compositorName, const String& textureName, size_t mrtIndex)
+	{  
+		mCompositorRefName = compositorName; 
+		mCompositorRefTexName = textureName; 
+		mCompositorRefMrtIndex = mrtIndex; 
+	}
+}

+ 1088 - 0
CamelotRenderer/OgreTextureUnitState.h

@@ -0,0 +1,1088 @@
+/*
+-----------------------------------------------------------------------------
+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 __TextureUnitState_H__
+#define __TextureUnitState_H__
+
+#include "OgrePrerequisites.h"
+#include "OgreCommon.h"
+#include "OgreBlendMode.h"
+#include "OgreMatrix4.h"
+#include "OgreString.h"
+#include "OgrePixelFormat.h"
+#include "OgreTexture.h"
+
+namespace Ogre {
+	/** \addtogroup Core
+	*  @{
+	*/
+	/** \addtogroup Materials
+	*  @{
+	*/
+	/** Class representing the state of a single texture unit during a Pass of a
+        Technique, of a Material.
+    @remarks
+        Texture units are pipelines for retrieving texture data for rendering onto
+        your objects in the world. Using them is common to both the fixed-function and 
+        the programmable (vertex and fragment program) pipeline, but some of the 
+        settings will only have an effect in the fixed-function pipeline (for example, 
+        setting a texture rotation will have no effect if you use the programmable
+        pipeline, because this is overridden by the fragment program). The effect
+        of each setting as regards the 2 pipelines is commented in each setting.
+    @par
+        When I use the term 'fixed-function pipeline' I mean traditional rendering
+        where you do not use vertex or fragment programs (shaders). Programmable 
+        pipeline means that for this pass you are using vertex or fragment programs.
+    */
+	class _OgreExport TextureUnitState
+    {
+        friend class RenderSystem;
+    public:
+        /** Definition of the broad types of texture effect you can apply to a texture unit.
+        @note
+            Note that these have no effect when using the programmable pipeline, since their
+            effect is overridden by the vertex / fragment programs.
+        */
+        enum TextureEffectType
+        {
+            /// Generate all texture coords based on angle between camera and vertex
+            ET_ENVIRONMENT_MAP,
+            /// Generate texture coords based on a frustum
+            ET_PROJECTIVE_TEXTURE,
+            /// Constant u/v scrolling effect
+            ET_UVSCROLL,
+			/// Constant u scrolling effect
+            ET_USCROLL,
+			/// Constant u/v scrolling effect
+            ET_VSCROLL,
+            /// Constant rotation
+            ET_ROTATE,
+            /// More complex transform
+            ET_TRANSFORM
+
+        };
+
+        /** Enumeration to specify type of envmap.
+        @note
+            Note that these have no effect when using the programmable pipeline, since their
+            effect is overridden by the vertex / fragment programs.
+        */
+        enum EnvMapType
+        {
+            /// Envmap based on vector from camera to vertex position, good for planar geometry
+            ENV_PLANAR,
+            /// Envmap based on dot of vector from camera to vertex and vertex normal, good for curves
+            ENV_CURVED,
+            /// Envmap intended to supply reflection vectors for cube mapping
+            ENV_REFLECTION,
+            /// Envmap intended to supply normal vectors for cube mapping
+            ENV_NORMAL
+        };
+
+        /** Useful enumeration when dealing with procedural transforms.
+        @note
+            Note that these have no effect when using the programmable pipeline, since their
+            effect is overridden by the vertex / fragment programs.
+        */
+        enum TextureTransformType
+        {
+            TT_TRANSLATE_U,
+            TT_TRANSLATE_V,
+            TT_SCALE_U,
+            TT_SCALE_V,
+            TT_ROTATE
+        };
+
+        /** Texture addressing modes - default is TAM_WRAP.
+        @note
+            These settings are relevant in both the fixed-function and the
+            programmable pipeline.
+        */
+        enum TextureAddressingMode
+        {
+            /// Texture wraps at values over 1.0
+            TAM_WRAP,
+            /// Texture mirrors (flips) at joins over 1.0
+            TAM_MIRROR,
+            /// Texture clamps at 1.0
+            TAM_CLAMP,
+            /// Texture coordinates outside the range [0.0, 1.0] are set to the border colour
+            TAM_BORDER
+        };
+
+		/** Texture addressing mode for each texture coordinate. */
+		struct UVWAddressingMode
+		{
+			TextureAddressingMode u, v, w;
+		};
+
+        /** Enum identifying the frame indexes for faces of a cube map (not the composite 3D type.
+        */
+        enum TextureCubeFace
+        {
+            CUBE_FRONT = 0,
+            CUBE_BACK = 1,
+            CUBE_LEFT = 2,
+            CUBE_RIGHT = 3,
+            CUBE_UP = 4,
+            CUBE_DOWN = 5
+        };
+
+        /** Internal structure defining a texture effect.
+        */
+        struct TextureEffect {
+            TextureEffectType type;
+            int subtype;
+            Real arg1, arg2;
+            WaveformType waveType;
+            Real base;
+            Real frequency;
+            Real phase;
+            Real amplitude;
+            Controller<Real>* controller;
+            const Frustum* frustum;
+        };
+
+        /** Texture effects in a multimap paired array
+        */
+        typedef multimap<TextureEffectType, TextureEffect>::type EffectMap;
+
+        /** Default constructor.
+        */
+        TextureUnitState(Pass* parent);
+
+        TextureUnitState(Pass* parent, const TextureUnitState& oth );
+
+        TextureUnitState & operator = ( const TextureUnitState& oth );
+
+        /** Default destructor.
+        */
+        ~TextureUnitState();
+
+        /** Name-based constructor.
+        @param
+        name The basic name of the texture e.g. brickwall.jpg, stonefloor.png
+        @param
+        texCoordSet The index of the texture coordinate set to use.
+        */
+		TextureUnitState( Pass* parent, const String& texName, unsigned int texCoordSet = 0);
+
+        /** Get the name of current texture image for this layer.
+        @remarks
+        This will either always be a single name for this layer,
+        or will be the name of the current frame for an animated
+        or otherwise multi-frame texture.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        const String& getTextureName(void) const;
+
+        /** Sets this texture layer to use a single texture, given the
+        name of the texture to use on this layer.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        void setTextureName( const String& name, TextureType ttype = TEX_TYPE_2D);
+
+		/** Sets this texture layer to use a combination of 6 texture maps, each one relating to a face of a cube.
+        @remarks
+        Cubic textures are made up of 6 separate texture images. Each one of these is an orthoganal view of the
+        world with a FOV of 90 degrees and an aspect ratio of 1:1. You can generate these from 3D Studio by
+        rendering a scene to a reflection map of a transparent cube and saving the output files.
+        @par
+        Cubic maps can be used either for skyboxes (complete wrap-around skies, like space) or as environment
+        maps to simulate reflections. The system deals with these 2 scenarios in different ways:
+        <ol>
+        <li>
+        <p>
+        for cubic environment maps, the 6 textures are combined into a single 'cubic' texture map which
+        is then addressed using 3D texture coordinates. This is required because you don't know what
+        face of the box you're going to need to address when you render an object, and typically you
+        need to reflect more than one face on the one object, so all 6 textures are needed to be
+        'active' at once. Cubic environment maps are enabled by calling this method with the forUVW
+        parameter set to true, and then calling setEnvironmentMap(true).
+        </p>
+        <p>
+        Note that not all cards support cubic environment mapping.
+        </p>
+        </li>
+        <li>
+        <p>
+        for skyboxes, the 6 textures are kept separate and used independently for each face of the skybox.
+        This is done because not all cards support 3D cubic maps and skyboxes do not need to use 3D
+        texture coordinates so it is simpler to render each face of the box with 2D coordinates, changing
+        texture between faces.
+        </p>
+        <p>
+        Skyboxes are created by calling SceneManager::setSkyBox.
+        </p>
+        </li>
+        </ul>
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        @param
+        name The basic name of the texture e.g. brickwall.jpg, stonefloor.png. There must be 6 versions
+        of this texture with the suffixes _fr, _bk, _up, _dn, _lf, and _rt (before the extension) which
+        make up the 6 sides of the box. The textures must all be the same size and be powers of 2 in width & height.
+        If you can't make your texture names conform to this, use the alternative method of the same name which takes
+        an array of texture names instead.
+        @param
+        forUVW Set to true if you want a single 3D texture addressable with 3D texture coordinates rather than
+        6 separate textures. Useful for cubic environment mapping.
+        */
+        void setCubicTextureName( const String& name, bool forUVW = false );
+
+        /** Sets this texture layer to use a combination of 6 texture maps, each one relating to a face of a cube.
+        @remarks
+        Cubic textures are made up of 6 separate texture images. Each one of these is an orthoganal view of the
+        world with a FOV of 90 degrees and an aspect ratio of 1:1. You can generate these from 3D Studio by
+        rendering a scene to a reflection map of a transparent cube and saving the output files.
+        @par
+        Cubic maps can be used either for skyboxes (complete wrap-around skies, like space) or as environment
+        maps to simulate reflections. The system deals with these 2 scenarios in different ways:
+        <ol>
+        <li>
+        <p>
+        for cubic environment maps, the 6 textures are combined into a single 'cubic' texture map which
+        is then addressed using 3D texture coordinates. This is required because you don't know what
+        face of the box you're going to need to address when you render an object, and typically you
+        need to reflect more than one face on the one object, so all 6 textures are needed to be
+        'active' at once. Cubic environment maps are enabled by calling this method with the forUVW
+        parameter set to true, and then calling setEnvironmentMap(true).
+        </p>
+        <p>
+        Note that not all cards support cubic environment mapping.
+        </p>
+        </li>
+        <li>
+        <p>
+        for skyboxes, the 6 textures are kept separate and used independently for each face of the skybox.
+        This is done because not all cards support 3D cubic maps and skyboxes do not need to use 3D
+        texture coordinates so it is simpler to render each face of the box with 2D coordinates, changing
+        texture between faces.
+        </p>
+        <p>
+        Skyboxes are created by calling SceneManager::setSkyBox.
+        </p>
+        </li>
+        </ul>
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        @param
+        name The basic name of the texture e.g. brickwall.jpg, stonefloor.png. There must be 6 versions
+        of this texture with the suffixes _fr, _bk, _up, _dn, _lf, and _rt (before the extension) which
+        make up the 6 sides of the box. The textures must all be the same size and be powers of 2 in width & height.
+        If you can't make your texture names conform to this, use the alternative method of the same name which takes
+        an array of texture names instead.
+        @param
+        forUVW Set to true if you want a single 3D texture addressable with 3D texture coordinates rather than
+        6 separate textures. Useful for cubic environment mapping.
+        */
+        void setCubicTextureName( const String* const names, bool forUVW = false );
+
+        /** Sets the names of the texture images for an animated texture.
+        @remarks
+        Animated textures are just a series of images making up the frames of the animation. All the images
+        must be the same size, and their names must have a frame number appended before the extension, e.g.
+        if you specify a name of "wall.jpg" with 3 frames, the image names must be "wall_0.jpg", "wall_1.jpg"
+        and "wall_2.jpg".
+        @par
+        You can change the active frame on a texture layer by calling the setCurrentFrame method.
+        @note
+        If you can't make your texture images conform to the naming standard layed out here, you
+        can call the alternative setAnimatedTextureName method which takes an array of names instead.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        @param
+        name The base name of the textures to use e.g. wall.jpg for frames wall_0.jpg, wall_1.jpg etc.
+        @param
+        numFrames The number of frames in the sequence.
+        @param
+        duration The length of time it takes to display the whole animation sequence, in seconds.
+        If 0, no automatic transition occurs.
+        */
+        void setAnimatedTextureName( const String& name, unsigned int numFrames, Real duration = 0 );
+
+        /** Sets the names of the texture images for an animated texture.
+        @remarks
+        This an alternative method to the one where you specify a single name and let the system derive
+        the names of each frame, incase your images can't conform to this naming standard.
+        @par
+        Animated textures are just a series of images making up the frames of the animation. All the images
+        must be the same size, and you must provide their names as an array in the first parameter.
+        You can change the active frame on a texture layer by calling the setCurrentFrame method.
+        @note
+        If you can make your texture images conform to a naming standard of basicName_frame.ext, you
+        can call the alternative setAnimatedTextureName method which just takes a base name instead.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        @param
+        names Pointer to array of names of the textures to use, in frame order.
+        @param
+        numFrames The number of frames in the sequence.
+        @param
+        duration The length of time it takes to display the whole animation sequence, in seconds.
+        If 0, no automatic transition occurs.
+        */
+        void setAnimatedTextureName( const String* const names, unsigned int numFrames, Real duration = 0 );
+
+        /** Returns the width and height of the texture in the given frame.
+        */
+        std::pair< size_t, size_t > getTextureDimensions( unsigned int frame = 0 ) const;
+
+        /** Changes the active frame in an animated or multi-image texture.
+        @remarks
+        An animated texture (or a cubic texture where the images are not combined for 3D use) is made up of
+        a number of frames. This method sets the active frame.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        void setCurrentFrame( unsigned int frameNumber );
+
+        /** Gets the active frame in an animated or multi-image texture layer.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        unsigned int getCurrentFrame(void) const;
+
+        /** Gets the name of the texture associated with a frame number.
+            Throws an exception if frameNumber exceeds the number of stored frames.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        const String& getFrameTextureName(unsigned int frameNumber) const;
+
+        /** Sets the name of the texture associated with a frame.
+        @param name The name of the texture
+        @param frameNumber The frame the texture name is to be placed in
+        @note
+        Throws an exception if frameNumber exceeds the number of stored frames.
+        Applies to both fixed-function and programmable pipeline.
+        */
+        void setFrameTextureName(const String& name, unsigned int frameNumber);
+
+        /** Add a Texture name to the end of the frame container.
+        @param name The name of the texture
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        void addFrameTextureName(const String& name);
+        /** deletes a specific texture frame.  The texture used is not deleted but the
+            texture will no longer be used by the Texture Unit.  An exception is raised
+            if the frame number exceeds the number of actual frames.
+        @param frameNumber The frame number of the texture to be deleted.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        void deleteFrameTextureName(const size_t frameNumber);
+        /** Gets the number of frames for a texture.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        unsigned int getNumFrames(void) const;
+
+
+		/** The type of unit to bind the texture settings to. */
+		enum BindingType
+		{
+			/** Regular fragment processing unit - the default. */
+			BT_FRAGMENT = 0,
+			/** Vertex processing unit - indicates this unit will be used for 
+				a vertex texture fetch.
+			*/
+			BT_VERTEX = 1
+		};
+		/** Enum identifying the type of content this texture unit contains.
+		*/
+		enum ContentType
+		{
+			/// Normal texture identified by name
+			CONTENT_NAMED = 0,
+			/// A shadow texture, automatically bound by engine
+			CONTENT_SHADOW = 1,
+			/// A compositor texture, automatically linked to active viewport's chain
+			CONTENT_COMPOSITOR = 2
+		};
+
+		/** Sets the type of unit these texture settings should be bound to. 
+		@remarks
+			Some render systems, when implementing vertex texture fetch, separate
+			the binding of textures for use in the vertex program versus those
+			used in fragment programs. This setting allows you to target the
+			vertex processing unit with a texture binding, in those cases. For
+			rendersystems which have a unified binding for the vertex and fragment
+			units, this setting makes no difference.
+		*/
+		void setBindingType(BindingType bt);
+
+		/** Gets the type of unit these texture settings should be bound to.  
+		*/
+		BindingType getBindingType(void) const;
+
+		/** Set the type of content this TextureUnitState references.
+		@remarks
+			The default is to reference a standard named texture, but this unit
+			can also reference automated content like a shadow texture.
+		*/
+		void setContentType(ContentType ct);
+		/** Get the type of content this TextureUnitState references. */
+		ContentType getContentType(void) const;
+
+        /** Returns true if this texture unit is either a series of 6 2D textures, each
+            in it's own frame, or is a full 3D cube map. You can tell which by checking
+            getTextureType.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        bool isCubic(void) const;
+
+        /** Returns true if this texture layer uses a composite 3D cubic texture.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        bool is3D(void) const;
+
+        /** Returns the type of this texture.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        TextureType getTextureType(void) const;
+
+        /** Sets the desired pixel format when load the texture.
+        */
+        void setDesiredFormat(PixelFormat desiredFormat);
+
+        /** Gets the desired pixel format when load the texture.
+        */
+        PixelFormat getDesiredFormat(void) const;
+
+        /** Sets how many mipmaps have been requested for the texture.
+		*/
+        void setNumMipmaps(int numMipmaps);
+
+        /** Gets how many mipmaps have been requested for the texture.
+		*/
+        int getNumMipmaps(void) const;
+
+		/** Sets whether this texture is requested to be loaded as alpha if single channel
+		*/
+        void setIsAlpha(bool isAlpha);
+
+		/** Gets whether this texture is requested to be loaded as alpha if single channel
+		*/
+        bool getIsAlpha(void) const;
+
+		/// @copydoc Texture::setHardwareGammaEnabled
+		void setHardwareGammaEnabled(bool enabled);
+		/// @copydoc Texture::isHardwareGammaEnabled
+		bool isHardwareGammaEnabled() const;
+
+        /** Gets the index of the set of texture co-ords this layer uses.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        unsigned int getTextureCoordSet(void) const;
+
+        /** Sets the index of the set of texture co-ords this layer uses.
+        @note
+        Default is 0 for all layers. Only change this if you have provided multiple texture co-ords per
+        vertex.
+        @note
+        Applies to both fixed-function and programmable pipeline.
+        */
+        void setTextureCoordSet(unsigned int set);
+
+        /** Sets a matrix used to transform any texture coordinates on this layer.
+        @remarks
+        Texture coordinates can be modified on a texture layer to create effects like scrolling
+        textures. A texture transform can either be applied to a layer which takes the source coordinates
+        from a fixed set in the geometry, or to one which generates them dynamically (e.g. environment mapping).
+        @par
+        It's obviously a bit impractical to create scrolling effects by calling this method manually since you
+        would have to call it every framw with a slight alteration each time, which is tedious. Instead
+        you can use the ControllerManager class to create a Controller object which will manage the
+        effect over time for you. See the ControllerManager::createTextureScroller and it's sibling methods for details.<BR>
+        In addition, if you want to set the individual texture transformations rather than concatenating them
+        yourself, use setTextureScroll, setTextureScale and setTextureRotate.
+        @note
+        Has no effect in the programmable pipeline.
+        */
+        void setTextureTransform(const Matrix4& xform);
+
+        /** Gets the current texture transformation matrix.
+        @remarks
+        Causes a reclaculation of the matrix if any parameters have been changed via
+        setTextureScroll, setTextureScale and setTextureRotate.
+        @note
+        Has no effect in the programmable pipeline.
+        */
+        const Matrix4& getTextureTransform(void) const;
+
+        /** Sets the translation offset of the texture, ie scrolls the texture.
+        @remarks
+        This method sets the translation element of the texture transformation, and is easier to use than setTextureTransform if
+        you are combining translation, scaling and rotation in your texture transformation. Again if you want
+        to animate these values you need to use a Controller
+        @note
+        Has no effect in the programmable pipeline.
+        @param u The amount the texture should be moved horizontally (u direction).
+        @param v The amount the texture should be moved vertically (v direction).
+        @see
+        ControllerManager, Controller
+        */
+        void setTextureScroll(Real u, Real v);
+
+        /** As setTextureScroll, but sets only U value.
+        @note
+        Has no effect in the programmable pipeline.
+        */
+        void setTextureUScroll(Real value);
+        // get texture uscroll value
+        Real getTextureUScroll(void) const;
+
+        /** As setTextureScroll, but sets only V value.
+        @note
+        Has no effect in the programmable pipeline.
+        */
+        void setTextureVScroll(Real value);
+        // get texture vscroll value
+        Real getTextureVScroll(void) const;
+
+        /** As setTextureScale, but sets only U value.
+        @note
+        Has no effect in the programmable pipeline.
+        */
+        void setTextureUScale(Real value);
+        // get texture uscale value
+        Real getTextureUScale(void) const;
+
+        /** As setTextureScale, but sets only V value.
+        @note
+        Has no effect in the programmable pipeline.
+        */
+        void setTextureVScale(Real value);
+        // get texture vscale value
+        Real getTextureVScale(void) const;
+
+        /** Sets the scaling factor applied to texture coordinates.
+        @remarks
+        This method sets the scale element of the texture transformation, and is easier to use than
+        setTextureTransform if you are combining translation, scaling and rotation in your texture transformation. Again if you want
+        to animate these values you need to use a Controller (see ControllerManager and it's methods for
+        more information).
+        @note
+        Has no effect in the programmable pipeline.
+        @param
+        uScale The value by which the texture is to be scaled horizontally.
+        @param
+        vScale The value by which the texture is to be scaled vertically.
+        */
+        void setTextureScale(Real uScale, Real vScale);
+
+        /** Sets the anticlockwise rotation factor applied to texture coordinates.
+        @remarks
+        This sets a fixed rotation angle - if you wish to animate this, see the
+        ControllerManager::createTextureRotater method.
+        @note
+        Has no effect in the programmable pipeline.
+        @param
+        angle The angle of rotation (anticlockwise).
+        */
+        void setTextureRotate(const Radian& angle);
+        // get texture rotation effects angle value
+        const Radian& getTextureRotate(void) const;
+
+        /** Gets the texture addressing mode for a given coordinate, 
+		 	i.e. what happens at uv values above 1.0.
+        @note
+        	The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
+        */
+        const UVWAddressingMode& getTextureAddressingMode(void) const;
+
+        /** Sets the texture addressing mode, i.e. what happens at uv values above 1.0.
+        @note
+        The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
+		@note This is a shortcut method which sets the addressing mode for all
+			coordinates at once; you can also call the more specific method
+			to set the addressing mode per coordinate.
+        @note
+        This applies for both the fixed-function and programmable pipelines.
+        */
+        void setTextureAddressingMode( TextureAddressingMode tam);
+
+        /** Sets the texture addressing mode, i.e. what happens at uv values above 1.0.
+        @note
+        The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
+        @note
+        This applies for both the fixed-function and programmable pipelines.
+		*/
+        void setTextureAddressingMode( TextureAddressingMode u, 
+			TextureAddressingMode v, TextureAddressingMode w);
+
+        /** Sets the texture addressing mode, i.e. what happens at uv values above 1.0.
+        @note
+        The default is TAM_WRAP i.e. the texture repeats over values of 1.0.
+        @note
+        This applies for both the fixed-function and programmable pipelines.
+		*/
+        void setTextureAddressingMode( const UVWAddressingMode& uvw);
+
+        /** Sets the texture border colour.
+        @note
+            The default is ColourValue::Black, and this value only used when addressing mode
+            is TAM_BORDER.
+        @note
+            This applies for both the fixed-function and programmable pipelines.
+		*/
+        void setTextureBorderColour(const ColourValue& colour);
+
+        /** Sets the texture border colour.
+        @note
+            The default is ColourValue::Black, and this value only used when addressing mode
+            is TAM_BORDER.
+		*/
+        const ColourValue& getTextureBorderColour(void) const;
+
+		/** Setting advanced blending options.
+        @remarks
+        This is an extended version of the TextureUnitState::setColourOperation method which allows
+        extremely detailed control over the blending applied between this and earlier layers.
+        See the IMPORTANT note below about the issues between mulitpass and multitexturing that
+        using this method can create.
+        @par
+        Texture colour operations determine how the final colour of the surface appears when
+        rendered. Texture units are used to combine colour values from various sources (ie. the
+        diffuse colour of the surface from lighting calculations, combined with the colour of
+        the texture). This method allows you to specify the 'operation' to be used, ie. the
+        calculation such as adds or multiplies, and which values to use as arguments, such as
+        a fixed value or a value from a previous calculation.
+        @par
+        The defaults for each layer are:
+        <ul>
+        <li>op = LBX_MODULATE</li>
+        <li>source1 = LBS_TEXTURE</li>
+        <li>source2 = LBS_CURRENT</li>
+        </ul>
+        ie. each layer takes the colour results of the previous layer, and multiplies them
+        with the new texture being applied. Bear in mind that colours are RGB values from
+        0.0 - 1.0 so multiplying them together will result in values in the same range,
+        'tinted' by the multiply. Note however that a straight multiply normally has the
+        effect of darkening the textures - for this reason there are brightening operations
+        like LBO_MODULATE_X2. See the LayerBlendOperation and LayerBlendSource enumerated
+        types for full details.
+        @note
+        Because of the limitations on some underlying APIs (Direct3D included)
+        the LBS_TEXTURE argument can only be used as the first argument, not the second.
+        @par
+        The final 3 parameters are only required if you decide to pass values manually
+        into the operation, i.e. you want one or more of the inputs to the colour calculation
+        to come from a fixed value that you supply. Hence you only need to fill these in if
+        you supply LBS_MANUAL to the corresponding source, or use the LBX_BLEND_MANUAL
+        operation.
+        @warning
+        Ogre tries to use multitexturing hardware to blend texture layers
+        together. However, if it runs out of texturing units (e.g. 2 of a GeForce2, 4 on a
+        GeForce3) it has to fall back on multipass rendering, i.e. rendering the same object
+        multiple times with different textures. This is both less efficient and there is a smaller
+        range of blending operations which can be performed. For this reason, if you use this method
+        you MUST also call TextureUnitState::setColourOpMultipassFallback to specify which effect you
+        want to fall back on if sufficient hardware is not available.
+        @note
+        This has no effect in the programmable pipeline.
+        @param
+        If you wish to avoid having to do this, use the simpler TextureUnitState::setColourOperation method
+        which allows less flexible blending options but sets up the multipass fallback automatically,
+        since it only allows operations which have direct multipass equivalents.
+        @param
+        op The operation to be used, e.g. modulate (multiply), add, subtract
+        @param
+        source1 The source of the first colour to the operation e.g. texture colour
+        @param
+        source2 The source of the second colour to the operation e.g. current surface colour
+        @param
+        arg1 Manually supplied colour value (only required if source1 = LBS_MANUAL)
+        @param
+        arg2 Manually supplied colour value (only required if source2 = LBS_MANUAL)
+        @param
+        manualBlend Manually supplied 'blend' value - only required for operations
+        which require manual blend e.g. LBX_BLEND_MANUAL
+        */
+        void setColourOperationEx(
+            LayerBlendOperationEx op,
+            LayerBlendSource source1 = LBS_TEXTURE,
+            LayerBlendSource source2 = LBS_CURRENT,
+
+            const ColourValue& arg1 = ColourValue::White,
+            const ColourValue& arg2 = ColourValue::White,
+
+            Real manualBlend = 0.0);
+
+        /** Determines how this texture layer is combined with the one below it (or the diffuse colour of
+        the geometry if this is layer 0).
+        @remarks
+        This method is the simplest way to blend tetxure layers, because it requires only one parameter,
+        gives you the most common blending types, and automatically sets up 2 blending methods: one for
+        if single-pass multitexturing hardware is available, and another for if it is not and the blending must
+        be achieved through multiple rendering passes. It is, however, quite limited and does not expose
+        the more flexible multitexturing operations, simply because these can't be automatically supported in
+        multipass fallback mode. If want to use the fancier options, use TextureUnitState::setColourOperationEx,
+        but you'll either have to be sure that enough multitexturing units will be available, or you should
+        explicitly set a fallback using TextureUnitState::setColourOpMultipassFallback.
+        @note
+        The default method is LBO_MODULATE for all layers.
+        @note
+        This option has no effect in the programmable pipeline.
+        @param
+        op One of the LayerBlendOperation enumerated blending types.
+        */
+        void setColourOperation( const LayerBlendOperation op);
+
+        /** Sets the multipass fallback operation for this layer, if you used TextureUnitState::setColourOperationEx
+        and not enough multitexturing hardware is available.
+        @remarks
+        Because some effects exposed using TextureUnitState::setColourOperationEx are only supported under
+        multitexturing hardware, if the hardware is lacking the system must fallback on multipass rendering,
+        which unfortunately doesn't support as many effects. This method is for you to specify the fallback
+        operation which most suits you.
+        @par
+        You'll notice that the interface is the same as the Material::setSceneBlending method; this is
+        because multipass rendering IS effectively scene blending, since each layer is rendered on top
+        of the last using the same mechanism as making an object transparent, it's just being rendered
+        in the same place repeatedly to get the multitexture effect.
+        @par
+        If you use the simpler (and hence less flexible) TextureUnitState::setColourOperation method you
+        don't need to call this as the system sets up the fallback for you.
+        @note
+        This option has no effect in the programmable pipeline, because there is no multipass fallback
+        and multitexture blending is handled by the fragment shader.
+        */
+        void setColourOpMultipassFallback( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor);
+
+        /** Get multitexturing colour blending mode.
+        */
+        const LayerBlendModeEx& getColourBlendMode(void) const;
+
+        /** Get multitexturing alpha blending mode.
+        */
+        const LayerBlendModeEx& getAlphaBlendMode(void) const;
+
+        /** Get the multipass fallback for colour blending operation source factor.
+        */
+        SceneBlendFactor getColourBlendFallbackSrc(void) const;
+
+        /** Get the multipass fallback for colour blending operation destination factor.
+        */
+        SceneBlendFactor getColourBlendFallbackDest(void) const;
+
+        /** Sets the alpha operation to be applied to this texture.
+        @remarks
+        This works in exactly the same way as setColourOperation, except
+        that the effect is applied to the level of alpha (i.e. transparency)
+        of the texture rather than its colour. When the alpha of a texel (a pixel
+        on a texture) is 1.0, it is opaque, wheras it is fully transparent if the
+        alpha is 0.0. Please refer to the setColourOperation method for more info.
+        @param
+        op The operation to be used, e.g. modulate (multiply), add, subtract
+        @param
+        source1 The source of the first alpha value to the operation e.g. texture alpha
+        @param
+        source2 The source of the second alpha value to the operation e.g. current surface alpha
+        @param
+        arg1 Manually supplied alpha value (only required if source1 = LBS_MANUAL)
+        @param
+        arg2 Manually supplied alpha value (only required if source2 = LBS_MANUAL)
+        @param
+        manualBlend Manually supplied 'blend' value - only required for operations
+        which require manual blend e.g. LBX_BLEND_MANUAL
+        @see
+        setColourOperation
+        @note
+        This option has no effect in the programmable pipeline.
+        */
+        void setAlphaOperation(LayerBlendOperationEx op,
+            LayerBlendSource source1 = LBS_TEXTURE,
+            LayerBlendSource source2 = LBS_CURRENT,
+            Real arg1 = 1.0,
+            Real arg2 = 1.0,
+            Real manualBlend = 0.0);
+
+        /** Determines if this texture layer is currently blank.
+        @note
+        This can happen if a texture fails to load or some other non-fatal error. Worth checking after
+        setting texture name.
+        */
+        bool isBlank(void) const;
+
+        /** Sets this texture layer to be blank.
+        */
+        void setBlank(void);
+
+		/** Tests if the texture associated with this unit has failed to load.
+		*/
+		bool isTextureLoadFailing() const { return mTextureLoadFailed; }
+
+		/** Tells the unit to retry loading the texture if it had failed to load.
+		*/
+		void retryTextureLoad() { mTextureLoadFailed = false; }
+
+        // get texture effects in a multimap paired array
+        const EffectMap& getEffects(void) const;
+        // get the animated-texture animation duration
+        Real getAnimationDuration(void) const;
+
+        /** Set the texture filtering for this unit, using the simplified interface.
+        @remarks
+            You also have the option of specifying the minification, magnification
+            and mip filter individually if you want more control over filtering
+            options. See the alternative setTextureFiltering methods for details.
+        @note
+        This option applies in both the fixed function and the programmable pipeline.
+        @param filterType The high-level filter type to use.
+        */
+        void setTextureFiltering(TextureFilterOptions filterType);
+        /** Set a single filtering option on this texture unit. 
+        @params ftype The filtering type to set
+        @params opts The filtering option to set
+        */
+        void setTextureFiltering(FilterType ftype, FilterOptions opts);
+        /** Set a the detailed filtering options on this texture unit. 
+        @params minFilter The filtering to use when reducing the size of the texture. 
+            Can be FO_POINT, FO_LINEAR or FO_ANISOTROPIC
+        @params magFilter The filtering to use when increasing the size of the texture
+            Can be FO_POINT, FO_LINEAR or FO_ANISOTROPIC
+        @params mipFilter The filtering to use between mip levels
+            Can be FO_NONE (turns off mipmapping), FO_POINT or FO_LINEAR (trilinear filtering)
+        */
+        void setTextureFiltering(FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter);
+        // get the texture filtering for the given type
+        FilterOptions getTextureFiltering(FilterType ftpye) const;
+
+        /** Sets the anisotropy level to be used for this texture level.
+        @par maxAniso The maximal anisotropy level, should be between 2 and the maximum supported by hardware (1 is the default, ie. no anisotrophy).
+        @note
+        This option applies in both the fixed function and the programmable pipeline.
+        */
+        void setTextureAnisotropy(unsigned int maxAniso);
+        // get this layer texture anisotropy level
+        unsigned int getTextureAnisotropy() const;
+
+		/** Sets the bias value applied to the mipmap calculation.
+		@remarks
+			You can alter the mipmap calculation by biasing the result with a 
+			single floating point value. After the mip level has been calculated,
+			this bias value is added to the result to give the final mip level.
+			Lower mip levels are larger (higher detail), so a negative bias will
+			force the larger mip levels to be used, and a positive bias
+			will cause smaller mip levels to be used. The bias values are in 
+			mip levels, so a -1 bias will force mip levels one larger than by the
+			default calculation.
+		@param bias The bias value as described above, can be positive or negative.
+		*/
+		void setTextureMipmapBias(float bias) { mMipmapBias = bias; }
+		/** Gets the bias value applied to the mipmap calculation.
+		@see TextureUnitState::setTextureMipmapBias
+		*/
+		float getTextureMipmapBias(void) const { return mMipmapBias; }
+
+		/** Set the compositor reference for this texture unit state.
+		@remarks 
+			Only valid when content type is compositor.
+		@param compositorName the name of the compositor to reference
+		@param textureName the name of the texture to reference
+		@param mrtIndex the index of the wanted texture, if referencing an MRT
+		*/
+		void setCompositorReference(const String& compositorName, const String& textureName, size_t mrtIndex = 0);
+
+		/** Gets the name of the compositor that this texture referneces */
+		const String& getReferencedCompositorName() const { return mCompositorRefName; }
+		/** Gets the name of the texture in the compositor that this texture references */
+		const String& getReferencedTextureName() const { return mCompositorRefTexName; }
+		/** Gets the MRT index of the texture in the compositor that this texture references */ 
+		size_t getReferencedMRTIndex() const { return mCompositorRefMrtIndex; }
+	
+        /// Gets the parent Pass object
+        Pass* getParent(void) const { return mParent; }
+
+		/** Internal method for preparing this object for load, as part of Material::prepare*/
+		void _prepare(void);
+		/** Internal method for undoing the preparation this object as part of Material::unprepare*/
+		void _unprepare(void);
+		/** Internal method for loading this object as part of Material::load */
+		void _load(void);
+		/** Internal method for unloading this object as part of Material::unload */
+		void _unload(void);
+        /// Returns whether this unit has texture coordinate generation that depends on the camera
+        bool hasViewRelativeTextureCoordinateGeneration(void) const;
+
+        // Is this loaded?
+        bool isLoaded(void) const;
+        /** Tells the class that it needs recompilation. */
+        void _notifyNeedsRecompile(void);
+
+        /** Set the name of the Texture Unit State
+        @remarks
+            The name of the Texture Unit State is optional.  Its usefull in material scripts where a material could inherit
+            from another material and only want to modify a particalar Texture Unit State.
+        */
+        void setName(const String& name);
+        /// get the name of the Texture Unit State
+        const String& getName(void) const { return mName; }
+
+        /** Set the alias name used for texture frame names
+        @param name can be any sequence of characters and does not have to be unique           
+        */
+        void setTextureNameAlias(const String& name);
+        /** gets the Texture Name Alias of the Texture Unit.
+        */
+        const String& getTextureNameAlias(void) const { return mTextureNameAlias;}
+
+        /** Applies texture names to Texture Unit State with matching texture name aliases.
+            If no matching aliases are found then the TUS state does not change.
+        @remarks
+            Cubic, 1d, 2d, and 3d textures are determined from current state of the Texture Unit.
+            Assumes animated frames are sequentially numbered in the name.
+            If matching texture aliases are found then true is returned.
+
+        @param
+            aliasList is a map container of texture alias, texture name pairs
+        @param
+            apply set true to apply the texture aliases else just test to see if texture alias matches are found.
+        @return
+            True if matching texture aliases were found in the Texture Unit State.
+        */
+        bool applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply = true);
+
+		/** Notify this object that its parent has changed */
+		void _notifyParent(Pass* parent);
+
+		/** Get the texture pointer for the current frame. */
+		const TexturePtr& _getTexturePtr(void) const;
+		/** Get the texture pointer for a given frame. */
+		const TexturePtr& _getTexturePtr(size_t frame) const;
+	
+		/** Set the texture pointer for the current frame (internal use only!). */
+		void _setTexturePtr(const TexturePtr& texptr);
+		/** Set the texture pointer for a given frame (internal use only!). */
+		void _setTexturePtr(const TexturePtr& texptr, size_t frame);
+
+		/** Gets the animation controller (as created because of setAnimatedTexture)
+			if it exists.
+		*/
+		Controller<Real>* _getAnimController() const { return mAnimController; }
+protected:
+        // State
+        /// The current animation frame.
+        unsigned int mCurrentFrame;
+
+        /// Duration of animation in seconds
+        Real mAnimDuration;            
+        bool mCubic; // is this a series of 6 2D textures to make up a cube?
+		
+        TextureType mTextureType; 
+        PixelFormat mDesiredFormat;
+		int mTextureSrcMipmaps; // Request number of mipmaps
+
+        unsigned int mTextureCoordSetIndex;
+        UVWAddressingMode mAddressMode;
+        ColourValue mBorderColour;
+
+        LayerBlendModeEx mColourBlendMode;
+        SceneBlendFactor mColourBlendFallbackSrc;
+        SceneBlendFactor mColourBlendFallbackDest;
+
+        LayerBlendModeEx mAlphaBlendMode;
+        mutable bool mTextureLoadFailed;
+        bool mIsAlpha;
+		bool mHwGamma;
+
+        mutable bool mRecalcTexMatrix;
+        Real mUMod, mVMod;
+        Real mUScale, mVScale;
+        Radian mRotate;
+        mutable Matrix4 mTexModMatrix;
+
+        /// Texture filtering - minification
+        FilterOptions mMinFilter;
+        /// Texture filtering - magnification
+        FilterOptions mMagFilter;
+        /// Texture filtering - mipmapping
+        FilterOptions mMipFilter;
+        ///Texture anisotropy
+        unsigned int mMaxAniso;
+		/// Mipmap bias (always float, not Real)
+		float mMipmapBias;
+
+        bool mIsDefaultAniso;
+        bool mIsDefaultFiltering;
+		/// Binding type (fragment or vertex pipeline)
+		BindingType mBindingType;
+		/// Content type of texture (normal loaded texture, auto-texture)
+		ContentType mContentType;
+		/// The index of the referenced texture if referencing an MRT in a compositor
+		size_t mCompositorRefMrtIndex;
+
+        //-----------------------------------------------------------------------------
+        // Complex members (those that can't be copied using memcpy) are at the end to 
+        // allow for fast copying of the basic members.
+        //
+        vector<String>::type mFrames;
+		mutable vector<TexturePtr>::type mFramePtrs;
+        String mName;               // optional name for the TUS
+        String mTextureNameAlias;       // optional alias for texture frames
+        EffectMap mEffects;
+		///The data that references the compositor
+		String mCompositorRefName;
+		String mCompositorRefTexName;
+        //-----------------------------------------------------------------------------
+
+        //-----------------------------------------------------------------------------
+        // Pointer members (those that can't be copied using memcpy), and MUST
+        // preserving even if assign from others
+        //
+        Pass* mParent;
+        Controller<Real>* mAnimController;
+        //-----------------------------------------------------------------------------
+
+
+        /** Internal method for calculating texture matrix.
+        */
+        void recalcTextureMatrix(void) const;
+
+		/** Internal method for ensuring the texture for a given frame is prepared. */
+		void ensurePrepared(size_t frame) const;
+		/** Internal method for ensuring the texture for a given frame is loaded. */
+		void ensureLoaded(size_t frame) const;
+
+
+    };
+
+	/** @} */
+	/** @} */
+
+}
+
+#endif