Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreGLPrerequisites.h
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreGLPrerequisites.h	(revision 115)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/include/OgreGLPrerequisites.h	(revision 193)
@@ -52,4 +52,5 @@
 #       define APIENTRY
 #   endif
+#   define GL_GLEXT_LEGACY 
 #   include <OpenGL/gl.h>
 #   include <OpenGL/glu.h>
@@ -270,5 +271,5 @@
     if (errCode != GL_NO_ERROR) {  \
     errString = gluErrorString (errCode);  \
-    LogManager::getSingleton().logMessage  ("[GL] :" + ERROR_MSG +  \
+    LogManager::getSingleton().logMessage  ("[GL] :" + Ogre::String(ERROR_MSG) +  \
     " : " + Ogre::String( (const char*) errString)); \
         } \
@@ -282,5 +283,5 @@
     errString = gluErrorString (errCode);  \
     OGRE_EXCEPT (Exception::ERR_INTERNAL_ERROR,  \
-    ERROR_MSG +  \
+    Ogre::String(ERROR_MSG) +  \
     " : " + Ogre::String( (const char*) errString), String("")); \
         } \
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 193)
@@ -40,5 +40,5 @@
 	            bool fullScreen, const NameValuePairList *miscParams);
         void destroy(void);
-        bool isActive(void) const;
+        bool isVisible() const;
         bool isClosed(void) const;
         void reposition(int left, int top);
@@ -61,7 +61,4 @@
 		// 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 );
@@ -72,8 +69,8 @@
 		HDC		mHDC;
 		HGLRC	mGlrc;
-		int		mOldSwapIntervall;
-		bool	mActive;				// Is active i.e. visible
-		bool	mReady;					// Is ready i.e. available for update
+        bool    mIsExternal;
+        bool    mSizing;
 		bool	mClosed;
+        int     mDisplayFrequency;      // fullscreen only, to restore display
         Win32Context *mContext;
 
Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLTexture.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLTexture.cpp	(revision 156)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLTexture.cpp	(revision 193)
@@ -37,5 +37,5 @@
 #include "OgreCodec.h"
 #include "OgreImageCodec.h"
-
+#include "OgreStringConverter.h"
 
 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
@@ -200,5 +200,5 @@
 				if(depth>1)		depth = depth/2;
 			}
-			delete tmpdata;
+			delete [] tmpdata;
 		}
 		else
@@ -355,8 +355,19 @@
 			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)
-				));
+                GLHardwarePixelBuffer *buf = new GLHardwarePixelBuffer(getGLTextureTarget(), mTextureID, face, mip,
+						static_cast<HardwareBuffer::Usage>(mUsage), doSoftware && mip==0);
+				mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buf));
+                
+                /// Check for error
+                if(buf->getWidth()==0 || buf->getHeight()==0 || buf->getDepth()==0)
+                {
+                    OGRE_EXCEPT(
+                        Exception::ERR_RENDERINGAPI_ERROR, 
+                        "Zero sized texture surface on texture "+getName()+
+                            " face "+StringConverter::toString(face)+
+                            " mipmap "+StringConverter::toString(mip)+
+                            ". Probably, the GL driver refused to create the texture.", 
+                            "GLTexture::_createSurfaceList");
+                }
 			}
 		}
Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLHardwareOcclusionQuery.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLHardwareOcclusionQuery.cpp	(revision 115)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLHardwareOcclusionQuery.cpp	(revision 193)
@@ -27,5 +27,4 @@
 #include "OgreException.h"
 
-
 namespace Ogre {
 
@@ -52,6 +51,9 @@
 	// Check for hardware occlusion support
 	// This is a hack to see if hw occlusion is supported. pointer is 0 if it's not supported.
-	//if (glGenQueriesARB_ptr != 0)
+#ifdef GTP_VISIBILITY_USE_ARB_QUERIES
+	if (glGenQueriesARB_ptr != 0)
+#else
 	if (glGenOcclusionQueriesNV_ptr != 0)
+#endif
     {
 		mHasOcclusionSupport = true;
@@ -64,6 +66,9 @@
 	if(mHasOcclusionSupport)
 	{
-		//glGenQueriesARB_ptr(1, &mQueryID );	
+#ifdef GTP_VISIBILITY_USE_ARB_QUERIES
+		glGenQueriesARB_ptr(1, &mQueryID );	
+#else
 		glGenOcclusionQueriesNV_ptr(1, &mQueryID);
+#endif
 	}
 }
@@ -76,6 +81,9 @@
 	if( mHasOcclusionSupport )
 	{
-		//glDeleteQueriesARB_ptr(1, &mQueryID);  
+#ifdef GTP_VISIBILITY_USE_ARB_QUERIES
+		glDeleteQueriesARB_ptr(1, &mQueryID);
+#else
 		glDeleteOcclusionQueriesNV_ptr(1, &mQueryID);  
+#endif
 	}	
 }
@@ -101,6 +109,9 @@
 		if (mSkipCounter == 0)
 		{
-			//glBeginQueryARB_ptr(GL_SAMPLES_PASSED_ARB, mQueryID);
+#ifdef GTP_VISIBILITY_USE_ARB_QUERIES
+			glBeginQueryARB_ptr(GL_SAMPLES_PASSED_ARB, mQueryID);
+#else
 			glBeginOcclusionQueryNV_ptr(mQueryID);
+#endif
 		}
 	}
@@ -114,6 +125,9 @@
 		if( mSkipCounter == 0)
 		{
-			//glEndQueryARB_ptr(GL_SAMPLES_PASSED_ARB);
+#ifdef GTP_VISIBILITY_USE_ARB_QUERIES
+			glEndQueryARB_ptr(GL_SAMPLES_PASSED_ARB);
+#else
 			glEndOcclusionQueryNV_ptr();
+#endif
 		}
 
@@ -129,6 +143,9 @@
 	if( mHasOcclusionSupport )	// Make it fail silently if hardware occlusion isn't supported
 	{
-		//glGetQueryObjectuivARB_ptr(mQueryID, GL_QUERY_RESULT_ARB, NumOfFragments);
+#ifdef GTP_VISIBILITY_USE_ARB_QUERIES
+		glGetQueryObjectuivARB_ptr(mQueryID, GL_QUERY_RESULT_ARB, NumOfFragments);
+#else
 glGetOcclusionQueryuivNV_ptr(mQueryID, GL_PIXEL_COUNT_NV, NumOfFragments);
+#endif
 	}
 	else
Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLRenderSystem.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLRenderSystem.cpp	(revision 150)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreGLRenderSystem.cpp	(revision 193)
@@ -149,5 +149,5 @@
 
     GLRenderSystem::GLRenderSystem()
-      : mExternalWindowHandle(0), mDepthWrite(true), mHardwareBufferManager(0),
+      : mDepthWrite(true), mHardwareBufferManager(0),
         mGpuProgramManager(0)
     {
@@ -173,5 +173,6 @@
         for (i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; i++)
         {
-            mTextureCoordIndex[i] = 0;
+			// Dummy value
+            mTextureCoordIndex[i] = 99;
         }
 
@@ -334,6 +335,18 @@
             GLint units;
             glGetIntegerv( GL_MAX_TEXTURE_UNITS, &units );
+			mFixedFunctionTextureUnits = units;
+
+			if (mGLSupport->checkExtension("GL_ARB_fragment_program"))
+			{
+				// Also check GL_MAX_TEXTURE_IMAGE_UNITS_ARB since NV at least
+				// only increased this on the FX/6x00 series
+				GLint arbUnits;
+				glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &arbUnits );
+				if (arbUnits > units)
+					units = arbUnits;
+			}
 
             mCapabilities->setNumTextureUnits(units);
+
         }
         else
@@ -405,4 +418,17 @@
             mGpuProgramManager->_pushSyntaxCode("arbvp1");
             mGpuProgramManager->registerProgramFactory("arbvp1", createGLArbGpuProgram);
+			if (mGLSupport->checkExtension("GL_NV_vertex_program2_option"))
+			{
+				mCapabilities->setMaxVertexProgramVersion("vp30");
+				mGpuProgramManager->_pushSyntaxCode("vp30");
+				mGpuProgramManager->registerProgramFactory("vp30", createGLArbGpuProgram);
+			}
+
+			if (mGLSupport->checkExtension("GL_NV_vertex_program3"))
+			{
+				mCapabilities->setMaxVertexProgramVersion("vp40");
+				mGpuProgramManager->_pushSyntaxCode("vp40");
+				mGpuProgramManager->registerProgramFactory("vp40", createGLArbGpuProgram);
+			}
         }
 
@@ -455,4 +481,17 @@
             mGpuProgramManager->_pushSyntaxCode("arbfp1");
             mGpuProgramManager->registerProgramFactory("arbfp1", createGLArbGpuProgram);
+			if (mGLSupport->checkExtension("GL_NV_fragment_program_option"))
+			{
+				mCapabilities->setMaxFragmentProgramVersion("fp30");
+				mGpuProgramManager->_pushSyntaxCode("fp30");
+				mGpuProgramManager->registerProgramFactory("fp30", createGLArbGpuProgram);
+			}
+
+			if (mGLSupport->checkExtension("GL_NV_fragment_program2"))
+			{
+				mCapabilities->setMaxFragmentProgramVersion("fp40");
+				mGpuProgramManager->_pushSyntaxCode("fp40");
+				mGpuProgramManager->registerProgramFactory("fp40", createGLArbGpuProgram);
+			}        
         }
 
@@ -911,10 +950,7 @@
 
         GLfloat mat[16];
-        makeGLMatrix(mat, mViewMatrix);
+		makeGLMatrix( mat, mViewMatrix * mWorldMatrix );
         glMatrixMode(GL_MODELVIEW);
         glLoadMatrixf(mat);
-
-        makeGLMatrix(mat, mWorldMatrix);
-        glMultMatrixf(mat);
 
         setGLClipPlanes();
@@ -1025,13 +1061,23 @@
             if(lastTextureType != mTextureTypes[stage] && lastTextureType != 0)
             {
+				if (stage < mFixedFunctionTextureUnits)
+				{
                 glDisable( lastTextureType );
             }
-
+            }
+
+			if (stage < mFixedFunctionTextureUnits)
+			{
 			glEnable( mTextureTypes[stage] );
+			}
+
 			if(!tex.isNull())
 				glBindTexture( mTextureTypes[stage], tex->getGLID() );
+
         }
         else
         {
+			if (stage < mFixedFunctionTextureUnits)
+			{
             if (lastTextureType != 0)
             {
@@ -1040,6 +1086,8 @@
 			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
         }
+        }
 
         glActiveTextureARB_ptr( GL_TEXTURE0 );
+
     }
 
@@ -1053,4 +1101,11 @@
         const Frustum* frustum)
     {
+		if (stage >= mFixedFunctionTextureUnits)
+		{
+			// Can't do this
+			return;
+		}
+
+		
         GLfloat M[16];
         Matrix4 projectionBias;
@@ -1209,4 +1264,10 @@
     void GLRenderSystem::_setTextureMatrix(size_t stage, const Matrix4& xform)
     {
+		if (stage >= mFixedFunctionTextureUnits)
+		{
+			// Can't do this
+			return;
+		}
+
         GLfloat mat[16];
         makeGLMatrix(mat, xform);
@@ -1286,13 +1347,26 @@
         GLint sourceBlend = getBlendMode(sourceFactor);
         GLint destBlend = getBlendMode(destFactor);
-        
+        if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO)
+        {
+            glDisable(GL_BLEND);
+        }
+        else
+        {
         glEnable(GL_BLEND);
         glBlendFunc(sourceBlend, destBlend);
     }
+    }
     //-----------------------------------------------------------------------------
     void GLRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value)
     {
+        if(func == CMPF_ALWAYS_PASS)
+        {
+            glDisable(GL_ALPHA_TEST);
+        }
+        else
+        {
         glEnable(GL_ALPHA_TEST);
         glAlphaFunc(convertCompareFunction(func), value / 255.0f);
+    }
     }
     //-----------------------------------------------------------------------------
@@ -1345,10 +1419,9 @@
                 "GLRenderSystem::_beginFrame");
 
+        // Activate the viewport clipping
+        glEnable(GL_SCISSOR_TEST);
         // Clear the viewport if required
         if (mActiveViewport->getClearEveryFrame())
         {
-            // Activate the viewport clipping
-            glEnable(GL_SCISSOR_TEST);
-
             clearFrameBuffer(FBT_COLOUR | FBT_DEPTH, 
                 mActiveViewport->getBackgroundColour());
@@ -1839,4 +1912,10 @@
     void GLRenderSystem::_setTextureBlendMode(size_t stage, const LayerBlendModeEx& bm)
     {       
+		if (stage >= mFixedFunctionTextureUnits)
+		{
+			// Can't do this
+			return;
+		}
+
         // Check to see if blending is supported
         if(!mCapabilities->hasCapability(RSC_BLENDING))
@@ -2095,4 +2174,8 @@
             {
                 pBufferData = static_cast<const GLDefaultHardwareVertexBuffer*>(vertexBuffer.get())->getDataPtr(elem->getOffset());
+            }
+            if (op.vertexData->vertexStart)
+            {
+                pBufferData = static_cast<char*>(pBufferData) + op.vertexData->vertexStart * vertexBuffer->getVertexSize();
             }
 
@@ -2132,5 +2215,5 @@
             case VES_TEXTURE_COORDINATES:
 
-                for (i = 0; i < mCapabilities->getNumTextureUnits(); i++)
+                for (i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; i++)
                 {
 					// Only set this texture unit's texcoord pointer if it
@@ -2227,10 +2310,9 @@
         else
         {
-            glDrawArrays(primType, op.vertexData->vertexStart,
-                op.vertexData->vertexCount);
+            glDrawArrays(primType, 0, op.vertexData->vertexCount);
         }
 
         glDisableClientState( GL_VERTEX_ARRAY );
-        for (int i = 0; i < mCapabilities->getNumTextureUnits(); i++)
+        for (int i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; i++)
         {
             glClientActiveTextureARB_ptr(GL_TEXTURE0 + i);
@@ -2451,4 +2533,5 @@
         dest[3][2] = -1;
     }
+
     // ------------------------------------------------------------------
     void GLRenderSystem::setClipPlane (ushort index, Real A, Real B, Real C, Real D)
@@ -2496,16 +2579,4 @@
     }
  	//---------------------------------------------------------------------
- 	void GLRenderSystem::resizeRepositionWindow(void* wich)
- 	{
- 		mGLSupport->resizeRepositionWindow(wich);
- 		for (RenderTargetMap::iterator it = mRenderTargets.begin(); it != mRenderTargets.end(); ++it)		
- 		{
- 			if (it->second->isActive())
- 			{
- 				mGLSupport->resizeReposition(it->second);
- 			}
- 		}
- 	}
-    //---------------------------------------------------------------------
     void GLRenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, 
         bool forGpuProgram)
@@ -2541,4 +2612,5 @@
         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);        
         glEnable(GL_COLOR_SUM);
+        glDisable(GL_DITHER);
 
         // Check for FSAA
Index: trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreWin32Window.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreWin32Window.cpp	(revision 156)
+++ trunk/VUT/work/ogre_changes/RenderSystems/GL/src/OgreWin32Window.cpp	(revision 193)
@@ -42,7 +42,9 @@
 		mIsFullScreen = false;
 		mHWnd = 0;
+		mIsExternal = false;
+		mSizing = false;
+		mClosed = false;
+		mDisplayFrequency = 0;
 		mActive = false;
-		mReady = false;
-		mClosed = false;
     }
 
@@ -55,15 +57,29 @@
 	            bool fullScreen, const NameValuePairList *miscParams)
     {
-        HWND parentHWnd = 0;
-		HWND externalHandle = 0;
+		// destroy current window, if any
+		if (mHWnd)
+			destroy();
+
 		HINSTANCE hInst = GetModuleHandle("RenderSystem_GL.dll");
+
+		mHWnd = 0;
+		mName = name;
+		mIsFullScreen = fullScreen;
+		mClosed = false;
+
+		// load window defaults
+		mLeft = mTop = -1; // centered
+		mWidth = width;
+		mHeight = height;
+		mDisplayFrequency = 0;
+		mIsDepthBuffered = true;
+		mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL);
+
+		HWND parent = 0;
+		String title = name;
 		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;
+		int fsaa = 0;
+		String border = "";
+		bool outerSize = false;
 
 		if(miscParams)
@@ -71,187 +87,172 @@
 			// Get variable-length params
 			NameValuePairList::const_iterator opt;
-			// left (x)
-			opt = miscParams->find("left");
+			NameValuePairList::const_iterator end = miscParams->end();
+
+			if ((opt = miscParams->find("title")) != end)
+				title = opt->second;
+
+			if ((opt = miscParams->find("left")) != end)
+				mLeft = StringConverter::parseInt(opt->second);
+
+			if ((opt = miscParams->find("top")) != end)
+				mTop = StringConverter::parseInt(opt->second);
+
+			if ((opt = miscParams->find("depthBuffer")) != end)
+				mIsDepthBuffered = StringConverter::parseBool(opt->second);
+
+			if ((opt = miscParams->find("vsync")) != end)
+				vsync = StringConverter::parseBool(opt->second);
+
+			if ((opt = miscParams->find("FSAA")) != end)
+				fsaa = StringConverter::parseUnsignedInt(opt->second);
+
+			if ((opt = miscParams->find("externalWindowHandle")) != end)
+			{
+				mHWnd = (HWND)StringConverter::parseUnsignedInt(opt->second);
+				if (mHWnd)
+				{
+					mIsExternal = true;
+					mIsFullScreen = false;
+				}
+			}
+			// window border style
+			opt = miscParams->find("border");
 			if(opt != miscParams->end())
-				left = StringConverter::parseUnsignedInt(opt->second);
-			// top (y)
-			opt = miscParams->find("top");
+				border = opt->second;
+			// set outer dimensions?
+			opt = miscParams->find("outerDimensions");
 			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);
-		}
+				outerSize = StringConverter::parseBool(opt->second);
 		
-		// Destroy current window if any
-		if( mHWnd )
-			destroy();
-
-        if (fullScreen)
+			if (mIsFullScreen)
         {
-			mColourDepth = colourDepth;
+				// only available with fullscreen
+				if ((opt = miscParams->find("displayFrequency")) != end)
+					mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second);
+				if ((opt = miscParams->find("colourDepth")) != end)
+					mColourDepth = StringConverter::parseUnsignedInt(opt->second);
         }
 		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)
+				// incompatible with fullscreen
+				if ((opt = miscParams->find("parentWindowHandle")) != end)
+					parent = (HWND)StringConverter::parseUnsignedInt(opt->second);
+			}
+		}
+
+		if (!mIsExternal)
 			{
-				// 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)
+			DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
+			DWORD dwStyleEx = 0;
+			int outerw, outerh;
+
+			if (mIsFullScreen)
                 {
-					mLeft = (GetSystemMetrics(SM_CXSCREEN) / 2) - (mWidth / 2);
+				dwStyle |= WS_POPUP;
+				dwStyleEx |= WS_EX_TOPMOST;
+				outerw = mWidth;
+				outerh = mHeight;
+				mLeft = mTop = 0;
                 }
 				else
                 {
-					mLeft = left;
-                }
-				if (!top)
+				if (border == "none")
+					dwStyle |= WS_POPUP;
+				else if (border == "fixed")
+					dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
+					WS_SYSMENU | WS_MINIMIZEBOX;
+				else
+					dwStyle |= WS_OVERLAPPEDWINDOW;
+
+				int screenw = GetSystemMetrics(SM_CXSCREEN);
+				int screenh = GetSystemMetrics(SM_CYSCREEN);
+
+				if (!outerSize)
                 {
-					mTop = (GetSystemMetrics(SM_CYSCREEN) / 2) - (mHeight / 2);
-                }
-				else
-                {
-                    mTop = top;
-                }
+					// calculate overall dimensions for requested client area
+					RECT rc = { 0, 0, mWidth, mHeight };
+					AdjustWindowRect(&rc, dwStyle, false);
+
+					// clamp window dimensions to screen size
+					outerw = (rc.right-rc.left < screenw)? rc.right-rc.left : screenw;
+					outerh = (rc.bottom-rc.top < screenh)? rc.bottom-rc.top : screenh;
+            }
+
+				// center window if given negative coordinates
+				if (mLeft < 0)
+					mLeft = (screenw - outerw) / 2;
+				if (mTop < 0)
+					mTop = (screenh - outerh) / 2;
+
+				// keep window contained in visible screen area
+				if (mLeft > screenw - outerw)
+					mLeft = screenw - outerw;
+				if (mTop > screenh - outerh)
+					mTop = screenh - outerh;
 			}
-			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");
-
+
+			// register class and create window
+			WNDCLASS wc = { CS_OWNDC, WndProc, 0, 0, hInst,
+				LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
+				(HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLWindow" };
+			RegisterClass(&wc);
+
+			// Pass pointer to self as WM_CREATE parameter
+			mHWnd = CreateWindowEx(dwStyleEx, "OgreGLWindow", title.c_str(),
+				dwStyle, mLeft, mTop, outerw, outerh, parent, 0, hInst, this);
+
+			StringUtil::StrStreamType str;
+			str << "Created Win32Window '"
+				<< mName << "' : " << mWidth << "x" << mHeight
+				<< ", " << mColourDepth << "bpp";
+			LogManager::getSingleton().logMessage(LML_NORMAL, str.str());
+
+			if (mIsFullScreen)
+			{
+				DEVMODE dm;
+				dm.dmSize = sizeof(DEVMODE);
+				dm.dmBitsPerPel = mColourDepth;
+				dm.dmPelsWidth = mWidth;
+				dm.dmPelsHeight = mHeight;
+				dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+				if (mDisplayFrequency)
+				{
+					dm.dmDisplayFrequency = mDisplayFrequency;
+					dm.dmFields |= DM_DISPLAYFREQUENCY;
+				}
+				if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
+					LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed");
+			}
 		    }
 
-		}
-		else {
-			mHWnd = externalHandle;
 			RECT rc;
+		// top and left represent outer window position
+		GetWindowRect(mHWnd, &rc);
+		mTop = rc.top;
+		mLeft = rc.left;
+		// width and height represent drawable area only
 			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)
+		mHDC = GetDC(mHWnd);
+
+		if (!mGLSupport.selectPixelFormat(mHDC, mColourDepth, fsaa))
+		{
+			if (fsaa == 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))
+			if (!mGLSupport.selectPixelFormat(mHDC, mColourDepth, 0))
 				OGRE_EXCEPT(0, "selectPixelFormat failed", "Win32Window::create");
 		}
 
-		HGLRC glrc = wglCreateContext(hdc);
-		if (!glrc)
+		mGlrc = wglCreateContext(mHDC);
+		if (!mGlrc)
 			OGRE_EXCEPT(0, "wglCreateContext", "Win32Window::create");
-		if (!wglMakeCurrent(hdc, glrc))
+		if (!wglMakeCurrent(mHDC, mGlrc))
 			OGRE_EXCEPT(0, "wglMakeCurrent", "Win32Window::create");
 		
-		mGlrc = glrc;
-		mHDC = hdc;
-
-		mOldSwapIntervall = wglGetSwapIntervalEXT();
-		if (vsync) 
-			wglSwapIntervalEXT(1);
-		else
-			wglSwapIntervalEXT(0);
-
-		mReady = true;
+		wglSwapIntervalEXT(vsync? 1 : 0);
 
         // Create RenderSystem context
@@ -260,8 +261,13 @@
         GLRenderSystem *rs = static_cast<GLRenderSystem*>(Root::getSingleton().getRenderSystem());
         rs->_registerContext(this, mContext);
+
+		mActive = true;
     }
 
     void Win32Window::destroy(void)
     {
+		if (!mHWnd)
+			return;
+
         // Unregister and destroy OGRE GLContext
         if (mContext)
@@ -270,32 +276,25 @@
             rs->_unregisterContext(this);
             delete mContext;
-            mContext = NULL;
-
-            wglSwapIntervalEXT(mOldSwapIntervall);
+			mContext = 0;
         }
-		if (mGlrc) {
-			wglMakeCurrent(NULL, NULL);
+		if (mGlrc)
+		{
 			wglDeleteContext(mGlrc);
-			mGlrc = NULL;
-		}
-		if (mHDC) {
-			ReleaseDC(mHWnd, mHDC);
-			mHDC = NULL;
-		}
+			mGlrc = 0;
+		}
+		if (!mIsExternal)
+		{
 		if (mIsFullScreen)
-		{
 			ChangeDisplaySettings(NULL, 0);
-		}
-        if (mHWnd)
-        {
 	        DestroyWindow(mHWnd);
-            mHWnd = 0;
         }
         mActive = false;
-    }
-
-    bool Win32Window::isActive() const
-    {
-        return mActive;
+		mHDC = 0; // no release thanks to CS_OWNDC wndclass style
+		mHWnd = 0;
+    }
+
+	bool Win32Window::isVisible() const
+    {
+		return (mHWnd && !IsIconic(mHWnd));
     }
 
@@ -307,12 +306,42 @@
     void Win32Window::reposition(int left, int top)
     {
-        // XXX FIXME
+		if (mHWnd && !mIsFullScreen)
+		{
+			SetWindowPos(mHWnd, 0, left, top, 0, 0,
+				SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+		}
     }
 
     void Win32Window::resize(unsigned int width, unsigned int height)
     {
-
-		mWidth = width;
-		mHeight = height;
+		if (mHWnd && !mIsFullScreen)
+		{
+			RECT rc = { 0, 0, width, height };
+			AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
+			width = rc.right - rc.left;
+			height = rc.bottom - rc.top;
+			SetWindowPos(mHWnd, 0, 0, 0, width, height,
+				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
+		}
+	}
+
+	void Win32Window::windowMovedOrResized()
+	{
+		if (!isVisible())
+			return;
+
+		RECT rc;
+		// top and left represent outer window position
+		GetWindowRect(mHWnd, &rc);
+		mTop = rc.top;
+		mLeft = rc.left;
+		// width and height represent drawable area only
+		GetClientRect(mHWnd, &rc);
+
+		if (mWidth == rc.right && mHeight == rc.bottom)
+			return;
+
+		mWidth = rc.right;
+		mHeight = rc.bottom;
 
 		// Notify viewports of resize
@@ -321,13 +350,4 @@
 		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
 	}
 
@@ -406,66 +426,64 @@
 	LRESULT Win32Window::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
 	{
-		Win32Window* win;
+
+		if (uMsg == WM_CREATE)
+		{
+			// Store pointer to Win32Window in user data area
+			SetWindowLong(hWnd, GWL_USERDATA,
+				(LONG)(((LPCREATESTRUCT)lParam)->lpCreateParams));
+			return 0;
+		}
 
 		// look up window instance
-		if( WM_CREATE != uMsg )
-			win = (Win32Window*)GetWindowLong( hWnd, 0 );
+		// note: it is possible to get a WM_SIZE before WM_CREATE
+		Win32Window* win = (Win32Window*)GetWindowLong(hWnd, GWL_USERDATA);
+		if (!win)
+			return DefWindowProc(hWnd, uMsg, wParam, lParam);
 
 		switch( uMsg )
 		{
 		case WM_ACTIVATE:
-			if( WA_INACTIVE == LOWORD( wParam ) )
+			if (win->mIsFullScreen)
+			{
+				if (LOWORD(wParam) == WA_INACTIVE)
+				{
 				win->mActive = false;
+					ChangeDisplaySettings(NULL, 0);
+					ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
+				}
 			else
+				{
 				win->mActive = true;
+					ShowWindow(hWnd, SW_SHOWNORMAL);
+
+					DEVMODE dm;
+					dm.dmSize = sizeof(DEVMODE);
+					dm.dmBitsPerPel = win->mColourDepth;
+					dm.dmPelsWidth = win->mWidth;
+					dm.dmPelsHeight = win->mHeight;
+					dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+					if (win->mDisplayFrequency)
+					{
+						dm.dmDisplayFrequency = win->mDisplayFrequency;
+						dm.dmFields |= DM_DISPLAYFREQUENCY;
+					}
+					ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
+				}
+			}
 			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;
+			win->mSizing = true;
 			break;
 
 		case WM_EXITSIZEMOVE:
 			win->windowMovedOrResized();
-			win->mReady = true;
+			win->mSizing = false;
 			break;
 
+		case WM_MOVE:
 		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 )
+			if (!win->mSizing)
 					win->windowMovedOrResized();
-			}
 			break;
 
@@ -477,5 +495,5 @@
 
 		case WM_CLOSE:
-			DestroyWindow( win->mHWnd );
+			win->destroy(); // will call DestroyWindow
 			win->mClosed = true;
 			return 0;
