Index: trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.cpp
===================================================================
--- trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.cpp	(revision 151)
+++ trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.cpp	(revision 153)
@@ -365,6 +365,6 @@
 	VisibilityTerrainSceneManager *sm = dynamic_cast<VisibilityTerrainSceneManager *>(mSceneMgr);
 
-	//mQueryManager = new ItemBufferQueryManager(sm->GetHierarchyInterface(), mWindow->getViewport(0));
-	mQueryManager = new PlatformQueryManager(sm->GetHierarchyInterface(), mWindow->getViewport(0));
+	mQueryManager = new ItemBufferQueryManager(sm->GetHierarchyInterface(), mWindow->getViewport(0));
+	//mQueryManager = new PlatformQueryManager(sm->GetHierarchyInterface(), mWindow->getViewport(0));
 
 	sm->GetVisibilityManager()->SetQueryManager(mQueryManager);
@@ -443,8 +443,8 @@
 		mQueryTypeInfo->setCaption(str);
 
-		sprintf(str, ": %d", (int)visibleNodes.size()); 
+		sprintf(str, ": %d", (int)nodesSize); 
 		mQueryVisibleNodesInfo->setCaption(str);
 	
-		sprintf(str,": %d", (int)visibleGeometry.size()); 
+		sprintf(str,": %d", (int)geomSize); 
 		mQueryVisibleGeometryInfo->setCaption(str);
 		
Index: trunk/VUT/work/ogre_changes/OgreMain/include/OgreRenderable.h
===================================================================
--- trunk/VUT/work/ogre_changes/OgreMain/include/OgreRenderable.h	(revision 131)
+++ trunk/VUT/work/ogre_changes/OgreMain/include/OgreRenderable.h	(revision 153)
@@ -53,5 +53,5 @@
     {
     public:
-		Renderable() {mId = 0;}
+		Renderable() {mId = -1;}
         /** Virtual destructor needed as class has virtual methods. */
         virtual ~Renderable() { }
Index: trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreOctreeNode.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreOctreeNode.cpp	(revision 141)
+++ trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreOctreeNode.cpp	(revision 153)
@@ -170,5 +170,5 @@
 void OctreeNode::getRenderOperation( RenderOperation& rend )
 {
-	//Node::getRenderOperation(rend);
+#ifdef GTP_VISIBILITY_MODIFED_OGRE
 	/*static SubMesh* pSubMesh = 0;
 
@@ -180,4 +180,6 @@
 	}
 	pSubMesh->_getRenderOperation(rend);*/
+
+	// HACK. render scaled box
 	if (mWireBoundingBox == NULL) 
 	{
@@ -191,4 +193,5 @@
 	mWireBoundingBox->getRenderOperation(rend);
 
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
 
     /* TODO
Index: trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreTerrainPageSource.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreTerrainPageSource.cpp	(revision 139)
+++ 	(revision )
@@ -1,152 +1,0 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-(Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2005 The OGRE Team
-Also see acknowledgements in Readme.html
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU Lesser General Public License as published by the Free Software
-Foundation; either version 2 of the License, or (at your option) any later
-version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place - Suite 330, Boston, MA 02111-1307, USA, or go to
-http://www.gnu.org/copyleft/lesser.txt.
------------------------------------------------------------------------------
-*/
-#include "OgreTerrainPageSource.h"
-#include "OgreTerrainPage.h"
-#include "OgreTerrainRenderable.h"
-#include "OgreSceneNode.h"
-#include "OgreTerrainSceneManager.h"
-#include "OgreLogManager.h"
-
-namespace Ogre {
-
-    //-----------------------------------------------------------------------
-    template<> TerrainPageSourceListenerManager* Singleton<TerrainPageSourceListenerManager>::ms_Singleton = 0;
-    TerrainPageSourceListenerManager* TerrainPageSourceListenerManager::getSingletonPtr(void)
-    {
-        return ms_Singleton;
-    }
-    TerrainPageSourceListenerManager& TerrainPageSourceListenerManager::getSingleton(void)
-    {  
-        assert( ms_Singleton );  return ( *ms_Singleton );  
-    }
-    //-------------------------------------------------------------------------
-	void TerrainPageSourceListenerManager::addListener(TerrainPageSourceListener* pl)
-	{
-        mPageSourceListeners.push_back(pl);
-	}
-    //-------------------------------------------------------------------------
-	void TerrainPageSourceListenerManager::removeListener(TerrainPageSourceListener* pl)
-	{
-        PageSourceListenerList::iterator i, iend;
-        iend = mPageSourceListeners.end();
-        for(i = mPageSourceListeners.begin(); i != iend; ++i)
-        {
-            if (*i == pl)
-            {
-                mPageSourceListeners.erase(i);
-                break;
-            }
-        }
-	}
-    //-------------------------------------------------------------------------
-	void TerrainPageSourceListenerManager::firePageConstructed(size_t pagex, size_t pagez, Real* heightData)
-	{
-        PageSourceListenerList::iterator i, iend;
-        iend = mPageSourceListeners.end();
-        for(i = mPageSourceListeners.begin(); i != iend; ++i)
-        {
-            (*i)->pageConstructed(pagex, pagez, heightData);
-        }
-	}
-	//-------------------------------------------------------------------------
-	TerrainPageSource::TerrainPageSource() : mSceneManager(0), mAsyncLoading(false) {
-	}
-	//-------------------------------------------------------------------------
-	TerrainPage* TerrainPageSource::buildPage(Real* heightData, const MaterialPtr& pMaterial)
-    {
-        String name;
-
-        // Create a Terrain Page
-        TerrainPage* page = new TerrainPage((mPageSize-1) / (mTileSize-1));
-        // Create a node for all tiles to be attached to
-        // Note we sequentially name since page can be attached at different points
-        // so page x/z is not appropriate
-        static size_t pageIndex = 0;
-		StringUtil::StrStreamType page_str;
-		page_str << pageIndex;
-        name = "page[";
-        name += page_str.str() + "]";
-        page->pageSceneNode = mSceneManager->createSceneNode(name);
-        
-        size_t q = 0;
-        for ( size_t j = 0; j < mPageSize - 1; j += ( mTileSize - 1 ) )
-        {
-            size_t p = 0;
-
-            for ( size_t i = 0; i < mPageSize - 1; i += ( mTileSize - 1 ) )
-            {
-				StringUtil::StrStreamType new_name_str;
-				
-                // Create scene node for the tile and the TerrainRenderable
-                new_name_str << "tile[" << pageIndex << "][" << (int)p << "," << (int)q << "]";
-				name = new_name_str.str();
-
-                SceneNode *c = page->pageSceneNode->createChildSceneNode( name );
-				
-                TerrainRenderable *tile = new TerrainRenderable(name);
-				// set queue
-				tile->setRenderQueueGroup(mSceneManager->getWorldGeometryRenderQueue());
-                // Initialise the tile
-				tile->setMaterial(pMaterial);
-				
-                tile->initialise(i, j, heightData);
-                // Attach it to the page
-                page->tiles[ p ][ q ] = tile;
-                // Attach it to the node
-                c ->attachObject( tile );
-                p++;
-			
-            }
-
-            q++;
-
-        }
-
-        pageIndex++;
-
-        // calculate neighbours for page
-        page->linkNeighbours();
-
-        return page;
-    }
-    //-------------------------------------------------------------------------
-    void TerrainPageSource::firePageConstructed(size_t pagex, size_t pagez, Real* heightData)
-    {
-		TerrainPageSourceListenerManager::getSingleton().firePageConstructed(pagex, pagez, heightData);
-    }
-    //-------------------------------------------------------------------------
-    void TerrainPageSource::addListener(TerrainPageSourceListener* pl)
-    {
-		TerrainPageSourceListenerManager::getSingleton().addListener(pl);
-    }
-    //-------------------------------------------------------------------------
-    void TerrainPageSource::removeListener(TerrainPageSourceListener* pl)
-    {
-		TerrainPageSourceListenerManager::getSingleton().removeListener(pl);
-
-    }
-    //-------------------------------------------------------------------------
-
-}
Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreGLTexture.h
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreGLTexture.h	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreGLTexture.h	(revision 153)
@@ -0,0 +1,169 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef __GLTEXTURE_H__
+#define __GLTEXTURE_H__
+
+#include "OgreGLPrerequisites.h"
+#include "OgrePlatform.h"
+#include "OgreRenderTexture.h"
+#include "OgreTexture.h"
+#include "OgreGLSupport.h"
+#include "OgreHardwarePixelBuffer.h"
+
+namespace Ogre {
+
+    class GLTexture : public Texture
+    {
+    public:
+        // Constructor
+        GLTexture(ResourceManager* creator, const String& name, ResourceHandle handle,
+            const String& group, bool isManual, ManualResourceLoader* loader, 
+            GLSupport& support);
+
+        virtual ~GLTexture();      
+
+        /// @copydoc Texture::createInternalResources
+        void createInternalResources(void);
+		void loadImage( const Image& img );
+        void createRenderTexture();
+			
+		/// @copydoc Texture::getBuffer
+		HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap);
+
+        // Takes the OGRE texture type (1d/2d/3d/cube) and returns the appropriate GL one
+        GLenum getGLTextureTarget(void) const;
+
+        GLuint getGLID() const
+        { return mTextureID; }
+
+    protected:
+        /// @copydoc Resource::loadImpl
+        void loadImpl(void);
+        /// @copydoc Resource::unloadImpl
+        void unloadImpl(void);
+
+		/** internal method, create GLHardwarePixelBuffers for every face and
+			 mipmap level. This method must be called after the GL texture object was created,
+			the number of mipmaps was set (GL_TEXTURE_MAX_LEVEL) and glTexImageXD was called to
+			actually allocate the buffer
+		*/
+		void _createSurfaceList();
+    private:
+        GLuint mTextureID;
+        GLSupport& mGLSupport;
+		
+		/// Vector of pointers to subsurfaces
+		typedef std::vector<HardwarePixelBufferSharedPtr> SurfaceList;
+		SurfaceList	mSurfaceList;
+    };
+
+    /** Specialisation of SharedPtr to allow SharedPtr to be assigned to GLTexturePtr 
+    @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 GLTexturePtr : public SharedPtr<GLTexture> 
+    {
+    public:
+        GLTexturePtr() : SharedPtr<GLTexture>() {}
+        explicit GLTexturePtr(GLTexture* rep) : SharedPtr<GLTexture>(rep) {}
+        GLTexturePtr(const GLTexturePtr& r) : SharedPtr<GLTexture>(r) {} 
+        GLTexturePtr(const ResourcePtr& r) : SharedPtr<GLTexture>()
+        {
+			// lock & copy other mutex pointer
+			OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
+			OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
+            pRep = static_cast<GLTexture*>(r.getPointer());
+            pUseCount = r.useCountPointer();
+            if (pUseCount)
+            {
+                ++(*pUseCount);
+            }
+        }
+
+        /// Operator used to convert a ResourcePtr to a GLTexturePtr
+        GLTexturePtr& operator=(const ResourcePtr& r)
+        {
+            if (pRep == static_cast<GLTexture*>(r.getPointer()))
+                return *this;
+            release();
+			// lock & copy other mutex pointer
+			OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
+			OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
+            pRep = static_cast<GLTexture*>(r.getPointer());
+            pUseCount = r.useCountPointer();
+            if (pUseCount)
+            {
+                ++(*pUseCount);
+            }
+            return *this;
+        }
+        /// Operator used to convert a TexturePtr to a GLTexturePtr
+        GLTexturePtr& operator=(const TexturePtr& r)
+        {
+            if (pRep == static_cast<GLTexture*>(r.getPointer()))
+                return *this;
+            release();
+			// lock & copy other mutex pointer
+			OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
+			OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
+            pRep = static_cast<GLTexture*>(r.getPointer());
+            pUseCount = r.useCountPointer();
+            if (pUseCount)
+            {
+                ++(*pUseCount);
+            }
+            return *this;
+        }
+    };
+
+    /// GL implementation of RenderTexture
+    class GLRenderTexture : public RenderTexture
+    {
+    public:
+        GLRenderTexture(const String& name, uint width, uint height, TextureType texType, PixelFormat format,
+			const NameValuePairList *miscParams) 
+            : RenderTexture(name, width, height, texType, format) 
+        {
+            mGLTexture = mTexture;
+        }
+
+        void _copyToTexture(void);
+
+        bool requiresTextureFlipping() const { return true; }
+        virtual void writeContentsToFile( const String & filename );
+
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+		uchar *getBufferContents(int &dimx, int &dimy);
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+
+    protected:
+        GLTexturePtr mGLTexture;
+    };
+}
+
+#endif // __GLTEXTURE_H__
Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreWin32Window.h
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreWin32Window.h	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreWin32Window.h	(revision 153)
@@ -0,0 +1,84 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef __Win32Window_H__
+#define __Win32Window_H__
+
+#include "OgreWin32Prerequisites.h"
+#include "OgreRenderWindow.h"
+
+namespace Ogre {
+    class Win32Window : public RenderWindow
+    {
+    public:
+        Win32Window(Win32GLSupport &glsupport);
+        ~Win32Window();
+
+       void create(const String& name, unsigned int width, unsigned int height,
+	            bool fullScreen, const NameValuePairList *miscParams);
+        void destroy(void);
+        bool isActive(void) const;
+        bool isClosed(void) const;
+        void reposition(int left, int top);
+        void resize(unsigned int width, unsigned int height);
+        void swapBuffers(bool waitForVSync);
+
+        /** Overridden - see RenderTarget.
+        */
+        void writeContentsToFile(const String& filename);
+
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+		uchar *getBufferContents(int &dimx, int &dimy);
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+
+		bool requiresTextureFlipping() const { return false; }
+
+		HWND getWindowHandle() const { return mHWnd; }
+		HDC getHDC() const { return mHDC; }
+		
+		// Method for dealing with resize / move & 3d library
+		virtual void windowMovedOrResized(void);
+		bool isReady() const { return mReady; }
+		void setReady(bool set) { mReady = set; }
+		void setActive(bool set) { mActive = set; }
+		
+		void getCustomAttribute( const String& name, void* pData );
+
+	protected:
+		Win32GLSupport &mGLSupport;
+		HWND	mHWnd;					// Win32 Window handle
+		HDC		mHDC;
+		HGLRC	mGlrc;
+		int		mOldSwapIntervall;
+		bool	mActive;				// Is active i.e. visible
+		bool	mReady;					// Is ready i.e. available for update
+		bool	mClosed;
+        Win32Context *mContext;
+
+		static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+    };
+}
+
+#endif
Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLTexture.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLTexture.cpp	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLTexture.cpp	(revision 153)
@@ -0,0 +1,457 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://ogre.sourceforge.net/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+-----------------------------------------------------------------------------
+*/
+
+#include "OgreGLTexture.h"
+#include "OgreGLSupport.h"
+#include "OgreGLPixelFormat.h"
+#include "OgreGLHardwarePixelBuffer.h"
+
+#include "OgreTextureManager.h"
+#include "OgreImage.h"
+#include "OgreLogManager.h"
+#include "OgreCamera.h"
+#include "OgreException.h"
+#include "OgreRoot.h"
+#include "OgreCodec.h"
+#include "OgreImageCodec.h"
+
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+#   include <windows.h>
+#   include <wingdi.h>
+#endif
+
+namespace Ogre {
+
+    unsigned int mostSignificantBitSet(unsigned int value)
+	{
+		unsigned int result = 0;
+		while (value != 0) {
+			++result;
+			value >>= 1;
+		}
+		return result-1;
+	}
+
+    GLTexture::GLTexture(ResourceManager* creator, const String& name, 
+        ResourceHandle handle, const String& group, bool isManual, 
+        ManualResourceLoader* loader, GLSupport& support) 
+        : Texture(creator, name, handle, group, isManual, loader),
+        mTextureID(0), mGLSupport(support)
+    {
+    }
+
+
+    GLTexture::~GLTexture()
+    {
+        // have to call this here reather than in Resource destructor
+        // since calling virtual methods in base destructors causes crash
+        unload(); 
+    }
+
+    GLenum GLTexture::getGLTextureTarget(void) const
+    {
+        switch(mTextureType)
+        {
+            case TEX_TYPE_1D:
+                return GL_TEXTURE_1D;
+            case TEX_TYPE_2D:
+                return GL_TEXTURE_2D;
+            case TEX_TYPE_3D:
+                return GL_TEXTURE_3D;
+            case TEX_TYPE_CUBE_MAP:
+                return GL_TEXTURE_CUBE_MAP;
+            default:
+                return 0;
+        };
+    }
+
+	//* Creation / loading methods ********************************************
+	void GLTexture::createInternalResources(void)
+    {
+		// Adjust requested parameters to capabilities
+
+		// Check power-of-two size if required
+        unsigned int newWidth = (1 << mostSignificantBitSet(mWidth));
+        if (newWidth != mWidth)
+            newWidth <<= 1;
+
+        unsigned int newHeight = (1 << mostSignificantBitSet(mHeight));
+        if (newHeight != mHeight)
+            newHeight <<= 1;
+
+		unsigned int newDepth = (1 << mostSignificantBitSet(mDepth));
+        if (newDepth != mDepth)
+            newDepth <<= 1;
+
+        if(!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES))
+		{
+			mHeight = newHeight;
+			mWidth = newWidth;
+			mDepth = newDepth;
+		}
+		
+		// Check compressed texture support
+		// if a compressed format not supported, revert to PF_A8R8G8B8
+		if(PixelUtil::isCompressed(mFormat) &&
+		 !Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability( RSC_TEXTURE_COMPRESSION_DXT ))
+		{
+			mFormat = PF_A8R8G8B8;
+		}
+		// if floating point textures not supported, revert to PF_A8R8G8B8
+		if(PixelUtil::isFloatingPoint(mFormat) &&
+		 !Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability( RSC_TEXTURE_FLOAT ))
+		{
+			mFormat = PF_A8R8G8B8;
+		}
+		
+		// Check requested number of mipmaps
+		// Zero means create mip levels until 1x1
+		size_t maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
+		if(mNumMipmaps>maxMips)
+			mNumMipmaps = maxMips;
+		
+		// Generate texture name
+        glGenTextures( 1, &mTextureID );
+		
+		// Set texture type
+		glBindTexture( getGLTextureTarget(), mTextureID );
+        
+		// This needs to be set otherwise the texture doesn't get rendered
+        glTexParameteri( getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, mNumMipmaps );
+		
+		// If we can do automip generation and the user desires this, do so
+		if((mUsage & TU_AUTOMIPMAP) &&
+		    mNumMipmaps &&
+		 	Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP))
+        {
+            glTexParameteri( getGLTextureTarget(), GL_GENERATE_MIPMAP, GL_TRUE );
+        }
+		
+		// Allocate internal buffer so that glTexSubImageXD can be used
+		// Internal format
+		GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat);
+		size_t width = mWidth;
+		size_t height = mHeight;
+		size_t depth = mDepth;
+		if(PixelUtil::isCompressed(mFormat))
+		{
+			// Compressed formats
+			size_t size = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
+			// Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
+			// accept a 0 pointer like normal glTexImageXD
+			// Run through this process for every mipmap to pregenerate mipmap piramid
+			uint8 *tmpdata = new uint8[size];
+			memset(tmpdata, 0, size);
+			
+			for(int mip=0; mip<=mNumMipmaps; mip++)
+			{
+			//int mip = 0;
+				size = PixelUtil::getMemorySize(width, height, depth, mFormat);
+				switch(mTextureType)
+				{
+					case TEX_TYPE_1D:
+						glCompressedTexImage1DARB_ptr(GL_TEXTURE_1D, mip, format, 
+							width, 0, 
+							size, tmpdata);
+						break;
+					case TEX_TYPE_2D:
+						glCompressedTexImage2DARB_ptr(GL_TEXTURE_2D, mip, format,
+							width, height, 0, 
+							size, tmpdata);
+						break;
+					case TEX_TYPE_3D:
+						glCompressedTexImage3DARB_ptr(GL_TEXTURE_3D, mip, format,
+							width, height, depth, 0, 
+							size, tmpdata);
+						break;
+					case TEX_TYPE_CUBE_MAP:
+						for(int face=0; face<6; face++) {
+							glCompressedTexImage2DARB_ptr(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
+								width, height, 0, 
+								size, tmpdata);
+						}
+						break;
+				};
+				if(width>1)		width = width/2;
+				if(height>1)	height = height/2;
+				if(depth>1)		depth = depth/2;
+			}
+			delete tmpdata;
+		}
+		else
+		{
+			// Run through this process to pregenerate mipmap piramid
+			for(int mip=0; mip<=mNumMipmaps; mip++)
+			{
+				// Normal formats
+				switch(mTextureType)
+				{
+					case TEX_TYPE_1D:
+						glTexImage1D(GL_TEXTURE_1D, mip, format,
+							width, 0, 
+							GL_RGBA, GL_UNSIGNED_BYTE, 0);
+	
+						break;
+					case TEX_TYPE_2D:
+						glTexImage2D(GL_TEXTURE_2D, mip, format,
+							width, height, 0, 
+							GL_RGBA, GL_UNSIGNED_BYTE, 0);
+						break;
+					case TEX_TYPE_3D:
+						glTexImage3D(GL_TEXTURE_3D, mip, format,
+							width, height, depth, 0, 
+							GL_RGBA, GL_UNSIGNED_BYTE, 0);
+						break;
+					case TEX_TYPE_CUBE_MAP:
+						for(int face=0; face<6; face++) {
+							glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
+								width, height, 0, 
+								GL_RGBA, GL_UNSIGNED_BYTE, 0);
+						}
+						break;
+				};
+				if(width>1)		width = width/2;
+				if(height>1)	height = height/2;
+				if(depth>1)		depth = depth/2;
+			}
+		}
+		_createSurfaceList();
+		// Get final internal format
+		mFormat = getBuffer(0,0)->getFormat();
+		mIsLoaded = true;
+	}
+	
+    void GLTexture::createRenderTexture(void)
+    {
+        if (this->getTextureType() != TEX_TYPE_2D)
+            OGRE_EXCEPT( Exception::UNIMPLEMENTED_FEATURE, "**** Create render texture implemented only for 2D textures!!! ****", "GLTexture::createRenderTexture" );
+
+        // Create the GL texture
+		// This already does everything neccessary
+        createInternalResources();
+    }
+	
+	void GLTexture::loadImage( const Image& img )
+    {
+        std::vector<const Image*> images;
+		
+        images.push_back(&img);
+        _loadImages(images);
+        images.clear();
+    }
+
+    void GLTexture::loadImpl()
+    {
+        if( mUsage & TU_RENDERTARGET )
+        {
+            createRenderTexture();
+            mIsLoaded = true;     
+        }
+        else
+        {
+            if(mTextureType == TEX_TYPE_1D || mTextureType == TEX_TYPE_2D || 
+                mTextureType == TEX_TYPE_3D)
+            {
+                Image img;
+                img.load(mName, mGroup);
+
+				// If this is a cube map, set the texture type flag accordingly.
+                if (img.hasFlag(IF_CUBEMAP))
+					mTextureType = TEX_TYPE_CUBE_MAP;
+				// If this is a volumetric texture set the texture type flag accordingly.
+				if(img.getDepth() > 1)
+					mTextureType = TEX_TYPE_3D;
+
+				loadImage( img );
+            }
+            else if (mTextureType == TEX_TYPE_CUBE_MAP)
+            {
+				if(StringUtil::endsWith(getName(), ".dds"))
+				{
+					// XX HACK there should be a better way to specify wether 
+					// all faces are in the same file or not
+					Image img;
+                	img.load(mName, mGroup);
+					loadImage( img );
+				}
+				else
+				{
+					String baseName, ext;
+					std::vector<Image> images(6);
+					std::vector<const Image*> imagePtrs;
+					static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"};
+	
+					for(size_t i = 0; i < 6; i++)
+					{
+						size_t pos = mName.find_last_of(".");
+						baseName = mName.substr(0, pos);
+						ext = mName.substr(pos);
+						String fullName = baseName + suffixes[i] + ext;
+	
+						images[i].load(fullName, mGroup);
+						imagePtrs.push_back(&images[i]);
+					}
+	
+					_loadImages( imagePtrs );
+				}
+            }
+            else
+                OGRE_EXCEPT( Exception::UNIMPLEMENTED_FEATURE, "**** Unknown texture type ****", "GLTexture::load" );
+        }
+    }
+	
+	//*************************************************************************
+    
+    void GLTexture::unloadImpl()
+    {
+		mSurfaceList.clear();
+        glDeleteTextures( 1, &mTextureID );
+    }
+
+	
+	//---------------------------------------------------------------------------------------------
+	void GLTexture::_createSurfaceList()
+	{
+		mSurfaceList.clear();
+		// Make our understanding of the number of mips matches the GL one
+		glBindTexture( getGLTextureTarget(), mTextureID );
+		GLint value;
+		glGetTexParameteriv( getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, &value );
+		mNumMipmaps = value;
+		
+		// For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr
+		bool wantGeneratedMips = (mUsage & TU_AUTOMIPMAP)!=0;
+		bool canMip = Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP);
+		
+		// Do mipmapping in software? (uses GLU) For some cards, this is still needed. Of course,
+		// only when mipmap generation is desired.
+		bool doSoftware = wantGeneratedMips && !canMip && getNumMipmaps(); 
+		
+		for(int face=0; face<getNumFaces(); face++)
+		{
+			for(int mip=0; mip<=getNumMipmaps(); mip++)
+			{
+				mSurfaceList.push_back(HardwarePixelBufferSharedPtr(
+					new GLHardwarePixelBuffer(getGLTextureTarget(), mTextureID, face, mip,
+						static_cast<HardwareBuffer::Usage>(mUsage), doSoftware && mip==0)
+				));
+			}
+		}
+	}
+	
+	//---------------------------------------------------------------------------------------------
+	HardwarePixelBufferSharedPtr GLTexture::getBuffer(size_t face, size_t mipmap)
+	{
+		if(face >= getNumFaces())
+			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Face index out of range",
+					"GLTexture::getBuffer");
+		if(mipmap > mNumMipmaps)
+			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range",
+					"GLTexture::getBuffer");
+		unsigned int idx = face*(mNumMipmaps+1) + mipmap;
+		assert(idx < mSurfaceList.size());
+		return mSurfaceList[idx];
+	}
+	
+	//---------------------------------------------------------------------------------------------
+    void GLRenderTexture::_copyToTexture(void)
+    {		
+        glBindTexture(GL_TEXTURE_2D, mGLTexture->getGLID());
+			
+        glCopyTexSubImage2D(GL_TEXTURE_2D, mGLTexture->getNumMipmaps(), 0, 0,
+            0, 0, mWidth, mHeight);
+
+    }
+    
+    void GLRenderTexture::writeContentsToFile( const String & filename ) 
+    {
+        ImageCodec::ImageData *imgData = new ImageCodec::ImageData();
+        
+        imgData->width = mGLTexture->getWidth();
+        imgData->height = mGLTexture->getHeight();
+		imgData->depth = 1;
+        imgData->format = PF_BYTE_RGB;
+
+        // Allocate buffer 
+        uchar* pBuffer = new uchar[imgData->width * imgData->height * 3];
+
+        // Read pixels
+        // I love GL: it does all the locking & colour conversion for us
+        glBindTexture(GL_TEXTURE_2D, mGLTexture->getGLID());
+        glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pBuffer);
+
+        // Wrap buffer in a chunk
+        DataStreamPtr stream(new MemoryDataStream(
+            pBuffer, imgData->width * imgData->height * 3, false));
+
+        // Need to flip the read data over in Y though
+        Image img;
+        img.loadRawData(stream, imgData->width, imgData->height, imgData->format );
+        img.flipAroundX();
+
+        MemoryDataStreamPtr streamFlipped(
+            new MemoryDataStream(img.getData(), stream->size(), false));
+
+        // Get codec 
+        size_t pos = filename.find_last_of(".");
+            String extension;
+        if( pos == String::npos )
+            OGRE_EXCEPT(
+                Exception::ERR_INVALIDPARAMS, 
+            "Unable to determine image type for '" + filename + "' - invalid extension.",
+                "GLRenderTexture::writeContentsToFile" );
+
+        while( pos != filename.length() - 1 )
+            extension += filename[++pos];
+
+        // Get the codec
+        Codec * pCodec = Codec::getCodec(extension);
+
+        // Write out
+        Codec::CodecDataPtr codecDataPtr(imgData);
+        pCodec->codeToFile(streamFlipped, filename, codecDataPtr);
+
+        delete [] pBuffer;
+    }
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	uchar *GLRenderTexture::getBufferContents(int &dimx, int &dimy)
+	{
+		ImageCodec::ImageData *imgData = new ImageCodec::ImageData();
+		dimx = mWidth;
+		dimy = mHeight;
+		
+		// Allocate buffer 
+		uchar* pBuffer = new uchar[mWidth * mHeight * 3];
+
+		// Read pixels
+		// I love GL: it does all the locking & colour conversion for us
+		glReadPixels(0, 0, mWidth-1, mHeight-1, GL_RGB, GL_UNSIGNED_BYTE, pBuffer);
+
+		return pBuffer;
+	}
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+}
+
Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreWin32Window.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreWin32Window.cpp	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreWin32Window.cpp	(revision 153)
@@ -0,0 +1,498 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+-----------------------------------------------------------------------------
+*/
+
+#include "OgreWin32Window.h"
+#include "OgreRoot.h"
+#include "OgreLogManager.h"
+#include "OgreRenderSystem.h"
+#include "OgreImageCodec.h"
+#include "OgreStringConverter.h"
+#include "OgreException.h"
+#include "OgreWin32GLSupport.h"
+#include "OgreWin32Context.h"
+
+namespace Ogre {
+
+	Win32Window::Win32Window(Win32GLSupport &glsupport):
+		mGLSupport(glsupport),
+        mContext(0)
+    {
+		mIsFullScreen = false;
+		mHWnd = 0;
+		mActive = false;
+		mReady = false;
+		mClosed = false;
+    }
+
+    Win32Window::~Win32Window()
+    {
+		destroy();
+    }
+
+	void Win32Window::create(const String& name, unsigned int width, unsigned int height,
+	            bool fullScreen, const NameValuePairList *miscParams)
+    {
+        HWND parentHWnd = 0;
+		HWND externalHandle = 0;
+		HINSTANCE hInst = GetModuleHandle("RenderSystem_GL.dll");
+		bool vsync = false;
+		unsigned int displayFrequency = 0;
+		String title = name;
+		unsigned int colourDepth = 32;
+		unsigned int left = 0; // Defaults to screen center
+		unsigned int top = 0; // Defaults to screen center
+		bool depthBuffer = true;
+		int multisample = 0;
+
+		if(miscParams)
+		{
+			// Get variable-length params
+			NameValuePairList::const_iterator opt;
+			// left (x)
+			opt = miscParams->find("left");
+			if(opt != miscParams->end())
+				left = StringConverter::parseUnsignedInt(opt->second);
+			// top (y)
+			opt = miscParams->find("top");
+			if(opt != miscParams->end())
+				top = StringConverter::parseUnsignedInt(opt->second);
+			// Window title
+			opt = miscParams->find("title");
+			if(opt != miscParams->end())
+				title = opt->second;
+			// externalWindowHandle		-> externalHandle
+			opt = miscParams->find("externalWindowHandle");
+			if(opt != miscParams->end())
+				externalHandle = (HWND)StringConverter::parseUnsignedInt(opt->second);
+			// parentWindowHandle -> parentHWnd
+			opt = miscParams->find("parentWindowHandle");
+			if(opt != miscParams->end()) 
+				parentHWnd = (HWND)StringConverter::parseUnsignedInt(opt->second);
+			// vsync	[parseBool]
+			opt = miscParams->find("vsync");
+			if(opt != miscParams->end())
+				vsync = StringConverter::parseBool(opt->second);
+			// displayFrequency
+			opt = miscParams->find("displayFrequency");
+			if(opt != miscParams->end())
+				displayFrequency = StringConverter::parseUnsignedInt(opt->second);
+			// colourDepth
+			opt = miscParams->find("colourDepth");
+			if(opt != miscParams->end())
+				colourDepth = StringConverter::parseUnsignedInt(opt->second);
+			// depthBuffer [parseBool]
+			opt = miscParams->find("depthBuffer");
+			if(opt != miscParams->end())
+				depthBuffer = StringConverter::parseBool(opt->second);
+			// FSAA
+			opt = miscParams->find("FSAA");
+			if(opt != miscParams->end())
+				multisample = StringConverter::parseUnsignedInt(opt->second);
+		}
+		
+		// Destroy current window if any
+		if( mHWnd )
+			destroy();
+
+        if (fullScreen)
+        {
+			mColourDepth = colourDepth;
+        }
+		else 
+		{
+			// Get colour depth from display
+			mColourDepth = GetDeviceCaps(GetDC(0), BITSPIXEL);
+		}
+
+		if (!externalHandle) {
+			DWORD dwStyle = (fullScreen ? WS_POPUP : WS_OVERLAPPEDWINDOW) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+			RECT rc;
+
+			mWidth = width;
+			mHeight = height;
+
+			if (!fullScreen)
+			{
+				// Calculate window dimensions required to get the requested client area
+				SetRect(&rc, 0, 0, mWidth, mHeight);
+				AdjustWindowRect(&rc, dwStyle, false);
+				mWidth = rc.right - rc.left;
+				mHeight = rc.bottom - rc.top;
+
+				// Clamp width and height to the desktop dimensions
+				if (mWidth > (unsigned)GetSystemMetrics(SM_CXSCREEN))
+					mWidth = (unsigned)GetSystemMetrics(SM_CXSCREEN);
+				if (mHeight > (unsigned)GetSystemMetrics(SM_CYSCREEN))
+					mHeight = (unsigned)GetSystemMetrics(SM_CYSCREEN);
+
+				if (!left)
+                {
+					mLeft = (GetSystemMetrics(SM_CXSCREEN) / 2) - (mWidth / 2);
+                }
+				else
+                {
+					mLeft = left;
+                }
+				if (!top)
+                {
+					mTop = (GetSystemMetrics(SM_CYSCREEN) / 2) - (mHeight / 2);
+                }
+				else
+                {
+                    mTop = top;
+                }
+			}
+			else
+            {
+				mTop = mLeft = 0;
+            }
+
+			// Register the window class
+
+			WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
+				WndProc, 0, 4, hInst,
+				LoadIcon( NULL, IDI_APPLICATION ),
+				LoadCursor( NULL, IDC_ARROW ),
+				(HBRUSH)GetStockObject( BLACK_BRUSH ), NULL,
+				TEXT(title.c_str()) };
+			RegisterClass( &wndClass );
+
+			// Create our main window
+			// Pass pointer to self
+			HWND hWnd = CreateWindowEx(fullScreen?WS_EX_TOPMOST:0, TEXT(title.c_str()), TEXT(title.c_str()),
+				dwStyle, mLeft, mTop, mWidth, mHeight, 0L, 0L, hInst, this);
+			mHWnd = hWnd;
+
+			GetClientRect(mHWnd,&rc);
+			mWidth = rc.right;
+			mHeight = rc.bottom;
+
+            if (fullScreen) {
+			    DEVMODE DevMode;
+			    DevMode.dmSize = sizeof(DevMode);
+			    DevMode.dmBitsPerPel = mColourDepth;
+			    DevMode.dmPelsWidth = mWidth;
+			    DevMode.dmPelsHeight = mHeight;
+			    DevMode.dmDisplayFrequency = displayFrequency;
+			    DevMode.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY;
+			    if (ChangeDisplaySettings(&DevMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
+				    LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettingsEx");
+
+		    }
+
+		}
+		else {
+			mHWnd = externalHandle;
+			RECT rc;
+			GetClientRect(mHWnd, &rc);
+			mWidth = rc.right;
+			mHeight = rc.bottom;
+			mLeft = rc.left;
+			mTop = rc.top;
+		}
+		ShowWindow(mHWnd, SW_SHOWNORMAL);
+		UpdateWindow(mHWnd);
+		mName = name;
+		mIsDepthBuffered = depthBuffer;
+		mIsFullScreen = fullScreen;
+
+		
+		HDC hdc = GetDC(mHWnd);
+
+        StringUtil::StrStreamType str;
+        str << "Created Win32Window '"
+            << mName << "' : " << mWidth << "x" << mHeight
+            << ", " << mColourDepth << "bpp";
+        LogManager::getSingleton().logMessage(LML_NORMAL, str.str());
+
+		if (!mGLSupport.selectPixelFormat(hdc, mColourDepth, multisample))
+		{
+			if (multisample == 0)
+				OGRE_EXCEPT(0, "selectPixelFormat failed", "Win32Window::create");
+
+			LogManager::getSingleton().logMessage(LML_NORMAL, "FSAA level not supported, falling back");
+			if (!mGLSupport.selectPixelFormat(hdc, mColourDepth, 0))
+				OGRE_EXCEPT(0, "selectPixelFormat failed", "Win32Window::create");
+		}
+
+		HGLRC glrc = wglCreateContext(hdc);
+		if (!glrc)
+			OGRE_EXCEPT(0, "wglCreateContext", "Win32Window::create");
+		if (!wglMakeCurrent(hdc, glrc))
+			OGRE_EXCEPT(0, "wglMakeCurrent", "Win32Window::create");
+		
+		mGlrc = glrc;
+		mHDC = hdc;
+
+		mOldSwapIntervall = wglGetSwapIntervalEXT();
+		if (vsync) 
+			wglSwapIntervalEXT(1);
+		else
+			wglSwapIntervalEXT(0);
+
+		mReady = true;
+
+        // Create RenderSystem context
+        mContext = new Win32Context(mHDC, mGlrc);
+        // Register the context with the rendersystem and associate it with this window
+        GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem());
+        rs->_registerContext(this, mContext);
+    }
+
+    void Win32Window::destroy(void)
+    {
+        // Unregister and destroy OGRE GLContext
+        if (mContext)
+        {
+            GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem());
+            rs->_unregisterContext(this);
+            delete mContext;
+            mContext = NULL;
+
+            wglSwapIntervalEXT(mOldSwapIntervall);
+        }
+		if (mGlrc) {
+			wglMakeCurrent(NULL, NULL);
+			wglDeleteContext(mGlrc);
+			mGlrc = NULL;
+		}
+		if (mHDC) {
+			ReleaseDC(mHWnd, mHDC);
+			mHDC = NULL;
+		}
+		if (mIsFullScreen)
+		{
+			ChangeDisplaySettings(NULL, 0);
+		}
+        if (mHWnd)
+        {
+	        DestroyWindow(mHWnd);
+            mHWnd = 0;
+        }
+        mActive = false;
+    }
+
+    bool Win32Window::isActive() const
+    {
+        return mActive;
+    }
+
+    bool Win32Window::isClosed() const
+    {
+        return mClosed;
+    }
+
+    void Win32Window::reposition(int left, int top)
+    {
+        // XXX FIXME
+    }
+
+    void Win32Window::resize(unsigned int width, unsigned int height)
+    {
+
+		mWidth = width;
+		mHeight = height;
+
+		// Notify viewports of resize
+		ViewportList::iterator it, itend;
+        itend = mViewportList.end();
+		for( it = mViewportList.begin(); it != itend; ++it )
+			(*it).second->_updateDimensions();
+		// TODO - resize window
+    }
+
+	void Win32Window::windowMovedOrResized()
+	{
+		RECT temprect;
+		::GetClientRect(getWindowHandle(),&temprect);
+		resize(temprect.right-temprect.left,temprect.bottom-temprect.top);
+		// TODO
+	}
+
+    void Win32Window::swapBuffers(bool waitForVSync)
+    {
+		SwapBuffers(mHDC);
+    }
+
+	void Win32Window::writeContentsToFile(const String& filename)
+	{
+		ImageCodec::ImageData *imgData = new ImageCodec::ImageData();
+		imgData->width = mWidth;
+		imgData->height = mHeight;
+		imgData->depth = 1;
+		imgData->format = PF_BYTE_RGB;
+
+		// Allocate buffer 
+		uchar* pBuffer = new uchar[mWidth * mHeight * 3];
+
+		// Read pixels
+		// I love GL: it does all the locking & colour conversion for us
+		glReadPixels(0,0, mWidth-1, mHeight-1, GL_RGB, GL_UNSIGNED_BYTE, pBuffer);
+
+		// Wrap buffer in a memory stream
+		DataStreamPtr stream(new MemoryDataStream(pBuffer, mWidth * mHeight * 3, false));
+
+		// Need to flip the read data over in Y though
+		Image img;
+		img.loadRawData(stream, mWidth, mHeight, imgData->format );
+		img.flipAroundX();
+
+		MemoryDataStreamPtr streamFlipped(new MemoryDataStream(img.getData(), stream->size(), false));
+
+		// Get codec 
+		size_t pos = filename.find_last_of(".");
+		String extension;
+		if( pos == String::npos )
+			OGRE_EXCEPT(
+			Exception::ERR_INVALIDPARAMS, 
+			"Unable to determine image type for '" + filename + "' - invalid extension.",
+			"Win32Window::writeContentsToFile" );
+
+		while( pos != filename.length() - 1 )
+			extension += filename[++pos];
+
+		// Get the codec
+		Codec * pCodec = Codec::getCodec(extension);
+
+		// Write out
+		Codec::CodecDataPtr ptr(imgData);
+        pCodec->codeToFile(streamFlipped, filename, ptr);
+
+		delete [] pBuffer;
+	}
+
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	uchar *Win32Window::getBufferContents(int &dimx, int &dimy)
+	{
+		ImageCodec::ImageData *imgData = new ImageCodec::ImageData();
+		dimx = mWidth;
+		dimy = mHeight;
+		
+		// Allocate buffer 
+		uchar* pBuffer = new uchar[mWidth * mHeight * 3];
+
+		// Read pixels
+		// I love GL: it does all the locking & colour conversion for us
+		glReadPixels(0, 0, mWidth-1, mHeight-1, GL_RGB, GL_UNSIGNED_BYTE, pBuffer);
+
+		return pBuffer;
+	}
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+
+	// Window procedure callback
+	// This is a static member, so applies to all windows but we store the
+	// Win32Window instance in the window data GetWindowLog/SetWindowLog
+	LRESULT Win32Window::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+	{
+		Win32Window* win;
+
+		// look up window instance
+		if( WM_CREATE != uMsg )
+			win = (Win32Window*)GetWindowLong( hWnd, 0 );
+
+		switch( uMsg )
+		{
+		case WM_ACTIVATE:
+			if( WA_INACTIVE == LOWORD( wParam ) )
+				win->mActive = false;
+			else
+				win->mActive = true;
+			break;
+
+		case WM_CREATE: {
+			// Log the new window
+			// Get CREATESTRUCT
+			LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
+			win = (Win32Window*)(lpcs->lpCreateParams);
+			// Store pointer in window user data area
+			SetWindowLong( hWnd, 0, (long)win );
+			win->mActive = true;
+
+			return 0; }
+			break;
+
+		case WM_PAINT:
+			// If we get WM_PAINT messges, it usually means our window was
+			// comvered up, so we need to refresh it by re-showing the contents
+			// of the current frame.
+			if( win->mActive && win->mReady )
+				win->update();
+			break;
+
+		case WM_MOVE:
+			// Move messages need to be tracked to update the screen rects
+			// used for blitting the backbuffer to the primary
+			// *** This doesn't need to be used to Direct3D9 ***
+			break;
+
+		case WM_ENTERSIZEMOVE:
+			// Previent rendering while moving / sizing
+			win->mReady = false;
+			break;
+
+		case WM_EXITSIZEMOVE:
+			win->windowMovedOrResized();
+			win->mReady = true;
+			break;
+
+		case WM_SIZE:
+			// Check to see if we are losing or gaining our window.  Set the 
+			// active flag to match
+			if( SIZE_MAXHIDE == wParam || SIZE_MINIMIZED == wParam )
+				win->mActive = false;
+			else
+			{
+				win->mActive = true;
+				if( win->mReady )
+					win->windowMovedOrResized();
+			}
+			break;
+
+		case WM_GETMINMAXINFO:
+			// Prevent the window from going smaller than some minimu size
+			((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
+			((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
+			break;
+
+		case WM_CLOSE:
+			DestroyWindow( win->mHWnd );
+			win->mClosed = true;
+			return 0;
+		}
+
+		return DefWindowProc( hWnd, uMsg, wParam, lParam );
+	}
+	
+	void Win32Window::getCustomAttribute( const String& name, void* pData )
+	{
+		if( name == "HWND" )
+		{
+			HWND *pHwnd = (HWND*)pData;
+			*pHwnd = getWindowHandle();
+			return;
+		}
+	}
+
+}
Index: trunk/VUT/work/ogre_changes/RenderSystems/Direct3D7/include/OgreD3D7RenderWindow.h
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/Direct3D7/include/OgreD3D7RenderWindow.h	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/Direct3D7/include/OgreD3D7RenderWindow.h	(revision 153)
@@ -0,0 +1,177 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+-----------------------------------------------------------------------------
+*/
+#ifndef __D3D7RenderWindow_H__
+#define __D3D7RenderWindow_H__
+
+// Precompiler options
+#include "OgreD3D7Prerequisites.h"
+
+#include "OgreRenderWindow.h"
+#include "OgreDDDriver.h"
+#include "OgreD3D7DeviceList.h"
+#include "OgreD3D7Device.h"
+
+namespace Ogre {
+    /** Defines the rendering window on Win32 systems
+        @remarks
+            This class represents the rendering window on the
+            Windows family of operating systems.
+     */
+    class D3D7RenderWindow : public RenderWindow
+    {
+    public:
+        D3D7RenderWindow(HINSTANCE instance, DDDriver *driver);
+        ~D3D7RenderWindow();
+
+		void create(const String& name, unsigned int width, unsigned int height,
+			bool fullScreen, const NameValuePairList *miscParams);
+
+        /** Overridden - see RenderWindow 
+        */
+        void destroy(void);
+
+        /** Overridden - see RenderWindow
+        */
+        bool isActive(void) const;
+
+        /** Overridden - see RenderWindow
+        */
+        bool isClosed(void) const;
+
+        /** Overridden - see RenderWindow
+        */
+        void reposition(int left, int top);
+
+        /** Overridden - see RenderWindow
+        */
+        void resize(unsigned int width, unsigned int height);
+
+        /** Overridden - see RenderWindow
+        */
+        void swapBuffers(bool waitForVSync);
+
+        /** Retrieves a handle to the window (Win32 specific)
+        */
+        HWND getWindowHandle(void) const;
+
+        /** Retrieves a handle to the window's parent, or 0 if there is no parent.
+        */
+        HWND getParentWindowHandle(void) const;
+
+        /** Returns true if this window is using DirectDraw.
+        */
+        bool isUsingDirectDraw(void) const;
+        /** Retrieves a pointer to the DirectDraw wrapper object used to 
+            manage the window's surface. (Win32 specific)
+            @note
+                Only applicable for windows using DirectDraw.
+        */
+        DDDriver* getDirectDrawDriver(void);
+
+        /** Returns a pointer to a DirectDraw surface containing the
+            front buffer.
+            @note
+                Only applicable for windows using DirectDraw.
+        */
+        LPDIRECTDRAWSURFACE7 getDDFrontBuffer(void);
+
+        /** Returns a pointer to a DirectDraw surface containing the back 
+            buffer. Only applicable if using DirectDraw.
+        */
+        LPDIRECTDRAWSURFACE7 getDDBackBuffer(void);
+
+        /** Returns a pointer to the Direct3D device that works with this
+            window
+            @note
+                Only applicable for windows using DirectDraw.
+        */
+        LPDIRECT3DDEVICE7 getD3DDevice(void);
+
+        bool requiresTextureFlipping() const { return false; }
+
+        /** Overridden - see RenderTarget.
+        */
+        void getCustomAttribute(const String& name, void* pData);
+
+        /** Overridden - see RenderTarget.
+        */
+        void writeContentsToFile(const String& filename);
+
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+		uchar *getBufferContents(int &dimx, int &dimy);
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+
+    protected:
+		HINSTANCE mInstance;			// Process instance
+		DDDriver *mDriver;			// D3D9 driver
+        // Win32-specific data members
+        bool mIsUsingDirectDraw;
+        HWND mHWnd;                    // Win32 Window handle
+        HWND mParentHWnd;
+        bool mActive;                // Is active i.e. visible
+        bool mReady;                // Is ready i.e. available for update
+        bool mClosed;
+
+        RECT rcBlitDest;            // Target for blit operation
+                                    // == window client area
+
+
+        static LRESULT CALLBACK WndProc( 
+            HWND hWnd, 
+            UINT uMsg, 
+            WPARAM wParam, 
+            LPARAM lParam);
+
+        // ---------------------------------------------------------
+        // DirectX-specific
+        // ---------------------------------------------------------
+
+        // Pointer to DDDriver encapsulating DirectDraw driver (if DirectX in use)
+        DDDriver* mlpDDDriver;
+
+        // Pointers to DX surfaces
+        LPDIRECTDRAWSURFACE7 mlpDDSFront; // Pointer to primary (front) buffer surface
+        LPDIRECTDRAWSURFACE7 mlpDDSBack; // Pointer to back buffer
+
+        // Pointer to the 3D Device specific for this window
+        LPDIRECT3DDEVICE7 mlpD3DDevice;
+
+        // DirectDraw Methods
+        void createDDSurfaces(void);
+        void releaseDDSurfaces(void);
+        void restoreDDSurfaces(void);
+        void createDepthBuffer(void);
+
+        // Method for dealing with resize / move & 3d library
+        void windowMovedOrResized(void);
+        
+        // ---------------------------------------------------------
+        // OpenGL-specific details
+        // ---------------------------------------------------------
+
+        // TODO
+    };
+}
+#endif
Index: trunk/VUT/work/ogre_changes/RenderSystems/Direct3D7/src/OgreD3D7RenderWindow.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/Direct3D7/src/OgreD3D7RenderWindow.cpp	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/Direct3D7/src/OgreD3D7RenderWindow.cpp	(revision 153)
@@ -0,0 +1,908 @@
+/*-------------------------------------------------------------------------
+This source file is a part of OGRE
+(Object-oriented Graphics Rendering Engine)
+
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This library is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License (LGPL) as 
+published by the Free Software Foundation; either version 2.1 of the 
+License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License 
+along with this library; if not, write to the Free Software Foundation, 
+Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA or go to
+http://www.gnu.org/copyleft/lesser.txt
+-------------------------------------------------------------------------*/
+#include "OgreD3D7RenderWindow.h"
+
+#include "OgreLogManager.h"
+#include "OgreViewport.h"
+#include "OgreException.h"
+#include "OgreRoot.h"
+#include "OgreRenderSystem.h"
+#include "OgreD3D7TextureManager.h"
+#include "OgreBitwise.h"
+#include "OgreImageCodec.h"
+#include "OgreStringConverter.h"
+
+namespace Ogre {
+
+
+    // Window procedure callback
+    // This is a static member, so applies to all windows but we store the 
+    // D3D7RenderWindow instance in the window data GetWindowLong/SetWindowLong.
+    LRESULT D3D7RenderWindow::WndProc( 
+        HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+    {
+        LPCREATESTRUCT lpcs;
+        D3D7RenderWindow* win;
+
+        // look up window instance
+        if (uMsg != WM_CREATE)
+        {
+            // Get window pointer
+            win = (D3D7RenderWindow*)GetWindowLong(hWnd, 0);
+        }
+
+        switch( uMsg )
+        {
+            case WM_ACTIVATE:
+                if( LOWORD( wParam ) == WA_INACTIVE )
+                    win->mActive = false;
+                else
+                    win->mActive = true;
+                break;
+
+            case WM_CREATE:
+                // Log the new window
+                // Get CREATESTRUCT
+                lpcs = (LPCREATESTRUCT)lParam;
+                win = (D3D7RenderWindow*)(lpcs->lpCreateParams);
+                // Store pointer in window user data area
+                SetWindowLong(hWnd, 0, (long)win);
+                win->mActive = true;
+
+                return 0;
+
+            case WM_KEYDOWN:
+                // TEMPORARY CODE
+                // TODO - queue up keydown / keyup events with
+                //  window name and timestamp to be processed
+                //  by main loop
+
+                // ESCAPE closes window
+                //if (wParam == VK_ESCAPE)
+                //{
+                //    win->mClosed = true;
+                //    return 0L;
+                //}
+                break;
+
+            case WM_PAINT:
+                // If we get WM_PAINT messages, it usually means our window was
+                // covered up, so we need to refresh it by re-showing the contents
+                // of the current frame.
+                if (win->mActive && win->mReady)
+                    win->update();
+                break;
+
+            case WM_MOVE:
+                // Move messages need to be tracked to update the screen rects
+                // used for blitting the backbuffer to the primary.
+                if(win->mActive && win->mReady)
+                    win->windowMovedOrResized();
+                break;
+
+            case WM_ENTERSIZEMOVE:
+                // Prevent rendering while moving / sizing
+                win->mReady = false;
+                break;
+
+            case WM_EXITSIZEMOVE:
+                win->windowMovedOrResized();
+                win->mReady = true;
+                break;
+
+            case WM_SIZE:
+                // Check to see if we are losing or gaining our window. Set the
+                // active flag to match.
+                if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
+                    win->mActive = false;
+                else
+                {
+                    win->mActive = true;
+                    if (win->mReady)
+                        win->windowMovedOrResized();
+                }
+
+                break;
+
+            case WM_GETMINMAXINFO:
+                // Prevent the window from going smaller than some minimum size
+                ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
+                ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
+                break;
+
+            case WM_CLOSE:
+                DestroyWindow( win->mHWnd );
+                win->mClosed = true;
+                return 0;
+
+            /*
+            case WM_DESTROY:
+                g_DIMSystem->CleanupRenderer();
+                PostQuitMessage(0);
+                return 0L;
+            */
+        }
+
+
+
+        return DefWindowProc( hWnd, uMsg, wParam, lParam );
+    }
+
+    // -------------------------------------------
+    // D3D7RenderWindow Implementation
+    // -------------------------------------------
+	D3D7RenderWindow::D3D7RenderWindow(HINSTANCE instance, DDDriver *driver):
+		mInstance(instance),
+		mDriver(driver)
+    {
+        mIsUsingDirectDraw = false;
+        mIsFullScreen = false;
+        mlpDDDriver = 0;
+        mHWnd = 0;
+        mActive = false;
+        mReady = false;
+        mClosed = false;
+    }
+
+    D3D7RenderWindow::~D3D7RenderWindow()
+    {
+    }
+
+
+
+	void D3D7RenderWindow::create(const String& name, unsigned int width, unsigned int height,
+	            bool fullScreen, const NameValuePairList *miscParams)
+    {
+
+        HWND parentHWnd = 0;
+        HINSTANCE hInst = mInstance;
+        DDDriver* drv = mDriver;
+        long tempPtr;
+		bool vsync = false;
+		unsigned int displayFrequency = 0;
+		String title = name;
+		unsigned int colourDepth = 32;
+		unsigned int left = 0; // Defaults to screen center
+		unsigned int top = 0; // Defaults to screen center
+		bool depthBuffer = true;
+		
+		if(miscParams)
+		{
+			// Get variable-length params
+			NameValuePairList::const_iterator opt;
+			// left (x)
+			opt = miscParams->find("left");
+			if(opt != miscParams->end())
+				left = StringConverter::parseUnsignedInt(opt->second);
+			// top (y)
+			opt = miscParams->find("top");
+			if(opt != miscParams->end())
+				top = StringConverter::parseUnsignedInt(opt->second);
+			// Window title
+			opt = miscParams->find("title");
+			if(opt != miscParams->end())
+				title = opt->second;
+			// parentWindowHandle -> parentHWnd
+			opt = miscParams->find("parentWindowHandle");
+			if(opt != miscParams->end()) 
+				parentHWnd = (HWND)StringConverter::parseUnsignedInt(opt->second);
+			// vsync	[parseBool]
+			opt = miscParams->find("vsync");
+			if(opt != miscParams->end())
+				vsync = StringConverter::parseBool(opt->second);
+			// displayFrequency
+			opt = miscParams->find("displayFrequency");
+			if(opt != miscParams->end())
+				displayFrequency = StringConverter::parseUnsignedInt(opt->second);
+			// colourDepth
+			opt = miscParams->find("colourDepth");
+			if(opt != miscParams->end())
+				colourDepth = StringConverter::parseUnsignedInt(opt->second);
+			// depthBuffer [parseBool]
+			opt = miscParams->find("depthBuffer");
+			if(opt != miscParams->end())
+				depthBuffer = StringConverter::parseBool(opt->second);
+		}
+
+
+        // Destroy current window if any
+        if (mHWnd)
+        {
+            destroy();
+        }
+
+        // TODO: deal with child windows
+        mParentHWnd = parentHWnd;
+
+		DWORD dwStyle = (fullScreen ? WS_POPUP : WS_OVERLAPPEDWINDOW) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+		RECT rc;
+
+		mWidth = width;
+		mHeight = height;
+
+		if (!fullScreen)
+		{
+			// Calculate window dimensions required to get the requested client area
+			SetRect(&rc, 0, 0, mWidth, mHeight);
+			AdjustWindowRect(&rc, dwStyle, false);
+			mWidth = rc.right - rc.left;
+			mHeight = rc.bottom - rc.top;
+
+			// Clamp width and height to the desktop dimensions
+			if (mWidth > (unsigned)GetSystemMetrics(SM_CXSCREEN))
+				mWidth = (unsigned)GetSystemMetrics(SM_CXSCREEN);
+			if (mHeight > (unsigned)GetSystemMetrics(SM_CYSCREEN))
+				mHeight = (unsigned)GetSystemMetrics(SM_CYSCREEN);
+
+			if (!left)
+				mLeft = (GetSystemMetrics(SM_CXSCREEN) / 2) - (mWidth / 2);
+			else
+				mLeft = left;
+			if (!top)
+				mTop = (GetSystemMetrics(SM_CYSCREEN) / 2) - (mHeight / 2);
+			else
+				mTop = top;
+		}
+		else
+			mTop = mLeft = 0;
+
+		// Register the window class
+        // NB Allow 4 bytes of window data for D3D7RenderWindow pointer
+        WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, WndProc, 0, 4, hInst,
+                              LoadIcon( NULL, IDI_APPLICATION ),
+                              LoadCursor(NULL, IDC_ARROW),
+                              (HBRUSH)GetStockObject(BLACK_BRUSH), NULL,
+                              TEXT(title.c_str()) };
+        RegisterClass( &wndClass );
+
+        // Create our main window
+        // Pass pointer to self
+        HWND hWnd = CreateWindow( TEXT(title.c_str()),
+                                  TEXT(title.c_str()),
+                                  dwStyle, mLeft, mTop,
+                                  mWidth, mHeight, 0L, 0L, hInst, this );
+
+		GetClientRect(hWnd,&rc);
+		mWidth = rc.right;
+		mHeight = rc.bottom;
+
+		ShowWindow( hWnd, SW_SHOWNORMAL );
+        UpdateWindow( hWnd );
+
+        mHWnd = hWnd;
+
+        // Store info
+        mName = name;
+        mWidth = width;
+        mHeight = height;
+        mIsDepthBuffered = depthBuffer;
+        mIsFullScreen = fullScreen;
+
+        if (fullScreen)
+        {
+            mColourDepth = colourDepth;
+            mLeft = 0;
+            mTop = 0;
+        }
+        else
+        {
+            // Get colour depth from display
+            HDC hdc = GetDC( mHWnd );
+            mColourDepth = GetDeviceCaps( hdc, BITSPIXEL );
+            ReleaseDC( mHWnd, hdc );
+            mTop = top;
+            mLeft = left;
+
+            // Record the dimensions of the blit location
+            GetClientRect( mHWnd, &rcBlitDest );
+            ClientToScreen( mHWnd, (POINT*)&rcBlitDest.left );
+            ClientToScreen( mHWnd, (POINT*)&rcBlitDest.right );
+        }
+
+        StringUtil::StrStreamType str;
+        str << "D3D7 : Created D3D7 Rendering Window '"
+            << mName << "' : " << mWidth << "x" << mHeight 
+            << ", " << mColourDepth << "bpp";
+        LogManager::getSingleton().logMessage(
+            LML_NORMAL, str.str());
+
+        // Set up DirectDraw if appropriate
+        // NB devices & surfaces set up for root window only
+        if (drv && mParentHWnd == NULL)
+        {
+            // DD Driver object passed
+            mlpDDDriver = drv;
+            mIsUsingDirectDraw = true;
+
+            createDDSurfaces();
+            // Get best device based on render bit depth
+            D3DDevice* dev = mlpDDDriver->get3DDeviceList()->getBest(mColourDepth);
+
+            // create D3D device for this window
+            mlpD3DDevice = dev->createDevice(mlpDDSBack);
+            createDepthBuffer();
+        }
+        else
+            mIsUsingDirectDraw = false;
+
+        mReady = true;
+    }
+
+    void D3D7RenderWindow::destroy(void)
+    {
+        if (mIsUsingDirectDraw)
+            releaseDDSurfaces();
+
+        DestroyWindow(mHWnd);
+
+    }
+
+    bool D3D7RenderWindow::isActive(void) const
+    {
+        return mActive;
+    }
+
+    bool D3D7RenderWindow::isClosed(void) const
+    {
+        return mClosed;
+    }
+
+    void D3D7RenderWindow::reposition(int left, int top)
+    {
+
+    }
+
+    void D3D7RenderWindow::resize(unsigned int width, unsigned int height)
+    {
+        mWidth = width;
+        mHeight = height;
+
+        // Notify viewports of resize
+        ViewportList::iterator it = mViewportList.begin();
+        while (it != mViewportList.end())
+            (*it++).second->_updateDimensions();
+
+        // TODO - resize window
+
+    }
+
+    void D3D7RenderWindow::swapBuffers(bool waitForVSync)
+    {
+        HRESULT hr;
+        DWORD flags;
+        if (mIsUsingDirectDraw)
+        {
+            if (mIsFullScreen)
+            {
+                // Use flipping chain
+                if (waitForVSync)
+                {
+                    flags = DDFLIP_WAIT;
+                }
+                else
+                {
+                    flags = DDFLIP_WAIT | DDFLIP_NOVSYNC;
+                }
+
+                hr = mlpDDSFront->Flip(NULL,flags);
+            }
+            else
+            {
+                // Ordinary Blit
+                RECT srcRect;
+                srcRect.left = 0;
+                srcRect.top = 0;
+                srcRect.right = rcBlitDest.right - rcBlitDest.left;
+                srcRect.bottom = rcBlitDest.bottom - rcBlitDest.top;
+                hr = mlpDDSFront->Blt(&rcBlitDest,mlpDDSBack,&srcRect,DDBLT_WAIT,NULL);
+            }
+
+            if (hr == DDERR_SURFACELOST)
+            {
+                // Restore surfaces
+                restoreDDSurfaces();
+            }
+            else if (FAILED(hr))
+            {
+                 OGRE_EXCEPT( 
+                     hr,
+                     "Error flipping surfaces", 
+                     "D3D7RenderWindow::swapBuffers" );
+            }
+        }
+
+    }
+
+    HWND D3D7RenderWindow::getWindowHandle(void) const
+    {
+        return mHWnd;
+    }
+
+    HWND D3D7RenderWindow::getParentWindowHandle(void) const
+    {
+        return mParentHWnd;
+    }
+
+    bool D3D7RenderWindow::isUsingDirectDraw(void) const
+    {
+        return mIsUsingDirectDraw;
+    }
+
+    // -------------------------------------------------------
+    //   DirectDraw specific methods
+    // -------------------------------------------------------
+    DDDriver* D3D7RenderWindow::getDirectDrawDriver(void)
+    {
+        return mlpDDDriver;
+    }
+
+    LPDIRECTDRAWSURFACE7 D3D7RenderWindow::getDDFrontBuffer(void)
+    {
+        return mlpDDSFront;
+
+    }
+
+    LPDIRECTDRAWSURFACE7 D3D7RenderWindow::getDDBackBuffer(void)
+    {
+        return mlpDDSBack;
+    }
+    LPDIRECT3DDEVICE7 D3D7RenderWindow::getD3DDevice(void)
+    {
+        return mlpD3DDevice;
+    }
+
+    void D3D7RenderWindow::createDDSurfaces(void)
+    {
+        // Use DirectDraw wrapper object to create surfaces
+        if( !mlpDDDriver )
+        {
+            OGRE_EXCEPT(
+            Exception::ERR_INVALIDPARAMS, 
+            "Cannot create surfaces because of no valid DirectDraw object",
+            "D3D7RenderWindow::createDDSurfaces" );
+        }
+
+        if( mIsFullScreen )
+        {
+            mlpDDDriver->createWindowSurfaces(
+                mHWnd, 
+                mWidth, mHeight, mColourDepth,
+                true, &mlpDDSFront, &mlpDDSBack);
+        }
+        else
+        {
+            // Windowed mode - need to use client rect for surface dimensions
+            // I.e. we need to ignore menu bars, borders, title bar etc
+            RECT rcClient;
+            unsigned int cWidth, cHeight;
+
+            GetClientRect( mHWnd, &rcClient );
+            ClientToScreen( mHWnd, (POINT*)&rcClient.left );
+            ClientToScreen( mHWnd, (POINT*)&rcClient.right );
+
+            cWidth  = rcClient.right - rcClient.left;
+            cHeight = rcClient.bottom - rcClient.top;
+
+            // Create surfaces (AND clipper)
+            mlpDDDriver->createWindowSurfaces(
+                mHWnd, 
+                cWidth, cHeight, 0,
+                false, &mlpDDSFront, &mlpDDSBack);
+
+            // Update own dimensions since target width / height is this
+            mWidth = cWidth;
+            mHeight = cHeight;
+        }
+    }
+
+    void D3D7RenderWindow::createDepthBuffer(void)
+    {
+        // Get best device based on render bit depth
+        D3DDevice* dev = mlpDDDriver->get3DDeviceList()->getBest(mColourDepth);
+        if (mIsDepthBuffered && dev->NeedsZBuffer())
+        {
+            // Create Z buffer
+            dev->createDepthBuffer(mlpDDSBack);
+            // Don't set z buffer params here, leave to material
+        }
+    }
+
+    void D3D7RenderWindow::releaseDDSurfaces(void)
+    {
+        // Release Z-buffer
+        HRESULT hr;
+        DDSCAPS2 ddscaps;
+
+        ZeroMemory(&ddscaps, sizeof(DDSCAPS2));
+        ddscaps.dwCaps = DDSCAPS_ZBUFFER;
+
+        LPDIRECTDRAWSURFACE7 zBufSurface;
+
+        hr = mlpDDSBack->GetAttachedSurface( &ddscaps, &zBufSurface );
+
+        // Release twice as this method has increased
+        zBufSurface->Release();
+        zBufSurface->Release();
+
+        // Release std buffers
+        mlpDDSBack->Release();
+        mlpDDSFront->Release();
+
+        mlpDDSBack = mlpDDSFront = 0;
+    }
+
+    void D3D7RenderWindow::restoreDDSurfaces(void)
+    {
+        HRESULT hr;
+
+        if( mlpDDSFront->IsLost() )
+        {
+            hr = mlpDDSFront->Restore();
+
+            if( FAILED( hr ) )
+                OGRE_EXCEPT( 
+                    Exception::ERR_INTERNAL_ERROR, 
+                    "Error restoring lost primary surface.", 
+                    "D3D7RenderWindow - restoreDDSurfaces" );
+        }
+
+        if( mlpDDSBack->IsLost() )
+        {
+            hr = mlpDDSBack->Restore();
+
+            if( FAILED( hr ) )
+                OGRE_EXCEPT( 
+                    Exception::ERR_INTERNAL_ERROR, 
+                    "Error restoring lost back buffer surface.", 
+                    "D3D7RenderWindow - restoreDDSurfaces" );
+        }
+    }
+
+    void D3D7RenderWindow::windowMovedOrResized(void)
+    {
+        // If windowed mode, check window size & position
+        RECT rcCheck;
+
+        if( mIsFullScreen )
+            return; // Nothing to check
+
+        GetClientRect( mHWnd, &rcCheck );
+        ClientToScreen( mHWnd, (POINT*)&rcCheck.left );
+        ClientToScreen( mHWnd, (POINT*)&rcCheck.right );
+
+        // Has the window resized? If so, we need to recreate surfaces
+        if( ( rcCheck.right - rcCheck.left != 
+                rcBlitDest.right - rcBlitDest.left ) ||
+            ( rcCheck.bottom - rcCheck.top !=
+                rcBlitDest.bottom - rcBlitDest.top ) )
+        {
+            // The window has changed size - DD surfaces must be recreated
+            releaseDDSurfaces();
+            createDDSurfaces();
+            createDepthBuffer();
+
+            // Update Viewport Sizes
+            
+            for( 
+                ViewportList::iterator it = mViewportList.begin();
+                it != mViewportList.end(); 
+                ++it )
+            {
+                it->second->_updateDimensions();
+            }
+
+            rcBlitDest = rcCheck;
+        }
+        else if( 
+            rcCheck.left != rcBlitDest.left ||
+            rcCheck.top  != rcBlitDest.top )
+        {
+            // Window has only moved
+            // Just alter the blit location
+            rcBlitDest = rcCheck;
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    void D3D7RenderWindow::getCustomAttribute( const String& name, void* pData )
+    {
+        // Valid attributes and their equivalent native functions:
+        // D3DDEVICE            : getD3DDeviceDriver
+        // DDBACKBUFFER         : getDDBackBuffer
+        // DDFRONTBUFFER        : getDDFrontBuffer
+        // HWND                 : getWindowHandle
+
+        if( name == "D3DDEVICE" )
+        {
+            LPDIRECT3DDEVICE7 *pDev = (LPDIRECT3DDEVICE7*)pData;
+
+            *pDev = getD3DDevice();
+            return;
+        }
+        else if( name == "DDBACKBUFFER" )
+        {
+            LPDIRECTDRAWSURFACE7 *pSurf = (LPDIRECTDRAWSURFACE7*)pData;
+
+            *pSurf = getDDBackBuffer();
+            return;
+        }
+        else if( name == "DDFRONTBUFFER" )
+        {
+            LPDIRECTDRAWSURFACE7 *pSurf = (LPDIRECTDRAWSURFACE7*)pData;
+
+            *pSurf = getDDFrontBuffer();
+            return;
+        }
+        else if( name == "HWND" )
+        {
+            HWND *pHwnd = (HWND*)pData;
+
+            *pHwnd = getWindowHandle();
+            return;
+        }
+        else if( name == "isTexture" )
+        {
+            bool *b = reinterpret_cast< bool * >( pData );
+            *b = false;
+
+            return;
+        }
+    }
+
+
+    void D3D7RenderWindow::writeContentsToFile(const String& filename)
+    {
+         HRESULT hr;
+         LPDIRECTDRAWSURFACE7 pTempSurf;
+         DDSURFACEDESC2 desc;
+         RECT srcRect;
+ 
+         // Cannot lock surface direct, so create temp surface and blit
+         memset(&desc, 0, sizeof (DDSURFACEDESC2));
+		 desc.dwSize = sizeof(DDSURFACEDESC2);
+         if (FAILED(hr = mlpDDSBack->GetSurfaceDesc(&desc)))
+         {
+	         OGRE_EXCEPT(hr, "Error getting description of back buffer!", 
+                 "D3D7RenderWindow::writeContentsToFile");
+         }
+
+         desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+         desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+
+		 if (FAILED(hr = mlpDDDriver->directDraw()->CreateSurface(&desc, &pTempSurf, NULL)))
+		 {
+             OGRE_EXCEPT(hr, "Error creating temporary surface!", 
+                 "D3D7RenderWindow::writeContentsToFile");
+		 }
+
+         if (mIsFullScreen)
+		 {
+         	pTempSurf->Blt(NULL, mlpDDSFront, NULL, NULL, NULL);
+		 }
+         else
+         {
+         	GetWindowRect(mHWnd, &srcRect);
+            srcRect.left += GetSystemMetrics(SM_CXSIZEFRAME);
+            srcRect.top += GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
+            srcRect.right = srcRect.left + desc.dwWidth;
+            srcRect.bottom = srcRect.top + desc.dwHeight;
+
+            pTempSurf->Blt(NULL, mlpDDSFront, &srcRect, NULL, NULL);
+         }
+
+		 if (FAILED(hr = pTempSurf->Lock(NULL, &desc,  
+             DDLOCK_WAIT | DDLOCK_READONLY, NULL)))
+         {
+             OGRE_EXCEPT(hr, "Cannot lock surface!", 
+                 "D3D7RenderWindow::writeContentsToFile");
+         }
+ 
+ 
+         ImageCodec::ImageData *imgData = new ImageCodec::ImageData();
+         imgData->width = desc.dwWidth;
+         imgData->height = desc.dwHeight;
+         imgData->format = PF_BYTE_RGB;
+ 
+         // Allocate contiguous buffer (surfaces aren't necessarily contiguous)
+         uchar* pBuffer = new uchar[desc.dwWidth * desc.dwHeight * 3];
+ 
+         uint x, y;
+         uchar *pData, *pDest;
+ 
+         pData = (uchar*)desc.lpSurface;
+         pDest = pBuffer;
+         for (y = 0; y < desc.dwHeight; ++y)
+         {
+             uchar *pRow = pData;
+ 
+             for (x = 0; x < desc.dwWidth; ++x)
+             {
+				 if (desc.ddpfPixelFormat.dwRGBBitCount == 16)
+				 {
+                     WORD val;
+ 
+                     val = *((WORD*)pRow);
+					 pRow += 2;
+
+					 *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0xF800, (BYTE)0xFF);
+					 *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x07E0, (BYTE)0xFF);
+					 *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x001F, (BYTE)0xFF);
+				 }
+				 else
+				 {
+					 // Actual format is BRGA for some reason
+                     *pDest++ = pRow[2]; // R
+                     *pDest++ = pRow[1]; // G
+                     *pDest++ = pRow[0]; // B
+
+                     pRow += 3; // skip alpha / dummy
+
+					 if (desc.ddpfPixelFormat.dwRGBBitCount == 32)
+					 {
+						 ++pRow; // Skip alpha
+					 }
+                 }
+ 
+                 
+             }
+             // increase by one line
+             pData += desc.lPitch;
+ 
+         }
+ 
+ 
+         // Wrap buffer in a chunk
+         MemoryDataStreamPtr stream(new MemoryDataStream(pBuffer, desc.dwWidth * desc.dwHeight * 3, false));
+ 
+         // Get codec 
+         size_t pos = filename.find_last_of(".");
+         String extension;
+ 	    if( pos == String::npos )
+             OGRE_EXCEPT(
+ 		    Exception::ERR_INVALIDPARAMS, 
+ 		    "Unable to determine image type for '" + filename + "' - invalid extension.",
+             "D3D8RenderWindow::writeContentsToFile" );
+ 
+         while( pos != filename.length() - 1 )
+             extension += filename[++pos];
+ 
+         // Get the codec
+         Codec * pCodec = Codec::getCodec(extension);
+ 
+         // Write out
+         pCodec->codeToFile(stream, filename, Codec::CodecDataPtr(imgData));
+ 
+         delete [] pBuffer;
+		 pTempSurf->Release();
+ 
+     }
+
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	uchar* D3D7RenderWindow::getBufferContents(int &dimx, int &dimy)
+    {
+         HRESULT hr;
+         LPDIRECTDRAWSURFACE7 pTempSurf;
+         DDSURFACEDESC2 desc;
+         RECT srcRect;
+ 
+         // Cannot lock surface direct, so create temp surface and blit
+         memset(&desc, 0, sizeof (DDSURFACEDESC2));
+		 desc.dwSize = sizeof(DDSURFACEDESC2);
+         if (FAILED(hr = mlpDDSBack->GetSurfaceDesc(&desc)))
+         {
+	         OGRE_EXCEPT(hr, "Error getting description of back buffer!", 
+                 "D3D7RenderWindow::writeContentsToFile");
+         }
+
+         desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+         desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+
+		 if (FAILED(hr = mlpDDDriver->directDraw()->CreateSurface(&desc, &pTempSurf, NULL)))
+		 {
+             OGRE_EXCEPT(hr, "Error creating temporary surface!", 
+                 "D3D7RenderWindow::writeContentsToFile");
+		 }
+
+         if (mIsFullScreen)
+		 {
+         	pTempSurf->Blt(NULL, mlpDDSFront, NULL, NULL, NULL);
+		 }
+         else
+         {
+         	GetWindowRect(mHWnd, &srcRect);
+            srcRect.left += GetSystemMetrics(SM_CXSIZEFRAME);
+            srcRect.top += GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
+            srcRect.right = srcRect.left + desc.dwWidth;
+            srcRect.bottom = srcRect.top + desc.dwHeight;
+
+            pTempSurf->Blt(NULL, mlpDDSFront, &srcRect, NULL, NULL);
+         }
+
+		 if (FAILED(hr = pTempSurf->Lock(NULL, &desc,  
+             DDLOCK_WAIT | DDLOCK_READONLY, NULL)))
+         {
+             OGRE_EXCEPT(hr, "Cannot lock surface!", 
+                 "D3D7RenderWindow::writeContentsToFile");
+         }
+ 
+         dimx = desc.dwWidth;
+         dimy = desc.dwHeight;
+         
+ 
+         // Allocate contiguous buffer (surfaces aren't necessarily contiguous)
+         uchar* pBuffer = new uchar[desc.dwWidth * desc.dwHeight * 3];
+ 
+         uint x, y;
+         uchar *pData, *pDest;
+ 
+         pData = (uchar*)desc.lpSurface;
+         pDest = pBuffer;
+         for (y = 0; y < desc.dwHeight; ++y)
+         {
+             uchar *pRow = pData;
+ 
+             for (x = 0; x < desc.dwWidth; ++x)
+             {
+				 if (desc.ddpfPixelFormat.dwRGBBitCount == 16)
+				 {
+                     WORD val;
+ 
+                     val = *((WORD*)pRow);
+					 pRow += 2;
+
+					 *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0xF800, (BYTE)0xFF);
+					 *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x07E0, (BYTE)0xFF);
+					 *pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x001F, (BYTE)0xFF);
+				 }
+				 else
+				 {
+					 // Actual format is BRGA for some reason
+                     *pDest++ = pRow[2]; // R
+                     *pDest++ = pRow[1]; // G
+                     *pDest++ = pRow[0]; // B
+
+                     pRow += 3; // skip alpha / dummy
+
+					 if (desc.ddpfPixelFormat.dwRGBBitCount == 32)
+					 {
+						 ++pRow; // Skip alpha
+					 }
+                 }
+ 
+                 
+             }
+             // increase by one line
+             pData += desc.lPitch;
+ 
+         }
+ 
+		 pTempSurf->Release();
+
+		 return pBuffer;
+
+     }
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+}
+
Index: trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/include/OgreD3D9Texture.h
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/include/OgreD3D9Texture.h	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/include/OgreD3D9Texture.h	(revision 153)
@@ -0,0 +1,328 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+-----------------------------------------------------------------------------
+*/
+#ifndef __D3D8TEXTURE_H__
+#define __D3D8TEXTURE_H__
+
+#include "OgreD3D9Prerequisites.h"
+#include "OgreTexture.h"
+#include "OgreRenderTexture.h"
+#include "OgreImage.h"
+#include "OgreException.h"
+#include "OgreD3D9HardwarePixelBuffer.h"
+
+#include "OgreNoMemoryMacros.h"
+#include <d3d9.h>
+#include <d3dx9.h>
+#include <dxerr9.h>
+#include "OgreMemoryMacros.h"
+
+namespace Ogre {
+	class D3D9Texture : public Texture
+	{
+	protected:
+		/// D3DDevice pointer
+		IDirect3DDevice9		*mpDev;		
+		/// D3D9 pointer
+		IDirect3D9				*mpD3D;
+		/// 1D/2D normal texture pointer
+		IDirect3DTexture9		*mpNormTex;	
+		/// cubic texture pointer
+		IDirect3DCubeTexture9	*mpCubeTex;	
+        /// Volume texture
+        IDirect3DVolumeTexture9 *mpVolumeTex;
+        /// z-buffer for the render surface pointer
+		IDirect3DSurface9		*mpZBuff;	
+		/// actual texture pointer
+		IDirect3DBaseTexture9	*mpTex;		
+
+		/// cube texture individual face names
+		String							mCubeFaceNames[6];
+		/// device creation parameters
+		D3DDEVICE_CREATION_PARAMETERS	mDevCreParams;
+		/// back buffer pixel format
+		D3DFORMAT						mBBPixelFormat;
+		/// The memory pool being used
+		D3DPOOL							mD3DPool;
+		/// device capabilities pointer
+		D3DCAPS9						mDevCaps;
+        // Auto-generated mipmaps?
+        bool                            mAutoGenMipmaps;
+		// Dynamic textures?
+		bool                            mDynamicTextures;
+		/// Vector of pointers to subsurfaces
+		typedef std::vector<HardwarePixelBufferSharedPtr> SurfaceList;
+		SurfaceList						mSurfaceList;
+	
+        /// Initialise the device and get formats
+        void _initDevice(void);
+		/// internal method, load a cube texture
+		void _loadCubeTex();
+		/// internal method, load a normal texture
+		void _loadNormTex();
+		/// internal method, load a volume texture
+		void _loadVolumeTex();
+
+		/// internal method, create a blank normal 1D/2D texture
+		void _createNormTex();
+		/// internal method, create a blank cube texture
+		void _createCubeTex();
+		/// internal method, create a blank cube texture
+		void _createVolumeTex();
+
+		/// internal method, return a D3D pixel format for texture creation
+		D3DFORMAT _chooseD3DFormat();
+
+		/// internal method, free D3D9 resources
+		void _freeResources();
+		/// internal method, set Texture class source image protected attributes
+		void _setSrcAttributes(unsigned long width, unsigned long height, unsigned long depth, PixelFormat format);
+		/// internal method, set Texture class final texture protected attributes
+		void _setFinalAttributes(unsigned long width, unsigned long height, unsigned long depth, PixelFormat format);
+		/// internal method, return the best by hardware supported filter method
+		D3DTEXTUREFILTERTYPE _getBestFilterMethod();
+		/// internal method, return true if the device/texture combination can use dynamic textures
+		bool _canUseDynamicTextures(DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat);
+		/// internal method, return true if the device/texture combination can auto gen. mip maps
+		bool _canAutoGenMipmaps(DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat);
+		/// internal method, create a depth stencil for the render target texture
+		void _createDepthStencil();
+
+		/// internal method, the cube map face name for the spec. face index
+		String _getCubeFaceName(unsigned char face) const
+		{ assert(face < 6); return mCubeFaceNames[face]; }
+		
+		/// internal method, create D3D9HardwarePixelBuffers for every face and
+		/// mipmap level. This method must be called after the D3D texture object was created
+		void _createSurfaceList(bool updateOldList=false);
+
+        /// overriden from Resource
+        void loadImpl();
+        /// overriden from Resource
+        void unloadImpl();
+	public:
+		/// constructor 
+        D3D9Texture(ResourceManager* creator, const String& name, ResourceHandle handle,
+            const String& group, bool isManual, ManualResourceLoader* loader, 
+            IDirect3DDevice9 *pD3DDevice);
+		/// destructor
+		~D3D9Texture();
+
+		/// overriden from Texture
+		void copyToTexture( TexturePtr& target );
+		/// overriden from Texture
+		void loadImage( const Image &img );
+
+        /// @copydoc Texture::createInternalResources
+        void createInternalResources(void);
+
+		/// @copydoc Texture::getBuffer
+		HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap);
+		
+		/// retrieves a pointer to the actual texture
+		IDirect3DBaseTexture9 *getTexture() 
+		{ assert(mpTex); return mpTex; }
+		/// retrieves a pointer to the normal 1D/2D texture
+		IDirect3DTexture9 *getNormTexture()
+		{ assert(mpNormTex); return mpNormTex; }
+		/// retrieves a pointer to the cube texture
+		IDirect3DCubeTexture9 *getCubeTexture()
+		{ assert(mpCubeTex); return mpCubeTex; }
+		/// retrieves a pointer to the Depth stencil
+		IDirect3DSurface9 *getDepthStencil() 
+		{ assert(mpZBuff); return mpZBuff; }
+		
+		/// utility method, convert D3D9 pixel format to Ogre pixel format
+		static PixelFormat _getPF(D3DFORMAT d3dPF);
+		/// utility method, convert Ogre pixel format to D3D9 pixel format
+		static D3DFORMAT _getPF(PixelFormat ogrePF);
+		/// utility method, find closest Ogre pixel format that D3D9 can support
+		static PixelFormat _getClosestSupportedPF(PixelFormat ogrePF);
+
+		/// For dealing with lost devices - release the resource if in the default pool
+		void releaseIfDefaultPool(void);
+		/// For dealing with lost devices - recreate the resource if in the default pool
+		void recreateIfDefaultPool(LPDIRECT3DDEVICE9 pDev);
+
+    };
+
+    /** Specialisation of SharedPtr to allow SharedPtr to be assigned to D3D9TexturePtr 
+    @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 D3D9TexturePtr : public SharedPtr<D3D9Texture> 
+    {
+    public:
+        D3D9TexturePtr() : SharedPtr<D3D9Texture>() {}
+        explicit D3D9TexturePtr(D3D9Texture* rep) : SharedPtr<D3D9Texture>(rep) {}
+        D3D9TexturePtr(const D3D9TexturePtr& r) : SharedPtr<D3D9Texture>(r) {} 
+        D3D9TexturePtr(const ResourcePtr& r) : SharedPtr<D3D9Texture>()
+        {
+			// lock & copy other mutex pointer
+			OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
+			OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
+            pRep = static_cast<D3D9Texture*>(r.getPointer());
+            pUseCount = r.useCountPointer();
+            if (pUseCount)
+            {
+                ++(*pUseCount);
+            }
+        }
+
+        /// Operator used to convert a ResourcePtr to a D3D9TexturePtr
+        D3D9TexturePtr& operator=(const ResourcePtr& r)
+        {
+            if (pRep == static_cast<D3D9Texture*>(r.getPointer()))
+                return *this;
+            release();
+			// lock & copy other mutex pointer
+			OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
+			OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
+            pRep = static_cast<D3D9Texture*>(r.getPointer());
+            pUseCount = r.useCountPointer();
+            if (pUseCount)
+            {
+                ++(*pUseCount);
+            }
+            return *this;
+        }
+        /// Operator used to convert a TexturePtr to a D3D9TexturePtr
+        D3D9TexturePtr& operator=(const TexturePtr& r)
+        {
+            if (pRep == static_cast<D3D9Texture*>(r.getPointer()))
+                return *this;
+            release();
+			// lock & copy other mutex pointer
+			OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
+			OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
+            pRep = static_cast<D3D9Texture*>(r.getPointer());
+            pUseCount = r.useCountPointer();
+            if (pUseCount)
+            {
+                ++(*pUseCount);
+            }
+            return *this;
+        }
+    };
+
+
+    /// RenderTexture implementation for D3D9
+    class D3D9RenderTexture : public RenderTexture
+    {
+    public:
+        D3D9RenderTexture( const String & name, 
+			unsigned int width, unsigned int height,
+			TextureType texType, PixelFormat internalFormat, 
+			const NameValuePairList *miscParams ) 
+			: RenderTexture( name, width, height, texType, internalFormat )
+        {
+            mPrivateTex = TextureManager::getSingleton().createManual
+                (mName + "_PRIVATE##", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
+                texType, mWidth, mHeight, 0, internalFormat, TU_RENDERTARGET );
+        }
+		
+        ~D3D9RenderTexture()
+        {
+			mPrivateTex->unload();
+			TextureManager::getSingleton().remove(mPrivateTex->getName());
+			
+        }
+
+		virtual void getCustomAttribute( const String& name, void *pData )
+        {
+			if( name == "DDBACKBUFFER" )
+            {
+                IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData;
+				if (mPrivateTex->getTextureType() == TEX_TYPE_2D)
+					mPrivateTex->getNormTexture()->GetSurfaceLevel( 0, &(*pSurf) );
+				else if (mPrivateTex->getTextureType() == TEX_TYPE_CUBE_MAP)
+					mPrivateTex->getCubeTexture()->GetCubeMapSurface( (D3DCUBEMAP_FACES)0, 0, &(*pSurf) );
+				else
+				{
+					OGRE_EXCEPT( Exception::UNIMPLEMENTED_FEATURE, 
+							"getCustomAttribute is implemented only for 2D and cube textures !!!", 
+							"D3D9RenderTexture::getCustomAttribute" );
+				}
+				// decrement reference count
+                (*pSurf)->Release();
+                return;
+            }
+            else if( name == "D3DZBUFFER" )
+            {
+                IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData;
+                *pSurf = mPrivateTex->getDepthStencil();
+                return;
+            }
+            else if( name == "DDFRONTBUFFER" )
+            {
+                IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData;
+				if (mPrivateTex->getTextureType() == TEX_TYPE_2D)
+					mPrivateTex->getNormTexture()->GetSurfaceLevel( 0, &(*pSurf) );
+				else if (mPrivateTex->getTextureType() == TEX_TYPE_CUBE_MAP)
+					mPrivateTex->getCubeTexture()->GetCubeMapSurface( (D3DCUBEMAP_FACES)0, 0, &(*pSurf) );
+				else
+				{
+					OGRE_EXCEPT( Exception::UNIMPLEMENTED_FEATURE, 
+							"getCustomAttribute is implemented only for 2D and cube textures !!!", 
+							"D3D9RenderTexture::getCustomAttribute" );
+				}
+                (*pSurf)->Release();
+                return;
+            }
+            else if( name == "HWND" )
+            {
+                HWND *pHwnd = (HWND*)pData;
+                *pHwnd = NULL;
+                return;
+            }
+            else if( name == "isTexture" )
+            {
+                bool *b = reinterpret_cast< bool * >( pData );
+                *b = true;
+                return;
+            }
+        }
+
+		bool requiresTextureFlipping() const { return false; }
+        virtual void writeContentsToFile( const String & filename ) {}
+
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+		uchar *getBufferContents(int &dimx, int &dimy) { return NULL; };
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+
+    protected:
+        /// The texture to which rendering takes place.
+        D3D9TexturePtr mPrivateTex;
+		
+        virtual void _copyToTexture()
+        {
+            // Copy the newly-rendered data to the public texture surface.
+            mPrivateTex->copyToTexture( mTexture );
+        }
+    };
+}
+
+#endif
Index: trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h	(revision 153)
@@ -0,0 +1,119 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+-----------------------------------------------------------------------------
+*/
+#ifndef __D3D9RENDERWINDOW_H__
+#define __D3D9RENDERWINDOW_H__
+
+#include "OgreD3D9Prerequisites.h"
+#include "OgreRenderWindow.h"
+#include "OgreD3D9Driver.h"
+
+namespace Ogre 
+{
+	class D3D9RenderWindow : public RenderWindow
+	{
+	public:
+		/** Constructor.
+		@param instance The application instance
+		@param driver The root driver
+		@param deviceIfSwapChain The existing D3D device to create an additional swap chain from, if this is not
+			the first window.
+		*/
+		D3D9RenderWindow(HINSTANCE instance, D3D9Driver *driver, LPDIRECT3DDEVICE9 deviceIfSwapChain = 0);
+		~D3D9RenderWindow();
+		void create(const String& name, unsigned int width, unsigned int height,
+	            bool fullScreen, const NameValuePairList *miscParams);
+		void destroy(void);
+		bool isActive() const { return mActive; }
+		bool isClosed() const { return mClosed; }
+		void reposition( int left, int top ) {}
+		void resize( unsigned int width, unsigned int height );
+		void swapBuffers( bool waitForVSync = true );
+		HWND getWindowHandle() const { return mHWnd; }
+
+		D3D9Driver* getDirectD3DDriver() { return mDriver; }
+		// changed to access driver member
+		LPDIRECT3DDEVICE9 getD3DDevice() { return mDriver->getD3DDevice(); }
+
+		void getCustomAttribute( const String& name, void* pData );
+		/** Overridden - see RenderTarget.
+		*/
+		void writeContentsToFile(const String& filename);
+
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+		uchar *getBufferContents(int &dimx, int &dimy);
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+
+		bool requiresTextureFlipping() const { return false; }
+
+		// Method for dealing with resize / move & 3d library
+		virtual void WindowMovedOrResized(void);
+
+		bool isReady() const { return mReady; }
+		void setReady(bool set) { mReady = set; }
+		void setActive(bool set) { mActive = set; }
+		/// Get the presentation parameters used with this window
+		D3DPRESENT_PARAMETERS* getPresentationParameters(void) 
+		{ return &md3dpp; }
+		/// @copydoc RenderTarget::update
+		void update(void);
+
+		/** Create (or recreate) the D3D device or SwapChain for this window.
+		*/
+		void createD3DResources(void);
+	
+	protected:
+		HINSTANCE mInstance;			// Process instance
+		D3D9Driver *mDriver;			// D3D9 driver
+		HWND	mHWnd;					// Win32 Window handle
+		bool	mActive;				// Is active i.e. visible
+		bool	mReady;					// Is ready i.e. available for update
+		bool	mClosed;
+		bool	mIsSwapChain;			// Is this a secondary window?
+
+		static LRESULT CALLBACK WndProc(
+			HWND hWnd,
+			UINT uMsg,
+			WPARAM wParam,
+			LPARAM lParam );
+
+		// -------------------------------------------------------
+		// DirectX-specific
+		// -------------------------------------------------------
+
+		// Pointer to swap chain, only valid if mIsSwapChain
+		LPDIRECT3DSWAPCHAIN9 mpSwapChain;
+		D3DPRESENT_PARAMETERS md3dpp;
+		LPDIRECT3DSURFACE9 mpRenderSurface;
+		LPDIRECT3DSURFACE9 mpRenderZBuffer;
+		D3DMULTISAMPLE_TYPE mFSAAType;
+		DWORD mFSAAQuality;
+		bool mVSync;
+
+		// just check if the multisampling requested is supported by the device
+		bool _checkMultiSampleQuality(D3DMULTISAMPLE_TYPE type, DWORD *outQuality, D3DFORMAT format, UINT adapterNum, D3DDEVTYPE deviceType, BOOL fullScreen);
+
+	};
+}
+#endif
Index: trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp	(revision 153)
+++ trunk/VUT/work/ogre_changes/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp	(revision 153)
@@ -0,0 +1,1063 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2005 The OGRE Team
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+-----------------------------------------------------------------------------
+*/
+#include "OgreD3D9RenderWindow.h"
+#include "OgreLogManager.h"
+#include "OgreViewport.h"
+#include "OgreException.h"
+#include "OgreD3D9RenderSystem.h"
+#include "OgreRenderSystem.h"
+#include "OgreBitwise.h"
+#include "OgreImageCodec.h"
+#include "OgreStringConverter.h"
+
+#include "OgreNoMemoryMacros.h"
+#include <d3d9.h>
+#include "OgreMemoryMacros.h"
+#include "OgreRoot.h"
+
+namespace Ogre
+{
+	// Window procedure callback
+	// This is a static member, so applies to all windows but we store the
+	// D3D9RenderWindow instance in the window data GetWindowLog/SetWindowLog
+	LRESULT D3D9RenderWindow::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+	{
+		LPCREATESTRUCT lpcs;
+		D3D9RenderWindow* win;
+
+		// look up window instance
+		if( WM_CREATE != uMsg )
+			// Get window pointer
+			win = (D3D9RenderWindow*)GetWindowLong( hWnd, 0 );
+
+		switch( uMsg )
+		{
+		case WM_ACTIVATE:
+			if( WA_INACTIVE == LOWORD( wParam ) )
+				win->mActive = false;
+			else
+				win->mActive = true;
+			break;
+
+		case WM_CREATE:
+			// Log the new window
+			// Get CREATESTRUCT
+			lpcs = (LPCREATESTRUCT)lParam;
+			win = (D3D9RenderWindow*)(lpcs->lpCreateParams);
+			// Store pointer in window user data area
+			SetWindowLong( hWnd, 0, (long)win );
+			win->mActive = true;
+
+			return 0;
+			break;
+
+		case WM_KEYDOWN:
+			// TEMPORARY CODE
+			// TODO - queue up keydown / keyup events with
+			//  window name and timestamp to be processed
+			//  by main loop
+
+			// ESCAPE closes window
+			/*
+			if (wParam == VK_ESCAPE)
+			{
+			win->mClosed = true;
+			return 0L;
+			}
+			*/
+			break;
+
+		case WM_PAINT:
+			// If we get WM_PAINT messges, it usually means our window was
+			// comvered up, so we need to refresh it by re-showing the contents
+			// of the current frame.
+			if( win->mActive && win->mReady )
+				win->update();
+			break;
+
+		case WM_MOVE:
+			// Move messages need to be tracked to update the screen rects
+			// used for blitting the backbuffer to the primary
+			// *** This doesn't need to be used to Direct3D9 ***
+			break;
+
+		case WM_ENTERSIZEMOVE:
+			// Previent rendering while moving / sizing
+			win->mReady = false;
+			break;
+
+		case WM_EXITSIZEMOVE:
+			win->WindowMovedOrResized();
+			win->mReady = true;
+			break;
+
+		case WM_SIZE:
+			// Check to see if we are losing or gaining our window.  Set the 
+			// active flag to match
+			if( SIZE_MAXHIDE == wParam || SIZE_MINIMIZED == wParam )
+				win->mActive = false;
+			else
+			{
+				win->mActive = true;
+				if( win->mReady )
+					win->WindowMovedOrResized();
+			}
+			break;
+
+		case WM_GETMINMAXINFO:
+			// Prevent the window from going smaller than some minimu size
+			((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
+			((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
+			break;
+
+		case WM_CLOSE:
+			DestroyWindow( win->mHWnd );
+			win->mClosed = true;
+			return 0;
+		}
+
+		return DefWindowProc( hWnd, uMsg, wParam, lParam );
+	}
+
+	D3D9RenderWindow::D3D9RenderWindow(HINSTANCE instance, D3D9Driver *driver, LPDIRECT3DDEVICE9 deviceIfSwapChain):
+		mInstance(instance),
+		mDriver(driver)
+	{
+		mIsFullScreen = false;
+		mIsSwapChain = deviceIfSwapChain != NULL;
+		mHWnd = 0;
+		mActive = false;
+		mReady = false;
+		mClosed = false;
+	}
+
+	D3D9RenderWindow::~D3D9RenderWindow()
+	{
+		// access and update device through driver, realse only primary
+		if (!mIsSwapChain) 
+		{
+			LPDIRECT3DDEVICE9 mpD3DDevice = mDriver->getD3DDevice();
+			SAFE_RELEASE( mpD3DDevice );
+			mDriver->setD3DDevice( mpD3DDevice );
+		}
+	}
+
+	bool D3D9RenderWindow::_checkMultiSampleQuality(D3DMULTISAMPLE_TYPE type, DWORD *outQuality, D3DFORMAT format, UINT adapterNum, D3DDEVTYPE deviceType, BOOL fullScreen)
+	{
+		LPDIRECT3D9 pD3D = mDriver->getD3D();
+
+		if (SUCCEEDED(pD3D->CheckDeviceMultiSampleType(
+				adapterNum, 
+				deviceType, format, 
+				fullScreen, type, outQuality)))
+			return true;
+		else
+			return false;
+	}
+
+	void D3D9RenderWindow::create(const String& name, unsigned int width, unsigned int height,
+	            bool fullScreen, const NameValuePairList *miscParams)
+	{
+		HINSTANCE hInst = mInstance;
+		D3D9Driver* driver = mDriver;
+		
+		HWND parentHWnd = 0;
+		HWND externalHandle = 0;
+		mFSAAType = D3DMULTISAMPLE_NONE;
+		mFSAAQuality = 0;
+		mVSync = false;
+		unsigned int displayFrequency = 0;
+		String title = name;
+		unsigned int colourDepth = 32;
+		unsigned int left = 0; // Defaults to screen center
+		unsigned int top = 0; // Defaults to screen center
+		bool depthBuffer = true;
+		
+		if(miscParams)
+		{
+			// Get variable-length params
+			NameValuePairList::const_iterator opt;
+			// left (x)
+			opt = miscParams->find("left");
+			if(opt != miscParams->end())
+				left = StringConverter::parseUnsignedInt(opt->second);
+			// top (y)
+			opt = miscParams->find("top");
+			if(opt != miscParams->end())
+				top = StringConverter::parseUnsignedInt(opt->second);
+			// Window title
+			opt = miscParams->find("title");
+			if(opt != miscParams->end())
+				title = opt->second;
+			// externalWindowHandle		-> externalHandle
+			opt = miscParams->find("externalWindowHandle");
+			if(opt != miscParams->end())
+				externalHandle = (HWND)StringConverter::parseUnsignedInt(opt->second);
+			// vsync	[parseBool]
+			opt = miscParams->find("vsync");
+			if(opt != miscParams->end())
+				mVSync = StringConverter::parseBool(opt->second);
+			// displayFrequency
+			opt = miscParams->find("displayFrequency");
+			if(opt != miscParams->end())
+				displayFrequency = StringConverter::parseUnsignedInt(opt->second);
+			// colourDepth
+			opt = miscParams->find("colourDepth");
+			if(opt != miscParams->end())
+				colourDepth = StringConverter::parseUnsignedInt(opt->second);
+			// depthBuffer [parseBool]
+			opt = miscParams->find("depthBuffer");
+			if(opt != miscParams->end())
+				depthBuffer = StringConverter::parseBool(opt->second);
+			// FSAA type
+			opt = miscParams->find("FSAA");
+			if(opt != miscParams->end())
+				mFSAAType = (D3DMULTISAMPLE_TYPE)StringConverter::parseUnsignedInt(opt->second);
+			// FSAA quality
+			opt = miscParams->find("FSAAQuality");
+			if(opt != miscParams->end())
+				mFSAAQuality = StringConverter::parseUnsignedInt(opt->second);
+		}
+		
+		// Destroy current window if any
+		if( mHWnd )
+			destroy();
+
+
+		if (!externalHandle)
+		{
+			DWORD dwStyle = (fullScreen ? WS_POPUP : WS_OVERLAPPEDWINDOW) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+			RECT rc;
+
+			mWidth = width;
+			mHeight = height;
+
+			if (!fullScreen)
+			{
+				// Calculate window dimensions required to get the requested client area
+				SetRect(&rc, 0, 0, mWidth, mHeight);
+				AdjustWindowRect(&rc, dwStyle, false);
+				mWidth = rc.right - rc.left;
+				mHeight = rc.bottom - rc.top;
+
+				// Clamp width and height to the desktop dimensions
+				if (mWidth > (unsigned)GetSystemMetrics(SM_CXSCREEN))
+					mWidth = (unsigned)GetSystemMetrics(SM_CXSCREEN);
+				if (mHeight > (unsigned)GetSystemMetrics(SM_CYSCREEN))
+					mHeight = (unsigned)GetSystemMetrics(SM_CYSCREEN);
+
+				if (!left)
+					mLeft = (GetSystemMetrics(SM_CXSCREEN) / 2) - (mWidth / 2);
+				else
+					mLeft = left;
+				if (!top)
+					mTop = (GetSystemMetrics(SM_CYSCREEN) / 2) - (mHeight / 2);
+				else
+					mTop = top;
+			}
+			else
+				mTop = mLeft = 0;
+
+			// Register the window class
+			// NB allow 4 bytes of window data for D3D9RenderWindow pointer
+            WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW, WndProc, 0, 4, hInst,
+				LoadIcon( NULL, IDI_APPLICATION ),
+				LoadCursor( NULL, IDC_ARROW ),
+				(HBRUSH)GetStockObject( BLACK_BRUSH ), NULL,
+				TEXT(title.c_str()) };
+			RegisterClass( &wndClass );
+
+			// Create our main window
+			// Pass pointer to self
+			HWND hWnd = CreateWindow(TEXT(title.c_str()),
+									 TEXT(title.c_str()),
+									 dwStyle, mLeft, mTop,
+									 mWidth, mHeight, 0L, 0L, hInst, this);
+			GetClientRect(hWnd,&rc);
+			mWidth = rc.right;
+			mHeight = rc.bottom;
+
+			ShowWindow(hWnd, SW_SHOWNORMAL);
+			UpdateWindow(hWnd);
+
+			mHWnd = hWnd;
+			// Store info
+			mName = name;
+			mIsDepthBuffered = depthBuffer;
+			mIsFullScreen = fullScreen;
+		}
+		else
+		{
+			mHWnd = externalHandle;
+			ShowWindow(mHWnd, SW_SHOWNORMAL);
+			UpdateWindow(mHWnd);
+			RECT rc;
+			GetClientRect(mHWnd,&rc);
+			mWidth = rc.right;
+			mHeight = rc.bottom;
+			mLeft = rc.left;
+			mTop = rc.top;
+			mName = name;
+			mIsDepthBuffered = depthBuffer;
+			mIsFullScreen = fullScreen;
+		}
+
+		// track colour depth
+		mColourDepth = colourDepth;
+
+        StringUtil::StrStreamType str;
+        str << "D3D9 : Created D3D9 Rendering Window '"
+            << mName << "' : " << mWidth << "x" << mHeight 
+       		<< ", " << mColourDepth << "bpp";
+		LogManager::getSingleton().logMessage(
+			LML_NORMAL, str.str());
+
+		createD3DResources();
+
+		mReady = true;
+	}
+
+	void D3D9RenderWindow::createD3DResources(void)
+	{
+		// access device via driver
+		LPDIRECT3DDEVICE9 mpD3DDevice = mDriver->getD3DDevice();
+
+		if (mIsSwapChain && !mpD3DDevice)
+		{
+			OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
+				"Secondary window has not been given the device from the primary!",
+				"D3D9RenderWindow::createD3DResources");
+		}
+
+		// Set up the presentation parameters
+		HRESULT hr;
+		LPDIRECT3D9 pD3D = mDriver->getD3D();
+		D3DDEVTYPE devType = D3DDEVTYPE_HAL;
+
+		ZeroMemory( &md3dpp, sizeof(D3DPRESENT_PARAMETERS) );
+		md3dpp.Windowed					= !mIsFullScreen;
+		md3dpp.SwapEffect				= D3DSWAPEFFECT_DISCARD;
+		md3dpp.BackBufferCount			= 1;
+		md3dpp.EnableAutoDepthStencil	= mIsDepthBuffered;
+		md3dpp.hDeviceWindow			= mHWnd;
+		md3dpp.BackBufferWidth			= mWidth;
+		md3dpp.BackBufferHeight			= mHeight;
+
+		if (mVSync)
+			md3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+		else
+			md3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+
+		md3dpp.BackBufferFormat		= D3DFMT_R5G6B5;
+		if( mColourDepth > 16 )
+			md3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
+
+		if (mColourDepth > 16 )
+		{
+			// Try to create a 32-bit depth, 8-bit stencil
+			if( FAILED( pD3D->CheckDeviceFormat(mDriver->getAdapterNumber(),
+				devType,  md3dpp.BackBufferFormat,  D3DUSAGE_DEPTHSTENCIL, 
+				D3DRTYPE_SURFACE, D3DFMT_D24S8 )))
+			{
+				// Bugger, no 8-bit hardware stencil, just try 32-bit zbuffer 
+				if( FAILED( pD3D->CheckDeviceFormat(mDriver->getAdapterNumber(),
+					devType,  md3dpp.BackBufferFormat,  D3DUSAGE_DEPTHSTENCIL, 
+					D3DRTYPE_SURFACE, D3DFMT_D32 )))
+				{
+					// Jeez, what a naff card. Fall back on 16-bit depth buffering
+					md3dpp.AutoDepthStencilFormat = D3DFMT_D16;
+				}
+				else
+					md3dpp.AutoDepthStencilFormat = D3DFMT_D32;
+			}
+			else
+			{
+				// Woohoo!
+				if( SUCCEEDED( pD3D->CheckDepthStencilMatch( mDriver->getAdapterNumber(), devType,
+					md3dpp.BackBufferFormat, md3dpp.BackBufferFormat, D3DFMT_D24S8 ) ) )
+				{
+					md3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; 
+				} 
+				else 
+					md3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; 
+			}
+		}
+		else
+			// 16-bit depth, software stencil
+			md3dpp.AutoDepthStencilFormat	= D3DFMT_D16;
+
+		md3dpp.MultiSampleType = mFSAAType;
+		md3dpp.MultiSampleQuality = (mFSAAQuality == 0) ? 0 : mFSAAQuality;
+
+		if (mIsSwapChain)
+		{
+			// Create swap chain			
+			hr = mpD3DDevice->CreateAdditionalSwapChain(
+				&md3dpp, &mpSwapChain);
+			if (FAILED(hr))
+			{
+				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 
+					"Unable to create an additional swap chain",
+					"D3D9RenderWindow::createD3DResources");
+
+			}
+			// Store references to buffers for convenience
+			mpSwapChain->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &mpRenderSurface );
+			// Additional swap chains need their own depth buffer
+			// to support resizing them
+			if (mIsDepthBuffered) 
+			{
+				hr = mpD3DDevice->CreateDepthStencilSurface(
+					mWidth, mHeight,
+					md3dpp.AutoDepthStencilFormat,
+					md3dpp.MultiSampleType,
+					md3dpp.MultiSampleQuality, 
+					(md3dpp.Flags & D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL),
+					&mpRenderZBuffer, NULL
+					);
+
+				if (FAILED(hr)) 
+				{
+					OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 
+						"Unable to create a depth buffer for the swap chain",
+						"D3D9RenderWindow::createD3DResources");
+
+				}
+			} 
+			else 
+			{
+				mpRenderZBuffer = 0;
+			}
+			// release immediately so we don't hog them
+			mpRenderSurface->Release();
+			// We'll need the depth buffer for rendering the swap chain
+			//mpRenderZBuffer->Release();
+		}
+		else
+		{
+			if (!mpD3DDevice)
+			{
+				// We haven't created the device yet, this must be the first time
+
+				// Do we want to preserve the FPU mode? Might be useful for scientific apps
+				DWORD extraFlags = 0;
+				ConfigOptionMap& options = Root::getSingleton().getRenderSystem()->getConfigOptions();
+				ConfigOptionMap::iterator opti = options.find("Floating-point mode");
+				if (opti != options.end() && opti->second.currentValue == "Consistent")
+					extraFlags |= D3DCREATE_FPU_PRESERVE;
+
+				hr = pD3D->CreateDevice( mDriver->getAdapterNumber(), devType, mHWnd,
+					D3DCREATE_HARDWARE_VERTEXPROCESSING | extraFlags, &md3dpp, &mpD3DDevice );
+				if( FAILED( hr ) )
+				{
+					hr = pD3D->CreateDevice( mDriver->getAdapterNumber(), devType, mHWnd,
+						D3DCREATE_MIXED_VERTEXPROCESSING | extraFlags, &md3dpp, &mpD3DDevice );
+					if( FAILED( hr ) )
+					{
+						hr = pD3D->CreateDevice( mDriver->getAdapterNumber(), devType, mHWnd,
+							D3DCREATE_SOFTWARE_VERTEXPROCESSING | extraFlags, &md3dpp, &mpD3DDevice );
+					}
+				}
+				// TODO: make this a bit better e.g. go from pure vertex processing to software
+				if( FAILED( hr ) )
+				{
+					destroy();
+					OGRE_EXCEPT( hr, "Failed to create Direct3D9 Device: " + 
+						Root::getSingleton().getErrorDescription(hr), 
+						"D3D9RenderWindow::createD3DResources" );
+				}
+			}
+			// update device in driver
+			mDriver->setD3DDevice( mpD3DDevice );
+			// Store references to buffers for convenience
+			mpD3DDevice->GetRenderTarget( 0, &mpRenderSurface );
+			mpD3DDevice->GetDepthStencilSurface( &mpRenderZBuffer );
+			// release immediately so we don't hog them
+			mpRenderSurface->Release();
+			mpRenderZBuffer->Release();
+		}
+
+	}
+
+	
+	void D3D9RenderWindow::destroy()
+	{
+		mpRenderSurface = 0;
+		if (mIsSwapChain)
+		{
+			SAFE_RELEASE(mpRenderZBuffer);
+			SAFE_RELEASE(mpSwapChain);
+		}
+		else
+		{
+			// ignore deptzh buffer, access device through driver
+			mpRenderZBuffer = 0;
+			LPDIRECT3DDEVICE9 mpD3DDevice = mDriver->getD3DDevice();
+			SAFE_RELEASE(mpD3DDevice);
+			mDriver->setD3DDevice( mpD3DDevice );
+			DestroyWindow( mHWnd );
+		}
+		mHWnd = 0;
+	}
+
+	void D3D9RenderWindow::resize( unsigned int width, unsigned int height )
+	{
+		
+		if (mIsSwapChain) 
+		{
+
+			D3DPRESENT_PARAMETERS pp = md3dpp;
+
+			pp.BackBufferWidth = width;
+			pp.BackBufferHeight = height;
+
+			SAFE_RELEASE( mpRenderZBuffer );
+			SAFE_RELEASE( mpSwapChain );
+
+			HRESULT hr = mDriver->getD3DDevice()->CreateAdditionalSwapChain(
+				&pp,
+				&mpSwapChain);
+
+			if (FAILED(hr)) 
+			{
+				StringUtil::StrStreamType str;
+				str << "D3D9RenderWindow: failed to reset device to new dimensions << "
+					<< width << " x " << height << ". Trying to recover.";
+				LogManager::getSingleton().logMessage(LML_CRITICAL, str.str());
+
+				// try to recover
+				hr = mDriver->getD3DDevice()->CreateAdditionalSwapChain(
+					&md3dpp,
+					&mpSwapChain);
+
+				if (FAILED(hr))
+					OGRE_EXCEPT( hr, "Reset window to last size failed", "D3D9RenderWindow::resize" );
+
+			}		
+			else 
+			{
+				md3dpp = pp;
+
+				mWidth = width;
+				mHeight = height;
+
+				hr = mpSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mpRenderSurface);
+				hr = mDriver->getD3DDevice()->CreateDepthStencilSurface(
+						mWidth, mHeight,
+						md3dpp.AutoDepthStencilFormat,
+						md3dpp.MultiSampleType,
+						md3dpp.MultiSampleQuality, 
+						(md3dpp.Flags & D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL),
+						&mpRenderZBuffer, NULL
+						);
+
+				if (FAILED(hr)) 
+				{
+					OGRE_EXCEPT( hr, "Failed to create depth stencil surface for Swap Chain", "D3D9RenderWindow::resize" );
+				}
+
+				mpRenderSurface->Release();
+			}
+		}
+		// primary windows would reset the device - not implemented yet.
+		else 
+		{
+			mWidth = width;
+			mHeight = height;
+		}
+
+		// Notify viewports of resize
+		ViewportList::iterator it = mViewportList.begin();
+		while( it != mViewportList.end() )
+			(*it++).second->_updateDimensions();
+		// TODO - resize window
+	}
+
+	void D3D9RenderWindow::swapBuffers( bool waitForVSync )
+	{
+		// access device through driver
+		LPDIRECT3DDEVICE9 mpD3DDevice = mDriver->getD3DDevice();
+		if( mpD3DDevice )
+		{
+			HRESULT hr;
+			if (mIsSwapChain)
+			{
+				hr = mpSwapChain->Present(NULL, NULL, NULL, NULL, 0);
+			}
+			else
+			{
+				hr = mpD3DDevice->Present( NULL, NULL, 0, NULL );
+			}
+			if( D3DERR_DEVICELOST == hr )
+			{
+				static_cast<D3D9RenderSystem*>(
+					Root::getSingleton().getRenderSystem())->_notifyDeviceLost();
+				Sleep(500);
+
+			}
+			else if( FAILED(hr) )
+				OGRE_EXCEPT( hr, "Error Presenting surfaces", "D3D9RenderWindow::swapBuffers" );
+		}
+	}
+
+	void D3D9RenderWindow::getCustomAttribute( const String& name, void* pData )
+	{
+		// Valid attributes and their equvalent native functions:
+		// D3DDEVICE			: getD3DDevice
+		// HWND					: getWindowHandle
+
+		if( name == "D3DDEVICE" )
+		{
+			LPDIRECT3DDEVICE9 *pDev = (LPDIRECT3DDEVICE9*)pData;
+			*pDev = getD3DDevice();
+			return;
+		}
+		else if( name == "HWND" )
+		{
+			HWND *pHwnd = (HWND*)pData;
+			*pHwnd = getWindowHandle();
+			return;
+		}
+		else if( name == "isTexture" )
+		{
+			bool *b = reinterpret_cast< bool * >( pData );
+			*b = false;
+
+			return;
+		}
+		else if( name == "D3DZBUFFER" )
+		{
+			LPDIRECT3DSURFACE9 *pSurf = (LPDIRECT3DSURFACE9*)pData;
+			*pSurf = mpRenderZBuffer;
+			return;
+		}
+		else if( name == "DDBACKBUFFER" )
+		{
+			LPDIRECT3DSURFACE9 *pSurf = (LPDIRECT3DSURFACE9*)pData;
+			*pSurf = mpRenderSurface;
+			return;
+		}
+		else if( name == "DDFRONTBUFFER" )
+		{
+			LPDIRECT3DSURFACE9 *pSurf = (LPDIRECT3DSURFACE9*)pData;
+			*pSurf = mpRenderSurface;
+			return;
+		}
+	}
+
+	void D3D9RenderWindow::WindowMovedOrResized()
+	{
+		// TODO
+	}
+
+	void D3D9RenderWindow::writeContentsToFile(const String& filename)
+	{
+		HRESULT hr;
+		LPDIRECT3DSURFACE9 pSurf=NULL, pTempSurf=NULL;
+		D3DSURFACE_DESC desc;
+		D3DDISPLAYMODE dm;
+
+		// access device through driver
+		LPDIRECT3DDEVICE9 mpD3DDevice = mDriver->getD3DDevice();
+
+		// get display dimensions
+		// this will be the dimensions of the front buffer
+		if (FAILED(hr = mpD3DDevice->GetDisplayMode(0, &dm)))
+			OGRE_EXCEPT(hr, "Can't get display mode!", "D3D9RenderWindow::writeContentsToFile");
+
+		desc.Width = dm.Width;
+		desc.Height = dm.Height;
+		desc.Format = D3DFMT_A8R8G8B8;
+		if (FAILED(hr = mpD3DDevice->CreateOffscreenPlainSurface(
+						desc.Width, 
+						desc.Height, 
+						desc.Format, 
+						D3DPOOL_SYSTEMMEM, 
+						&pTempSurf, 
+						NULL)))
+		{
+			OGRE_EXCEPT(hr, "Cannot create offscreen buffer 1!", "D3D9RenderWindow::writeContentsToFile");
+		}
+
+		if (FAILED(hr = mpD3DDevice->GetFrontBufferData(0, pTempSurf)))
+		{
+			SAFE_RELEASE(pTempSurf);
+			OGRE_EXCEPT(hr, "Can't get front buffer!", "D3D9RenderWindow::writeContentsToFile");
+		}
+
+		if (!mIsFullScreen)
+		{
+			POINT pt={0, 0};
+			RECT srcRect;
+			GetWindowRect(mHWnd, &srcRect);
+
+			desc.Width = srcRect.right - srcRect.left;
+			desc.Height = srcRect.bottom - srcRect.top;
+			desc.Format = D3DFMT_A8R8G8B8;         // this is what we get from the screen, so stick with it
+
+			// NB we can't lock the back buffer direct because it's no created that way
+			// and to do so hits performance, so copy to another surface
+			// Must be the same format as the source surface
+			if (FAILED(hr = mpD3DDevice->CreateOffscreenPlainSurface(
+							desc.Width, 
+							desc.Height, 
+							desc.Format, 
+							D3DPOOL_DEFAULT, 
+							&pSurf,
+							NULL)))
+			{
+				SAFE_RELEASE(pSurf);
+				OGRE_EXCEPT(hr, "Cannot create offscreen buffer 2!", "D3D9RenderWindow::writeContentsToFile");
+			}
+
+			// Copy
+			if (FAILED(hr = mpD3DDevice->UpdateSurface(pTempSurf, &srcRect, pSurf, &pt)))
+			{
+				SAFE_RELEASE(pTempSurf);
+				SAFE_RELEASE(pSurf);
+				OGRE_EXCEPT(hr, "Cannot update surface!", "D3D9RenderWindow::writeContentsToFile");
+			}
+
+			SAFE_RELEASE(pTempSurf);
+			pTempSurf = pSurf;
+			pSurf = NULL;
+		}
+
+		D3DLOCKED_RECT lockedRect;
+		if (FAILED(hr = pTempSurf->LockRect(&lockedRect, NULL, 
+			D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK)))
+		{
+			OGRE_EXCEPT(hr, "can't lock rect!", "D3D9RenderWindow::writeContentsToFile");
+		} 
+
+        ImageCodec::ImageData *imgData = new ImageCodec::ImageData();
+        imgData->width = desc.Width;
+        imgData->height = desc.Height;
+        imgData->format = PF_BYTE_RGB;
+
+		// Allocate contiguous buffer (surfaces aren't necessarily contiguous)
+		uchar* pBuffer = new uchar[desc.Width * desc.Height * 3];
+
+		uint x, y;
+		uchar *pData, *pDest;
+
+		pData = (uchar*)lockedRect.pBits;
+		pDest = pBuffer;
+		for (y = 0; y < desc.Height; ++y)
+		{
+			uchar *pRow = pData;
+
+			for (x = 0; x < desc.Width; ++x)
+			{
+				switch(desc.Format)
+				{
+				case D3DFMT_R5G6B5:
+					WORD val;
+
+					val = *((WORD*)pRow);
+					pRow += 2;
+
+					*pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0xF800, (BYTE)0xFF);
+					*pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x07E0, (BYTE)0xFF);
+					*pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x001F, (BYTE)0xFF);
+					break;
+				case D3DFMT_A8R8G8B8:
+				case D3DFMT_X8R8G8B8:
+					// Actual format is BRGA for some reason
+					*pDest++ = pRow[2]; // R
+					*pDest++ = pRow[1]; // G
+					*pDest++ = pRow[0]; // B
+					pRow += 4; // skip alpha / dummy
+					break;
+				case D3DFMT_R8G8B8:
+					// Actual format is BRGA for some reason
+					*pDest++ = pRow[2]; // R
+					*pDest++ = pRow[1]; // G
+					*pDest++ = pRow[0]; // B
+					pRow += 3; 
+					break;
+				}
+
+
+			}
+			// increase by one line
+			pData += lockedRect.Pitch;
+		}
+
+		// Wrap buffer in a chunk
+		MemoryDataStreamPtr stream(new MemoryDataStream(pBuffer, desc.Width * desc.Height * 3, false));
+
+		// Get codec 
+		size_t pos = filename.find_last_of(".");
+		String extension;
+		if( pos == String::npos )
+			OGRE_EXCEPT(
+			Exception::ERR_INVALIDPARAMS, 
+			"Unable to determine image type for '" + filename + "' - invalid extension.",
+			"D3D9RenderWindow::writeContentsToFile" );
+
+		while( pos != filename.length() - 1 )
+			extension += filename[++pos];
+
+		// Get the codec
+		Codec * pCodec = Codec::getCodec(extension);
+
+		// Write out
+		{
+			Codec::CodecDataPtr ptr(imgData);
+        	pCodec->codeToFile(stream, filename, ptr);
+		}
+
+		delete [] pBuffer;
+
+		SAFE_RELEASE(pTempSurf);
+		SAFE_RELEASE(pSurf);
+	}
+	//-----------------------------------------------------------------------------
+	void D3D9RenderWindow::update(void)
+	{
+		D3D9RenderSystem* rs = static_cast<D3D9RenderSystem*>(
+			Root::getSingleton().getRenderSystem());
+
+		// access device through driver
+		LPDIRECT3DDEVICE9 mpD3DDevice = mDriver->getD3DDevice();
+
+		if (rs->isDeviceLost())
+		{
+			// Test the cooperative mode first
+			HRESULT hr = mpD3DDevice->TestCooperativeLevel();
+			if (hr == D3DERR_DEVICELOST)
+			{
+				// device lost, and we can't reset
+				// can't do anything about it here, wait until we get 
+				// D3DERR_DEVICENOTRESET; rendering calls will silently fail until 
+				// then (except Present, but we ignore device lost there too)
+				mpRenderSurface = 0;
+				// need to release if swap chain
+				if (!mIsSwapChain)
+					mpRenderZBuffer = 0;
+				else
+					SAFE_RELEASE (mpRenderZBuffer);
+				Sleep(500);
+				return;
+			}
+			else if (hr == D3DERR_DEVICENOTRESET)
+			{
+				// device lost, and we can reset
+				rs->restoreLostDevice();
+
+				// Still lost?
+				if (rs->isDeviceLost())
+				{
+					// Wait a while
+					Sleep(500);
+					return;
+				}
+			
+				// fixed: this only works for not swap chained
+				if (!mIsSwapChain) 
+				{
+					// re-qeuery buffers
+					mpD3DDevice->GetRenderTarget( 0, &mpRenderSurface );
+					mpD3DDevice->GetDepthStencilSurface( &mpRenderZBuffer );
+					// release immediately so we don't hog them
+					mpRenderSurface->Release();
+					mpRenderZBuffer->Release();
+				}
+				else 
+				{
+					mpSwapChain->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &mpRenderSurface );
+					if (mIsDepthBuffered) {
+						hr = mpD3DDevice->CreateDepthStencilSurface(
+							mWidth, mHeight,
+							md3dpp.AutoDepthStencilFormat,
+							md3dpp.MultiSampleType,
+							md3dpp.MultiSampleQuality, 
+							(md3dpp.Flags & D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL),
+							&mpRenderZBuffer, NULL
+							);
+
+						if (FAILED(hr)) {
+							OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 
+								"Unable to re-create depth buffer for the swap chain",
+								"D3D9RenderWindow::update");
+
+						}
+					} 
+					else
+					{
+						mpRenderZBuffer = 0;
+					}
+
+					// release immediately so we don't hog them
+					mpRenderSurface->Release();
+				}
+			}
+
+		}
+		RenderWindow::update();
+	}
+
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	uchar *D3D9RenderWindow::getBufferContents(int &dimx, int &dimy)
+	{
+		HRESULT hr;
+		LPDIRECT3DSURFACE9 pSurf=NULL, pTempSurf=NULL;
+		D3DSURFACE_DESC desc;
+		D3DDISPLAYMODE dm;
+
+		// access device through driver
+		LPDIRECT3DDEVICE9 mpD3DDevice = mDriver->getD3DDevice();
+
+		// get display dimensions
+		// this will be the dimensions of the front buffer
+		if (FAILED(hr = mpD3DDevice->GetDisplayMode(0, &dm)))
+			OGRE_EXCEPT(hr, "Can't get display mode!", "D3D9RenderWindow::writeContentsToFile");
+
+		desc.Width = dm.Width;
+		desc.Height = dm.Height;
+		desc.Format = D3DFMT_A8R8G8B8;
+		if (FAILED(hr = mpD3DDevice->CreateOffscreenPlainSurface(
+						desc.Width, 
+						desc.Height, 
+						desc.Format, 
+						D3DPOOL_SYSTEMMEM, 
+						&pTempSurf, 
+						NULL)))
+		{
+			OGRE_EXCEPT(hr, "Cannot create offscreen buffer 1!", "D3D9RenderWindow::writeContentsToFile");
+		}
+
+		if (FAILED(hr = mpD3DDevice->GetFrontBufferData(0, pTempSurf)))
+		{
+			SAFE_RELEASE(pTempSurf);
+			OGRE_EXCEPT(hr, "Can't get front buffer!", "D3D9RenderWindow::writeContentsToFile");
+		}
+
+		if (!mIsFullScreen)
+		{
+			POINT pt={0, 0};
+			RECT srcRect;
+			GetWindowRect(mHWnd, &srcRect);
+
+			desc.Width = srcRect.right - srcRect.left;
+			desc.Height = srcRect.bottom - srcRect.top;
+			desc.Format = D3DFMT_A8R8G8B8;         // this is what we get from the screen, so stick with it
+
+			// NB we can't lock the back buffer direct because it's no created that way
+			// and to do so hits performance, so copy to another surface
+			// Must be the same format as the source surface
+			if (FAILED(hr = mpD3DDevice->CreateOffscreenPlainSurface(
+							desc.Width, 
+							desc.Height, 
+							desc.Format, 
+							D3DPOOL_DEFAULT, 
+							&pSurf,
+							NULL)))
+			{
+				SAFE_RELEASE(pSurf);
+				OGRE_EXCEPT(hr, "Cannot create offscreen buffer 2!", "D3D9RenderWindow::writeContentsToFile");
+			}
+
+			// Copy
+			if (FAILED(hr = mpD3DDevice->UpdateSurface(pTempSurf, &srcRect, pSurf, &pt)))
+			{
+				SAFE_RELEASE(pTempSurf);
+				SAFE_RELEASE(pSurf);
+				OGRE_EXCEPT(hr, "Cannot update surface!", "D3D9RenderWindow::writeContentsToFile");
+			}
+
+			SAFE_RELEASE(pTempSurf);
+			pTempSurf = pSurf;
+			pSurf = NULL;
+		}
+
+		D3DLOCKED_RECT lockedRect;
+		if (FAILED(hr = pTempSurf->LockRect(&lockedRect, NULL, 
+			D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK)))
+		{
+			OGRE_EXCEPT(hr, "can't lock rect!", "D3D9RenderWindow::writeContentsToFile");
+		} 
+
+       
+        dimx = desc.Width;
+        dimy = desc.Height;
+      
+		// Allocate contiguous buffer (surfaces aren't necessarily contiguous)
+		uchar* pBuffer = new uchar[desc.Width * desc.Height * 3];
+
+		uint x, y;
+		uchar *pData, *pDest;
+
+		pData = (uchar*)lockedRect.pBits;
+		pDest = pBuffer;
+		for (y = 0; y < desc.Height; ++y)
+		{
+			uchar *pRow = pData;
+
+			for (x = 0; x < desc.Width; ++x)
+			{
+				switch(desc.Format)
+				{
+				case D3DFMT_R5G6B5:
+					WORD val;
+
+					val = *((WORD*)pRow);
+					pRow += 2;
+
+					*pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0xF800, (BYTE)0xFF);
+					*pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x07E0, (BYTE)0xFF);
+					*pDest++ = Bitwise::convertBitPattern((WORD)val, (WORD)0x001F, (BYTE)0xFF);
+					break;
+				case D3DFMT_A8R8G8B8:
+				case D3DFMT_X8R8G8B8:
+					// Actual format is BRGA for some reason
+					*pDest++ = pRow[2]; // R
+					*pDest++ = pRow[1]; // G
+					*pDest++ = pRow[0]; // B
+					pRow += 4; // skip alpha / dummy
+					break;
+				case D3DFMT_R8G8B8:
+					// Actual format is BRGA for some reason
+					*pDest++ = pRow[2]; // R
+					*pDest++ = pRow[1]; // G
+					*pDest++ = pRow[0]; // B
+					pRow += 3; 
+					break;
+				}
+
+
+			}
+			// increase by one line
+			pData += lockedRect.Pitch;
+		}
+
+		SAFE_RELEASE(pTempSurf);
+		SAFE_RELEASE(pSurf);
+
+		return pBuffer;
+	}
+#endif // GTP_VISIBILITY_MODIFIED_OGRE
+}
