瀏覽代碼

More documentation

Marko Pintera 11 年之前
父節點
當前提交
21e4301182
共有 26 個文件被更改,包括 860 次插入2724 次删除
  1. 12 0
      BansheeCore/Include/BsGpuProgramManager.h
  2. 1 2
      BansheeGLRenderSystem/BansheeGLRenderSystem.vcxproj
  3. 2 5
      BansheeGLRenderSystem/BansheeGLRenderSystem.vcxproj.filters
  4. 16 48
      BansheeGLRenderSystem/Include/BsGLContext.h
  5. 2 32
      BansheeGLRenderSystem/Include/BsGLPrerequisites.h
  6. 29 20
      BansheeGLRenderSystem/Include/BsGLSupport.h
  7. 18 2
      BansheeGLRenderSystem/Include/BsWin32Context.h
  8. 44 13
      BansheeGLRenderSystem/Include/BsWin32GLSupport.h
  9. 3 0
      BansheeGLRenderSystem/Include/BsWin32Prerequisites.h
  10. 8 8
      BansheeGLRenderSystem/Include/BsWin32VideoModeInfo.h
  11. 27 20
      BansheeGLRenderSystem/Include/BsWin32Window.h
  12. 0 1
      BansheeGLRenderSystem/Source/BsGLContext.cpp
  13. 533 0
      BansheeGLRenderSystem/Source/BsGLSLParamParser.cpp
  14. 0 37
      BansheeGLRenderSystem/Source/BsGLSupport.cpp
  15. 4 4
      BansheeGLRenderSystem/Source/BsWin32GLSupport.cpp
  16. 12 13
      BansheeGLRenderSystem/Source/BsWin32Window.cpp
  17. 29 72
      BansheeGLRenderSystem/Source/GLSL/include/BsGLSLGpuProgram.h
  18. 66 538
      BansheeGLRenderSystem/Source/GLSL/include/BsGLSLParamParser.h
  19. 0 525
      BansheeGLRenderSystem/Source/GLSL/include/BsGLSLPreprocessor.h
  20. 15 3
      BansheeGLRenderSystem/Source/GLSL/include/BsGLSLProgramFactory.h
  21. 24 0
      BansheeGLRenderSystem/Source/GLSL/include/BsGLSLProgramPipelineManager.h
  22. 3 74
      BansheeGLRenderSystem/Source/GLSL/src/BsGLSLGpuProgram.cpp
  23. 0 1301
      BansheeGLRenderSystem/Source/GLSL/src/BsGLSLPreprocessor.cpp
  24. 7 0
      BansheeGLRenderSystem/Source/win32/BsGLUtil.h
  25. 4 4
      ExampleProject/Main/Main.cpp
  26. 1 2
      Renderer.txt

+ 12 - 0
BansheeCore/Include/BsGpuProgramManager.h

@@ -21,6 +21,18 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual const String& getLanguage() const = 0;
 		virtual const String& getLanguage() const = 0;
 
 
+		/**
+		 * @brief	Creates a new GPU program using the provided source code. If compilation fails or program is not supported
+		 *			"isCompiled" method on the returned program will return false, and you will be able to retrieve the error message 
+		 *			via "getCompileErrorMessage".
+		 *
+		 * @param	source		Source code to compile the shader from.
+		 * @param	entryPoint	Name of the entry point function, e.g. "main".
+		 * @param	gptype		Type of the program, e.g. vertex or fragment.
+		 * @param	profile		Program profile specifying supported feature-set. Must match the type.
+		 * @param	includes	Optional includes to append to the source before compiling.
+		 * @param	requiresAdjacency	If true then adjacency information will be provided when rendering using this program.
+		 */
 		virtual GpuProgramPtr create(const String& source, const String& entryPoint, GpuProgramType gptype, 
 		virtual GpuProgramPtr create(const String& source, const String& entryPoint, GpuProgramType gptype, 
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requiresAdjacencyInformation) = 0;
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requiresAdjacencyInformation) = 0;
 
 

+ 1 - 2
BansheeGLRenderSystem/BansheeGLRenderSystem.vcxproj

@@ -265,13 +265,13 @@
     <ClInclude Include="Include\BsWin32Window.h" />
     <ClInclude Include="Include\BsWin32Window.h" />
     <ClInclude Include="Source\GLSL\include\BsGLSLGpuProgram.h" />
     <ClInclude Include="Source\GLSL\include\BsGLSLGpuProgram.h" />
     <ClInclude Include="Source\GLSL\include\BsGLSLParamParser.h" />
     <ClInclude Include="Source\GLSL\include\BsGLSLParamParser.h" />
-    <ClInclude Include="Source\GLSL\include\BsGLSLPreprocessor.h" />
     <ClInclude Include="Source\GLSL\include\BsGLSLProgramFactory.h" />
     <ClInclude Include="Source\GLSL\include\BsGLSLProgramFactory.h" />
     <ClInclude Include="Source\GLSL\include\BsGLSLProgramPipelineManager.h" />
     <ClInclude Include="Source\GLSL\include\BsGLSLProgramPipelineManager.h" />
     <ClInclude Include="Source\win32\BsGLUtil.h" />
     <ClInclude Include="Source\win32\BsGLUtil.h" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="BsGLPlugin.cpp" />
     <ClCompile Include="BsGLPlugin.cpp" />
+    <ClCompile Include="Source\BsGLSLParamParser.cpp" />
     <ClCompile Include="Source\BsGLVertexArrayObjectManager.cpp" />
     <ClCompile Include="Source\BsGLVertexArrayObjectManager.cpp" />
     <ClCompile Include="Source\BsGLContext.cpp" />
     <ClCompile Include="Source\BsGLContext.cpp" />
     <ClCompile Include="Source\BsGLEventQuery.cpp" />
     <ClCompile Include="Source\BsGLEventQuery.cpp" />
@@ -299,7 +299,6 @@
     <ClCompile Include="Source\BsWin32Window.cpp" />
     <ClCompile Include="Source\BsWin32Window.cpp" />
     <ClCompile Include="Source\glew.cpp" />
     <ClCompile Include="Source\glew.cpp" />
     <ClCompile Include="Source\GLSL\src\BsGLSLGpuProgram.cpp" />
     <ClCompile Include="Source\GLSL\src\BsGLSLGpuProgram.cpp" />
-    <ClCompile Include="Source\GLSL\src\BsGLSLPreprocessor.cpp" />
     <ClCompile Include="Source\GLSL\src\BsGLSLProgramFactory.cpp" />
     <ClCompile Include="Source\GLSL\src\BsGLSLProgramFactory.cpp" />
     <ClCompile Include="Source\GLSL\src\BsGLSLProgramPipelineManager.cpp" />
     <ClCompile Include="Source\GLSL\src\BsGLSLProgramPipelineManager.cpp" />
     <ClCompile Include="Source\win32\BsWin32Context.cpp" />
     <ClCompile Include="Source\win32\BsWin32Context.cpp" />

+ 2 - 5
BansheeGLRenderSystem/BansheeGLRenderSystem.vcxproj.filters

@@ -126,9 +126,6 @@
     <ClInclude Include="Source\GLSL\include\BsGLSLProgramFactory.h">
     <ClInclude Include="Source\GLSL\include\BsGLSLProgramFactory.h">
       <Filter>Header Files\GLSL</Filter>
       <Filter>Header Files\GLSL</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Source\GLSL\include\BsGLSLPreprocessor.h">
-      <Filter>Header Files\GLSL</Filter>
-    </ClInclude>
     <ClInclude Include="Source\GLSL\include\BsGLSLParamParser.h">
     <ClInclude Include="Source\GLSL\include\BsGLSLParamParser.h">
       <Filter>Header Files\GLSL</Filter>
       <Filter>Header Files\GLSL</Filter>
     </ClInclude>
     </ClInclude>
@@ -227,10 +224,10 @@
     <ClCompile Include="Source\GLSL\src\BsGLSLProgramFactory.cpp">
     <ClCompile Include="Source\GLSL\src\BsGLSLProgramFactory.cpp">
       <Filter>Source Files\GLSL</Filter>
       <Filter>Source Files\GLSL</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="Source\GLSL\src\BsGLSLPreprocessor.cpp">
+    <ClCompile Include="Source\GLSL\src\BsGLSLGpuProgram.cpp">
       <Filter>Source Files\GLSL</Filter>
       <Filter>Source Files\GLSL</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="Source\GLSL\src\BsGLSLGpuProgram.cpp">
+    <ClCompile Include="Source\BsGLSLParamParser.cpp">
       <Filter>Source Files\GLSL</Filter>
       <Filter>Source Files\GLSL</Filter>
     </ClCompile>
     </ClCompile>
   </ItemGroup>
   </ItemGroup>

+ 16 - 48
BansheeGLRenderSystem/Include/BsGLContext.h

@@ -1,64 +1,32 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-#ifndef __OgreGLContext_H__
-#define __OgreGLContext_H__
+#pragma once
 
 
 #include "BsGLPrerequisites.h"
 #include "BsGLPrerequisites.h"
 
 
-namespace BansheeEngine {
-
-    /**
-     * Class that encapsulates an GL context. (IE a window/pbuffer). This is a 
-     * virtual base class which should be implemented in a GLSupport.
-     * This object can also be used to cache renderstate if we decide to do so
-     * in the future.
-     */
+namespace BansheeEngine 
+{
+	/**
+	 * @brief	Abstract class that encapsulated an OpenGL context. Each platform
+	 *			should provide its own GLContext specialization.
+	 */
     class BS_RSGL_EXPORT GLContext
     class BS_RSGL_EXPORT GLContext
     {
     {
     public:
     public:
         GLContext();
         GLContext();
         virtual ~GLContext();
         virtual ~GLContext();
 
 
-        /**
-         * Enable the context. All subsequent rendering commands will go here.
-         */
+		/**
+		 * @brief	Activates the rendering context (all subsequent rendering commands will be executed on it).
+		 */
         virtual void setCurrent() = 0;
         virtual void setCurrent() = 0;
-        /**
-         * This is called before another context is made current. By default,
-         * nothing is done here.
-         */
+
+		/**
+		 * @brief	Deactivates the rendering context. Normally called just before setCurrent is called on another context.
+		 */
         virtual void endCurrent() = 0;
         virtual void endCurrent() = 0;
         
         
 		/**
 		/**
-		* Release the render context.
-		*/
+		 * @brief	Releases the render context, freeing all of its resources.
+		 */
 		virtual void releaseContext() {}
 		virtual void releaseContext() {}
     };
     };
 }
 }
-
-#endif

+ 2 - 32
BansheeGLRenderSystem/Include/BsGLPrerequisites.h

@@ -1,32 +1,4 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
-
-Copyright (c) 2000-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-#ifndef __GLPrerequisites_H__
-#define __GLPrerequisites_H__
+#pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
 
 
@@ -113,6 +85,4 @@ namespace BansheeEngine
 #    define BS_RSGL_EXPORT  __attribute__ ((visibility("default")))
 #    define BS_RSGL_EXPORT  __attribute__ ((visibility("default")))
 #else
 #else
 #    define BS_RSGL_EXPORT
 #    define BS_RSGL_EXPORT
-#endif
-
-#endif //#ifndef __GLPrerequisites_H__
+#endif

+ 29 - 20
BansheeGLRenderSystem/Include/BsGLSupport.h

@@ -6,58 +6,67 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	/**
+	 * @brief	Helper class dealing mostly with platform specific OpenGL functionality,
+	 *			initialization, extensions and window creation.
+	 */
 	class BS_RSGL_EXPORT GLSupport
 	class BS_RSGL_EXPORT GLSupport
 	{
 	{
 	public:
 	public:
 		GLSupport() { }
 		GLSupport() { }
 		virtual ~GLSupport() { }
 		virtual ~GLSupport() { }
 
 
+		/**
+		 * @brief	Creates a new render window using the specified descriptor.
+		 *
+		 * @param	desc			Description of a render window to create.
+		 * @param	parentWindow	Optional parent window if the window shouldn't be a main window. First
+		 *							created window cannot have a parent.
+		 *
+		 * @param	Returns newly created window.
+		 */
 		virtual RenderWindowPtr newWindow(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow) = 0;
 		virtual RenderWindowPtr newWindow(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow) = 0;
 
 
 		/**
 		/**
-		* Start anything special
-		*/
+		 * @brief	Called when OpenGL is being initialized.
+		 */
 		virtual void start() = 0;
 		virtual void start() = 0;
 
 
 		/**
 		/**
-		* Stop anything special
-		*/
+		 * @brief	Called when OpenGL is being shut down.
+		 */
 		virtual void stop() = 0;
 		virtual void stop() = 0;
 
 
 		/**
 		/**
-		* Get vendor information
-		*/
+		 * @brief	Gets OpenGL vendor name.
+		 */
 		const String& getGLVendor() const
 		const String& getGLVendor() const
 		{
 		{
 			return mVendor;
 			return mVendor;
 		}
 		}
 
 
 		/**
 		/**
-		* Get version information
-		*/
+		 * @brief	Gets OpenGL version string.
+		 */
 		const String& getGLVersion() const
 		const String& getGLVersion() const
 		{
 		{
 			return mVersion;
 			return mVersion;
 		}
 		}
 
 
 		/**
 		/**
-		* Compare GL version numbers
-		*/
-		bool checkMinGLVersion(const String& v) const;
-
-		/**
-		* Check if an extension is available
-		*/
+		 * @brief	Checks is the specified extension available.
+		 */
 		virtual bool checkExtension(const String& ext) const;
 		virtual bool checkExtension(const String& ext) const;
 
 
 		/**
 		/**
-		* Get the address of a function
-		*/
+		 * @brief	Gets an address of an OpenGL procedure with the specified name.
+		 */
 		virtual void* getProcAddress(const String& procname) = 0;
 		virtual void* getProcAddress(const String& procname) = 0;
 
 
-		/** Initialises GL extensions, must be done AFTER the GL context has been
-			established.
-		*/
+		/**
+		 * @brief	Initializes OpenGL extensions. Must be called after we have a valid and active
+		 *			OpenGL context.
+		 */
 		virtual void initializeExtensions();
 		virtual void initializeExtensions();
 
 
 		/**
 		/**

+ 18 - 2
BansheeGLRenderSystem/Include/BsWin32Context.h

@@ -5,17 +5,33 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
+	/**
+	 * @brief	Windows specific implementation of an OpenGL context.
+	 */
     class BS_RSGL_EXPORT Win32Context : public GLContext
     class BS_RSGL_EXPORT Win32Context : public GLContext
     {
     {
     public:
     public:
+		/**
+		 * @brief	Constructs a new context from a Windows device context and OpenGL rendering context.
+		 *			Optionally you may specify that the context isn't owned by us (might be created by some external
+		 *			library), in which case it will not be automatically released.
+		 */
         Win32Context(HDC hdc, HGLRC glrc, bool ownsContext);
         Win32Context(HDC hdc, HGLRC glrc, bool ownsContext);
         virtual ~Win32Context();
         virtual ~Win32Context();
 
 
-        /** See GLContext */
+        /**
+         * @copydoc	GLContext::setCurrent
+         */
         virtual void setCurrent();
         virtual void setCurrent();
-		/** See GLContext */
+
+        /**
+         * @copydoc	GLContext::endCurrent
+         */
 		virtual void endCurrent();
 		virtual void endCurrent();
 
 
+        /**
+         * @copydoc	GLContext::releaseContext
+         */
 		virtual void releaseContext();
 		virtual void releaseContext();
 
 
 	protected:
 	protected:

+ 44 - 13
BansheeGLRenderSystem/Include/BsWin32GLSupport.h

@@ -6,37 +6,62 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	/**
+	 * @brief	Handles OpenGL initialization, window creation and extensions
+	 *			on Windows.
+	 */
 	class BS_RSGL_EXPORT Win32GLSupport : public GLSupport
 	class BS_RSGL_EXPORT Win32GLSupport : public GLSupport
 	{
 	{
 	public:
 	public:
         Win32GLSupport();
         Win32GLSupport();
 
 
-		/// @copydoc RenderSystem::_createRenderWindow
+		/**
+		 * @copydoc	GLSupport::newWindow
+		 */
 		virtual RenderWindowPtr newWindow(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow);
 		virtual RenderWindowPtr newWindow(RENDER_WINDOW_DESC& desc, RenderWindowPtr parentWindow);
 
 
 		/**
 		/**
-		* Start anything special
-		*/
+		 * @copydoc	GLSupport::start
+		 */
 		void start();
 		void start();
 
 
 		/**
 		/**
-		* Stop anything special
-		*/
+		 * @copydoc	GLSupport::stop
+		 */
 		void stop();
 		void stop();
 
 
 		/**
 		/**
-		* Get the address of a function
-		*/
+		 * @copydoc	GLSupport::getProcAddress
+		 */
 		void* getProcAddress(const String& procname);
 		void* getProcAddress(const String& procname);
 
 
 		/**
 		/**
-		 * Initialize extensions
+		 * @copydoc	GLSupport::initializeExtensions
 		 */
 		 */
 		virtual void initializeExtensions();
 		virtual void initializeExtensions();
 		
 		
+		/**
+		 * @brief	Creates a new OpenGL context.
+		 *
+		 * @param	hdc				Handle to device context to create the context from.
+		 * @param	externalGlrc	(Optional) Handle to external OpenGL context. If not provided
+		 *							new context will be created.
+		 *
+		 * @returns	Newly created GLContext class referencing the created or external context handle.
+		 */
 		Win32Context* createContext(HDC hdc, HGLRC externalGlrc = 0);
 		Win32Context* createContext(HDC hdc, HGLRC externalGlrc = 0);
 
 
-		bool selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma);
+		/**
+		 * @brief	Selects and sets an appropriate pixel format based on the provided parameters.
+		 *
+		 * @param	hdc			Handle to device context to create the context from.
+		 * @param	colorDepth	Wanted color depth of the pixel format, in bits.
+		 * @param	multisample	Amount of multisampling wanted, if any.
+		 * @param	hwGamma		Should the format support automatic gamma conversion on write/read.
+		 *
+		 * @returns	True if a pixel format was successfully set.
+		 */
+		bool selectPixelFormat(HDC hdc, int colorDepth, int multisample, bool hwGamma);
 
 
 		/**
 		/**
 		 * @copydoc	GLSupport::getVideoModeInfo
 		 * @copydoc	GLSupport::getVideoModeInfo
@@ -44,7 +69,16 @@ namespace BansheeEngine
 		VideoModeInfoPtr getVideoModeInfo() const;
 		VideoModeInfoPtr getVideoModeInfo() const;
 
 
 	private:
 	private:
-		// Allowed video modes
+		/**
+		 * @brief	Initializes windows specific OpenGL extensions needed for advanced context creation.
+		 */
+		void initialiseWGL();
+
+		/**
+		 * @brief	Dummy window procedure used when creating the initial dummy OpenGL context.
+		 */
+		static LRESULT CALLBACK dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp);
+
 		Vector<DEVMODE> mDevModes;
 		Vector<DEVMODE> mDevModes;
 		Win32Window *mInitialWindow;
 		Win32Window *mInitialWindow;
 		Vector<int> mMultisampleLevels;
 		Vector<int> mMultisampleLevels;
@@ -52,8 +86,5 @@ namespace BansheeEngine
         bool mHasMultisample;
         bool mHasMultisample;
 		bool mHasHardwareGamma;
 		bool mHasHardwareGamma;
 		bool mHasAdvancedContext;
 		bool mHasAdvancedContext;
-
-		void initialiseWGL();
-		static LRESULT CALLBACK dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp);
 	};
 	};
 }
 }

+ 3 - 0
BansheeGLRenderSystem/Include/BsWin32Prerequisites.h

@@ -9,5 +9,8 @@ namespace BansheeEngine
     class Win32Window;
     class Win32Window;
     class Win32Context;
     class Win32Context;
 
 
+	/**
+	 * @brief	Retrieves last Windows API error and returns a description of it.
+	 */
 	String translateWGLError();
 	String translateWGLError();
 }
 }

+ 8 - 8
BansheeGLRenderSystem/Include/BsWin32VideoModeInfo.h

@@ -6,8 +6,8 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	/**
 	/**
-	* @copydoc	VideoMode
-	*/
+	 * @copydoc	VideoMode
+	 */
 	class BS_RSGL_EXPORT Win32VideoMode : public VideoMode
 	class BS_RSGL_EXPORT Win32VideoMode : public VideoMode
 	{
 	{
 	public:
 	public:
@@ -18,8 +18,8 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/**
 	/**
-	* @copydoc	VideoOutputInfo
-	*/
+	 * @copydoc	VideoOutputInfo
+	 */
 	class BS_RSGL_EXPORT Win32VideoOutputInfo : public VideoOutputInfo
 	class BS_RSGL_EXPORT Win32VideoOutputInfo : public VideoOutputInfo
 	{
 	{
 	public:
 	public:
@@ -27,8 +27,8 @@ namespace BansheeEngine
 		~Win32VideoOutputInfo();
 		~Win32VideoOutputInfo();
 
 
 		/**
 		/**
-		* @brief	Gets a Win32 handle to the monitor referenced by this object.
-		*/
+		 * @brief	Gets a Win32 handle to the monitor referenced by this object.
+		 */
 		HMONITOR getMonitorHandle() const { return mMonitorHandle; }
 		HMONITOR getMonitorHandle() const { return mMonitorHandle; }
 
 
 	private:
 	private:
@@ -36,8 +36,8 @@ namespace BansheeEngine
 	};
 	};
 
 
 	/**
 	/**
-	* @copydoc	VideoModeInfo
-	*/
+	 * @copydoc	VideoModeInfo
+	 */
 	class BS_RSGL_EXPORT Win32VideoModeInfo : public VideoModeInfo
 	class BS_RSGL_EXPORT Win32VideoModeInfo : public VideoModeInfo
 	{
 	{
 	public:
 	public:

+ 27 - 20
BansheeGLRenderSystem/Include/BsWin32Window.h

@@ -5,6 +5,9 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
+	/**
+	 * @brief	Render window implementation for Windows.
+	 */
     class BS_RSGL_EXPORT Win32Window : public RenderWindow
     class BS_RSGL_EXPORT Win32Window : public RenderWindow
     {
     {
     public:
     public:
@@ -88,18 +91,17 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc RenderWindow::setActive
 		 * @copydoc RenderWindow::setActive
 		 */
 		 */
-		virtual void setActive( bool state );
+		virtual void setActive(bool state);
 
 
 		/**
 		/**
 		 * @copydoc RenderWindow::_windowMovedOrResized
 		 * @copydoc RenderWindow::_windowMovedOrResized
 		 */
 		 */
-		void _windowMovedOrResized(void);
+		void _windowMovedOrResized();
 
 
-		HWND _getWindowHandle() const { return mHWnd; }
+		/**
+		 * @brief	Returns handle to device context associated with the window.
+		 */
 		HDC _getHDC() const { return mHDC; }
 		HDC _getHDC() const { return mHDC; }
-		
-		void _adjustWindow(unsigned int clientWidth, unsigned int clientHeight, 
-			unsigned int* winWidth, unsigned int* winHeight);
 
 
 	protected:
 	protected:
 		friend class GLRenderWindowManager;
 		friend class GLRenderWindowManager;
@@ -117,19 +119,24 @@ namespace BansheeEngine
 		 */
 		 */
 		void destroy_internal();
 		void destroy_internal();
 
 
-		protected:
-			Win32GLSupport &mGLSupport;
-			HWND mHWnd;					// Win32 Window handle
-			HDC	mHDC;
-			DWORD mWindowedStyle;
-			DWORD mWindowedStyleEx;
-			bool mIsExternal;
-			bool mIsChild;
-			char* mDeviceName;
-			bool mIsExternalGLControl;
-			bool mSizing;
-			bool mClosed;
-			int mDisplayFrequency;      // fullscreen only, to restore display
-			Win32Context *mContext;
+		/**
+		 * @brief	Calculates window size based on provided client area size and currently set window style. 
+		 */
+		void getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight, UINT32* winWidth, UINT32* winHeight);
+
+	protected:
+		Win32GLSupport &mGLSupport;
+		HWND mHWnd;
+		HDC	mHDC;
+		DWORD mWindowedStyle;
+		DWORD mWindowedStyleEx;
+		bool mIsExternal;
+		bool mIsChild;
+		char* mDeviceName;
+		bool mIsExternalGLControl;
+		bool mSizing;
+		bool mClosed;
+		int mDisplayFrequency;
+		Win32Context *mContext;
     };
     };
 }
 }

+ 0 - 1
BansheeGLRenderSystem/Source/BsGLContext.cpp

@@ -2,7 +2,6 @@
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
-    // Empty base class
     GLContext::GLContext()
     GLContext::GLContext()
 	{ }
 	{ }
     
     

+ 533 - 0
BansheeGLRenderSystem/Source/BsGLSLParamParser.cpp

@@ -0,0 +1,533 @@
+#include "BsGLSLParamParser.h"
+
+namespace BansheeEngine
+{
+	INT32 GLSLAttribute::matchesName(const String& name)
+	{
+		if (name.length() >= mName.length())
+		{
+			if (name.substr(0, mName.length()) == mName)
+			{
+				String indexStr = name.substr(mName.length(), name.length());
+				return parseUnsignedInt(indexStr, 0);
+			}
+		}
+
+		return -1;
+	}
+
+	VertexDeclaration::VertexElementList GLSLParamParser::buildVertexDeclaration(GLuint glProgram)
+	{
+		GLint numAttributes = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTES, &numAttributes);
+
+		GLint maxNameSize = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameSize);
+
+		GLchar* attributeName = (GLchar*)bs_alloc<ScratchAlloc>(sizeof(GLchar)* maxNameSize);
+
+		VertexDeclaration::VertexElementList elementList;
+		for (GLint i = 0; i < numAttributes; i++)
+		{
+			GLint attribSize = 0;
+			GLenum attribType = 0;
+			glGetActiveAttrib(glProgram, i, maxNameSize, nullptr, &attribSize, &attribType, attributeName);
+
+			VertexElementSemantic semantic = VES_POSITION;
+			UINT16 index = 0;
+			if (attribNameToElementSemantic(attributeName, semantic, index))
+			{
+				VertexElementType type = glTypeToAttributeType(attribType);
+
+				elementList.push_back(VertexElement(0, i, type, semantic, index));
+			}
+			else
+			{
+				LOGWRN("Cannot determine vertex input attribute type for attribute: " + String(attributeName));
+			}
+		}
+
+		bs_free<ScratchAlloc>(attributeName);
+
+		return elementList;
+	}
+
+	VertexElementType GLSLParamParser::glTypeToAttributeType(GLenum glType)
+	{
+		switch (glType)
+		{
+		case GL_FLOAT:
+			return VET_FLOAT1;
+		case GL_FLOAT_VEC2:
+			return VET_FLOAT2;
+		case GL_FLOAT_VEC3:
+			return VET_FLOAT3;
+		case GL_FLOAT_VEC4:
+			return VET_FLOAT4;
+		default:
+			BS_EXCEPT(NotImplementedException, "OpenGL render system currently only supports float parameters.");
+		}
+	}
+
+	bool GLSLParamParser::attribNameToElementSemantic(const String& name, VertexElementSemantic& semantic, UINT16& index)
+	{
+		static GLSLAttribute attributes[] =
+		{
+			GLSLAttribute("bs_position", VES_POSITION),
+			GLSLAttribute("bs_normal", VES_NORMAL),
+			GLSLAttribute("bs_tangent", VES_TANGENT),
+			GLSLAttribute("bs_bitangent", VES_BITANGENT),
+			GLSLAttribute("bs_texcoord", VES_TEXCOORD),
+			GLSLAttribute("bs_color", VES_COLOR),
+			GLSLAttribute("bs_blendweights", VES_BLEND_WEIGHTS),
+			GLSLAttribute("bs_blendindices", VES_BLEND_INDICES)
+		};
+
+		static const UINT32 numAttribs = sizeof(attributes) / sizeof(attributes[0]);
+
+		for (UINT32 i = 0; i < numAttribs; i++)
+		{
+			INT32 attribIndex = attributes[i].matchesName(name);
+			if (attribIndex != -1)
+			{
+				index = attribIndex;
+				semantic = attributes[i].getSemantic();
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	void GLSLParamParser::buildUniformDescriptions(GLuint glProgram, GpuParamDesc& returnParamDesc)
+	{
+		// scan through the active uniforms and add them to the reference list
+		GLint maxBufferSize = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxBufferSize);
+
+		GLint maxBlockNameBufferSize = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxBlockNameBufferSize);
+
+		if (maxBlockNameBufferSize > maxBufferSize)
+			maxBufferSize = maxBlockNameBufferSize;
+
+		GLchar* uniformName = (GLchar*)bs_alloc<ScratchAlloc>(sizeof(GLchar)* maxBufferSize);
+
+		GpuParamBlockDesc newGlobalBlockDesc;
+		newGlobalBlockDesc.slot = 0;
+		newGlobalBlockDesc.name = "BS_INTERNAL_Globals";
+		newGlobalBlockDesc.blockSize = 0;
+		newGlobalBlockDesc.isShareable = false;
+
+		UINT32 textureSlot = 0;
+
+		returnParamDesc.paramBlocks[newGlobalBlockDesc.name] = newGlobalBlockDesc;
+		GpuParamBlockDesc& globalBlockDesc = returnParamDesc.paramBlocks[newGlobalBlockDesc.name];
+
+		GLint uniformBlockCount = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &uniformBlockCount);
+
+		Map<UINT32, String> blockSlotToName;
+		Set<String> blockNames;
+		for (GLuint index = 0; index < (GLuint)uniformBlockCount; index++)
+		{
+			GLsizei unusedSize = 0;
+			glGetActiveUniformBlockName(glProgram, index, maxBufferSize, &unusedSize, uniformName);
+
+			GpuParamBlockDesc newBlockDesc;
+			newBlockDesc.slot = index + 1;
+			newBlockDesc.name = uniformName;
+			newBlockDesc.blockSize = 0;
+			newBlockDesc.isShareable = true;
+
+			returnParamDesc.paramBlocks[newBlockDesc.name] = newBlockDesc;
+			blockSlotToName.insert(std::make_pair(newBlockDesc.slot, newBlockDesc.name));
+			blockNames.insert(newBlockDesc.name);
+		}
+
+		Map<String, UINT32> foundFirstArrayIndex;
+		Map<String, GpuParamDataDesc> foundStructs;
+
+		// get the number of active uniforms
+		GLint uniformCount = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &uniformCount);
+
+		// Loop over each of the active uniforms, and add them to the reference container
+		// only do this for user defined uniforms, ignore built in gl state uniforms
+		for (GLuint index = 0; index < (GLuint)uniformCount; index++)
+		{
+			GLsizei arraySize = 0;
+			glGetActiveUniformName(glProgram, index, maxBufferSize, &arraySize, uniformName);
+
+			String paramName = String(uniformName);
+
+			// Naming rules and packing rules used here are described in
+			// OpenGL Core Specification 2.11.4
+
+			// Check if parameter is a part of a struct
+			Vector<String> nameElements = StringUtil::tokenise(paramName, ".");
+
+			bool inStruct = false;
+			String structName;
+			if (nameElements.size() > 1)
+			{
+				auto uniformBlockFind = blockNames.find(nameElements[0]);
+
+				// Check if the name is not a struct, and instead a Uniform block namespace
+				if (uniformBlockFind != blockNames.end())
+				{
+					// Possibly it's a struct inside a named uniform block
+					if (nameElements.size() > 2)
+					{
+						inStruct = true;
+						structName = nameElements[1];
+					}
+				}
+				else
+				{
+					inStruct = true;
+					structName = nameElements[0];
+				}
+			}
+
+			String cleanParamName = paramName; // Param name without array indexes
+
+			// Check if the parameter is in an array
+			UINT32 arrayIdx = 0;
+			bool isInArray = false;
+			if (inStruct)
+			{
+				// If the uniform name has a "[" in it then its an array element uniform.
+				String::size_type arrayStart = structName.find("[");
+				String::size_type arrayEnd = structName.find("]");
+				if (arrayStart != String::npos)
+				{
+					String strArrIdx = structName.substr(arrayStart + 1, arrayEnd - (arrayStart + 1));
+					arrayIdx = parseUnsignedInt(strArrIdx, 0);
+					isInArray = true;
+
+					structName = structName.substr(0, arrayStart);
+				}
+			}
+			else
+			{
+				// If the uniform name has a "[" in it then its an array element uniform.
+				String::size_type arrayStart = cleanParamName.find("[");
+				String::size_type arrayEnd = cleanParamName.find("]");
+				if (arrayStart != String::npos)
+				{
+					String strArrIdx = cleanParamName.substr(arrayStart + 1, arrayEnd - (arrayStart + 1));
+					arrayIdx = parseUnsignedInt(strArrIdx, 0);
+					isInArray = true;
+
+					cleanParamName = cleanParamName.substr(0, arrayStart);
+				}
+			}
+
+			if (inStruct)
+			{
+				// OpenGL makes struct management really difficult, which is why I have given up on implementing this so far
+				// Some of the issues I encountered:
+				//  - Elements will be optimized out if they are not used. This makes it hard to determine proper structure size.
+				//     - If struct is within a Uniform buffer block, then it is possible because the element won't be optimized out of the buffer
+				//     - If the struct is within a global buffer, it is impossible to determine actual size, since the element will be optimized out of the buffer too
+				//     - Same issue happens with arrays, as OpenGL will optimize out array elements. With global buffers this makes it impossible to determine
+				//       actual array size (e.g. suppose OpenGL optimized out few last elements)
+				//        - Normal arrays work fine as OpenGL has utilities for reporting their actual size, but those do not work with structs
+
+				BS_EXCEPT(NotImplementedException, "Structs are not supported.")
+			}
+
+			// GLSL will optimize out unused array indexes, so there's no guarantee that 0 is the first,
+			// so we store the first one here
+			int firstArrayIndex = 0;
+			if (isInArray)
+			{
+				String& nameToSearch = cleanParamName;
+				if (inStruct)
+					nameToSearch = structName;
+
+				auto arrayIndexFind = foundFirstArrayIndex.find(nameToSearch);
+				if (arrayIndexFind == foundFirstArrayIndex.end())
+				{
+					foundFirstArrayIndex[nameToSearch] = arrayIdx;
+				}
+
+				firstArrayIndex = foundFirstArrayIndex[nameToSearch];
+			}
+
+
+			GLint uniformType;
+			glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_TYPE, &uniformType);
+
+			bool isSampler = false;
+			switch (uniformType)
+			{
+			case GL_SAMPLER_1D:
+			case GL_SAMPLER_2D:
+			case GL_SAMPLER_3D:
+			case GL_SAMPLER_CUBE:
+				isSampler = true;
+			}
+
+			if (isSampler)
+			{
+				GpuParamObjectDesc samplerParam;
+				samplerParam.name = paramName;
+				samplerParam.slot = glGetUniformLocation(glProgram, uniformName);
+
+				GpuParamObjectDesc textureParam;
+				textureParam.name = paramName;
+				textureParam.slot = samplerParam.slot;
+
+				switch (uniformType)
+				{
+				case GL_SAMPLER_1D:
+					samplerParam.type = GPOT_SAMPLER1D;
+					textureParam.type = GPOT_TEXTURE1D;
+					break;
+				case GL_SAMPLER_2D:
+					samplerParam.type = GPOT_SAMPLER2D;
+					textureParam.type = GPOT_TEXTURE2D;
+					break;
+				case GL_SAMPLER_3D:
+					samplerParam.type = GPOT_SAMPLER3D;
+					textureParam.type = GPOT_TEXTURE3D;
+					break;
+				case GL_SAMPLER_CUBE:
+					samplerParam.type = GPOT_SAMPLERCUBE;
+					textureParam.type = GPOT_TEXTURECUBE;
+					break;
+				}
+
+				returnParamDesc.samplers.insert(std::make_pair(paramName, samplerParam));
+				returnParamDesc.textures.insert(std::make_pair(paramName, textureParam));
+			}
+			else
+			{
+				// If array index is larger than 0 and uniform is not a part of a struct,
+				// it means we already processed it (struct arrays are processed differently)
+				if (!inStruct && arrayIdx != 0)
+					continue;
+
+				GLint blockIndex;
+				glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
+
+				GpuParamDataDesc gpuParam;
+
+				if (isInArray)
+					gpuParam.name = cleanParamName;
+				else
+					gpuParam.name = paramName;
+
+				determineParamInfo(gpuParam, paramName, glProgram, index);
+
+				if (blockIndex != -1)
+				{
+					GLint blockOffset;
+					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_OFFSET, &blockOffset);
+					blockOffset = blockOffset / 4;
+
+					gpuParam.gpuMemOffset = blockOffset;
+
+					gpuParam.paramBlockSlot = blockIndex + 1; // 0 is reserved for globals
+
+					String& blockName = blockSlotToName[gpuParam.paramBlockSlot];
+					GpuParamBlockDesc& curBlockDesc = returnParamDesc.paramBlocks[blockName];
+
+					gpuParam.cpuMemOffset = blockOffset;
+					curBlockDesc.blockSize = std::max(curBlockDesc.blockSize, gpuParam.cpuMemOffset + gpuParam.arrayElementStride * gpuParam.arraySize);
+				}
+				else
+				{
+					gpuParam.gpuMemOffset = glGetUniformLocation(glProgram, uniformName);
+					gpuParam.paramBlockSlot = 0;
+					gpuParam.cpuMemOffset = globalBlockDesc.blockSize;
+
+					globalBlockDesc.blockSize = std::max(globalBlockDesc.blockSize, gpuParam.cpuMemOffset + gpuParam.arrayElementStride * gpuParam.arraySize);
+				}
+
+				// If parameter is not a part of a struct we're done
+				if (!inStruct)
+				{
+					returnParamDesc.params.insert(std::make_pair(gpuParam.name, gpuParam));
+					continue;
+				}
+
+				// If the parameter is part of a struct, then we need to update the struct definition
+				auto findExistingStruct = foundStructs.find(structName);
+
+				// Create new definition if one doesn't exist
+				if (findExistingStruct == foundStructs.end())
+				{
+					foundStructs[structName] = GpuParamDataDesc();
+					GpuParamDataDesc& structDesc = foundStructs[structName];
+					structDesc.type = GPDT_STRUCT;
+					structDesc.name = structName;
+					structDesc.arraySize = 1;
+					structDesc.elementSize = 0;
+					structDesc.arrayElementStride = 0;
+					structDesc.gpuMemOffset = gpuParam.gpuMemOffset;
+					structDesc.cpuMemOffset = gpuParam.cpuMemOffset;
+					structDesc.paramBlockSlot = gpuParam.paramBlockSlot;
+				}
+
+				// Update struct with size of the new parameter
+				GpuParamDataDesc& structDesc = foundStructs[structName];
+
+				assert(gpuParam.cpuMemOffset >= structDesc.cpuMemOffset);
+				if (arrayIdx == firstArrayIndex) // Determine element size only using the first array element
+				{
+					structDesc.elementSize = std::max(structDesc.elementSize, (gpuParam.cpuMemOffset - structDesc.cpuMemOffset) + gpuParam.arrayElementStride * gpuParam.arraySize);
+					structDesc.arrayElementStride = structDesc.elementSize;
+				}
+
+				// New array element reached, determine arrayElementStride
+				if (arrayIdx != firstArrayIndex)
+				{
+					UINT32 numElements = arrayIdx - firstArrayIndex;
+					structDesc.arrayElementStride = (gpuParam.cpuMemOffset - structDesc.cpuMemOffset) / numElements;
+				}
+
+				structDesc.arraySize = std::max(structDesc.arraySize, arrayIdx + 1);
+			}
+		}
+
+		for (auto iter = foundStructs.begin(); iter != foundStructs.end(); ++iter)
+			returnParamDesc.params.insert(std::make_pair(iter->first, iter->second));
+
+		// Param blocks alway needs to be a multiple of 4, so make it so
+		for (auto iter = returnParamDesc.paramBlocks.begin(); iter != returnParamDesc.paramBlocks.end(); ++iter)
+		{
+			GpuParamBlockDesc& blockDesc = iter->second;
+
+			if (blockDesc.blockSize % 4 != 0)
+				blockDesc.blockSize += (4 - (blockDesc.blockSize % 4));
+		}
+
+#if BS_DEBUG_MODE
+		// Check if manually calculated and OpenGL buffer sizes match
+		for (auto iter = returnParamDesc.paramBlocks.begin(); iter != returnParamDesc.paramBlocks.end(); ++iter)
+		{
+			if (iter->second.slot == 0)
+				continue;
+
+			GLint blockSize = 0;
+			glGetActiveUniformBlockiv(glProgram, iter->second.slot - 1, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
+
+			assert(blockSize % 4 == 0);
+			blockSize = blockSize / 4;
+
+			if (iter->second.blockSize != blockSize)
+				BS_EXCEPT(InternalErrorException, "OpenGL specified and manual uniform block buffer sizes don't match!");
+		}
+#endif
+
+		bs_free<ScratchAlloc>(uniformName);
+	}
+
+	void GLSLParamParser::determineParamInfo(GpuParamDataDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex)
+	{
+		GLint arraySize;
+		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
+		desc.arraySize = arraySize;
+
+		GLint uniformType;
+		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_TYPE, &uniformType);
+
+		switch (uniformType)
+		{
+		case GL_BOOL:
+			desc.type = GPDT_BOOL;
+			desc.elementSize = 1;
+			break;
+		case GL_FLOAT:
+			desc.type = GPDT_FLOAT1;
+			desc.elementSize = 1;
+			break;
+		case GL_FLOAT_VEC2:
+			desc.type = GPDT_FLOAT2;
+			desc.elementSize = 2;
+			break;
+		case GL_FLOAT_VEC3:
+			desc.type = GPDT_FLOAT3;
+			desc.elementSize = 3;
+			break;
+		case GL_FLOAT_VEC4:
+			desc.type = GPDT_FLOAT4;
+			desc.elementSize = 4;
+			break;
+		case GL_INT:
+			desc.type = GPDT_INT1;
+			desc.elementSize = 1;
+			break;
+		case GL_INT_VEC2:
+			desc.type = GPDT_INT2;
+			desc.elementSize = 2;
+			break;
+		case GL_INT_VEC3:
+			desc.type = GPDT_INT3;
+			desc.elementSize = 3;
+			break;
+		case GL_INT_VEC4:
+			desc.type = GPDT_INT4;
+			desc.elementSize = 4;
+			break;
+		case GL_FLOAT_MAT2:
+			desc.type = GPDT_MATRIX_2X2;
+			desc.elementSize = 4;
+			break;
+		case GL_FLOAT_MAT3:
+			desc.type = GPDT_MATRIX_3X3;
+			desc.elementSize = 9;
+			break;
+		case GL_FLOAT_MAT4:
+			desc.type = GPDT_MATRIX_4X4;
+			desc.elementSize = 16;
+			break;
+		case GL_FLOAT_MAT2x3:
+			desc.type = GPDT_MATRIX_2X3;
+			desc.elementSize = 6;
+			break;
+		case GL_FLOAT_MAT3x2:
+			desc.type = GPDT_MATRIX_3X2;
+			desc.elementSize = 6;
+			break;
+		case GL_FLOAT_MAT2x4:
+			desc.type = GPDT_MATRIX_2X4;
+			desc.elementSize = 8;
+			break;
+		case GL_FLOAT_MAT4x2:
+			desc.type = GPDT_MATRIX_4X2;
+			desc.elementSize = 8;
+			break;
+		case GL_FLOAT_MAT3x4:
+			desc.type = GPDT_MATRIX_3X4;
+			desc.elementSize = 12;
+			break;
+		case GL_FLOAT_MAT4x3:
+			desc.type = GPDT_MATRIX_4X3;
+			desc.elementSize = 12;
+			break;
+		default:
+			BS_EXCEPT(InternalErrorException, "Invalid shader parameter type: " + toString(uniformType) + " for parameter " + paramName);
+		}
+
+		if (arraySize > 1)
+		{
+			GLint arrayStride;
+			glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE, &arrayStride);
+
+			if (arrayStride > 0)
+			{
+				assert(arrayStride % 4 == 0);
+
+				desc.arrayElementStride = arrayStride / 4;
+			}
+			else
+				desc.arrayElementStride = desc.elementSize;
+		}
+		else
+			desc.arrayElementStride = desc.elementSize;
+	}
+}

+ 0 - 37
BansheeGLRenderSystem/Source/BsGLSupport.cpp

@@ -33,43 +33,6 @@ namespace BansheeEngine
 		}
 		}
     }
     }
 
 
-    bool GLSupport::checkMinGLVersion(const String& v) const
-    {
-        unsigned int first, second, third;
-        unsigned int cardFirst, cardSecond, cardThird;
-        if(v == mVersion)
-            return true;
-
-        String::size_type pos = v.find(".");
-        if(pos == String::npos)
-            return false;
-
-        String::size_type pos1 = v.rfind(".");
-        if(pos1 == String::npos)
-            return false;
-
-        first = ::atoi(v.substr(0, pos).c_str());
-        second = ::atoi(v.substr(pos + 1, pos1 - (pos + 1)).c_str());
-        third = ::atoi(v.substr(pos1 + 1, v.length()).c_str());
-
-        pos = mVersion.find(".");
-        if(pos == String::npos)
-            return false;
-
-        pos1 = mVersion.rfind(".");
-        if(pos1 == String::npos)
-            return false;
-
-        cardFirst  = ::atoi(mVersion.substr(0, pos).c_str());
-        cardSecond = ::atoi(mVersion.substr(pos + 1, pos1 - (pos + 1)).c_str());
-        cardThird  = ::atoi(mVersion.substr(pos1 + 1, mVersion.length()).c_str());
-
-        if(first <= cardFirst && second <= cardSecond && third <= cardThird)
-          return true;
-
-        return false;
-    }
-
     bool GLSupport::checkExtension(const String& ext) const
     bool GLSupport::checkExtension(const String& ext) const
     {
     {
         if(extensionList.find(ext) == extensionList.end())
         if(extensionList.find(ext) == extensionList.end())

+ 4 - 4
BansheeGLRenderSystem/Source/BsWin32GLSupport.cpp

@@ -247,7 +247,7 @@ namespace BansheeEngine
 			wglDeleteContext(hrc);
 			wglDeleteContext(hrc);
 		}
 		}
 
 
-		// clean up our dummy window and class
+		// Clean up our dummy window and class
 		DestroyWindow(hwnd);
 		DestroyWindow(hwnd);
 		UnregisterClass(dummyText, hinst);
 		UnregisterClass(dummyText, hinst);
 	}
 	}
@@ -257,7 +257,7 @@ namespace BansheeEngine
 		return DefWindowProc(hwnd, umsg, wp, lp);
 		return DefWindowProc(hwnd, umsg, wp, lp);
 	}
 	}
 
 
-	bool Win32GLSupport::selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma)
+	bool Win32GLSupport::selectPixelFormat(HDC hdc, int colorDepth, int multisample, bool hwGamma)
 	{
 	{
 		PIXELFORMATDESCRIPTOR pfd;
 		PIXELFORMATDESCRIPTOR pfd;
 		memset(&pfd, 0, sizeof(pfd));
 		memset(&pfd, 0, sizeof(pfd));
@@ -265,8 +265,8 @@ namespace BansheeEngine
 		pfd.nVersion = 1;
 		pfd.nVersion = 1;
 		pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
 		pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
 		pfd.iPixelType = PFD_TYPE_RGBA;
 		pfd.iPixelType = PFD_TYPE_RGBA;
-		pfd.cColorBits = (colourDepth > 16)? 24 : colourDepth;
-		pfd.cAlphaBits = (colourDepth > 16)? 8 : 0;
+		pfd.cColorBits = (colorDepth > 16)? 24 : colorDepth;
+		pfd.cAlphaBits = (colorDepth > 16)? 8 : 0;
 		pfd.cDepthBits = 24;
 		pfd.cDepthBits = 24;
 		pfd.cStencilBits = 8;
 		pfd.cStencilBits = 8;
 
 

+ 12 - 13
BansheeGLRenderSystem/Source/BsWin32Window.cpp

@@ -165,7 +165,7 @@ namespace BansheeEngine
 				int screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top;
 				int screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top;
 
 
 				unsigned int winWidth, winHeight;
 				unsigned int winWidth, winHeight;
-				_adjustWindow(mDesc.videoMode.getWidth(), mDesc.videoMode.getHeight(), &winWidth, &winHeight);
+				getAdjustedWindowSize(mDesc.videoMode.getWidth(), mDesc.videoMode.getHeight(), &winWidth, &winHeight);
 
 
 				// clamp window dimensions to screen size
 				// clamp window dimensions to screen size
 				int outerw = (int(winWidth) < screenw)? int(winWidth) : screenw;
 				int outerw = (int(winWidth) < screenw)? int(winWidth) : screenw;
@@ -436,8 +436,8 @@ namespace BansheeEngine
 		ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
 		ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
 
 
 		// Calculate overall dimensions for requested client area
 		// Calculate overall dimensions for requested client area
-		unsigned int winWidth, winHeight;
-		_adjustWindow(mWidth, mHeight, &winWidth, &winHeight);
+		UINT32 winWidth, winHeight;
+		getAdjustedWindowSize(mWidth, mHeight, &winWidth, &winHeight);
 
 
 		// Deal with centering when switching down to smaller resolution
 		// Deal with centering when switching down to smaller resolution
 		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
 		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
@@ -449,8 +449,8 @@ namespace BansheeEngine
 		LONG screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
 		LONG screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
 		LONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 		LONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 
 
-		int left = screenw > int(winWidth) ? ((screenw - int(winWidth)) / 2) : 0;
-		int top = screenh > int(winHeight) ? ((screenh - int(winHeight)) / 2) : 0;
+		INT32 left = screenw > INT32(winWidth) ? ((screenw - INT32(winWidth)) / 2) : 0;
+		INT32 top = screenh > INT32(winHeight) ? ((screenh - INT32(winHeight)) / 2) : 0;
 
 
 		SetWindowLong(mHWnd, GWL_STYLE, mWindowedStyle);
 		SetWindowLong(mHWnd, GWL_STYLE, mWindowedStyle);
 		SetWindowLong(mHWnd, GWL_EXSTYLE, mWindowedStyleEx);
 		SetWindowLong(mHWnd, GWL_EXSTYLE, mWindowedStyleEx);
@@ -603,7 +603,7 @@ namespace BansheeEngine
 		else if(name == "WINDOW")
 		else if(name == "WINDOW")
 		{
 		{
 			HWND *pHwnd = (HWND*)pData;
 			HWND *pHwnd = (HWND*)pData;
-			*pHwnd = _getWindowHandle();
+			*pHwnd = mHWnd;
 			return;
 			return;
 		} 
 		} 
 	}
 	}
@@ -690,17 +690,15 @@ namespace BansheeEngine
 		RenderWindow::_windowMovedOrResized();
 		RenderWindow::_windowMovedOrResized();
 	}
 	}
 
 
-	void Win32Window::_adjustWindow(unsigned int clientWidth, unsigned int clientHeight, 
-		unsigned int* winWidth, unsigned int* winHeight)
+	void Win32Window::getAdjustedWindowSize(UINT32 clientWidth, UINT32 clientHeight, UINT32* winWidth, UINT32* winHeight)
 	{
 	{
-		// NB only call this for non full screen
 		RECT rc;
 		RECT rc;
 		SetRect(&rc, 0, 0, clientWidth, clientHeight);
 		SetRect(&rc, 0, 0, clientWidth, clientHeight);
-		AdjustWindowRect(&rc, WS_VISIBLE | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW, false);
+		AdjustWindowRectEx(&rc, mWindowedStyle, false, mWindowedStyleEx);
 		*winWidth = rc.right - rc.left;
 		*winWidth = rc.right - rc.left;
 		*winHeight = rc.bottom - rc.top;
 		*winHeight = rc.bottom - rc.top;
 
 
-		// adjust to monitor
+		// Adjust to monitor
 		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
 		HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
 
 
 		// Get monitor info	
 		// Get monitor info	
@@ -713,9 +711,10 @@ namespace BansheeEngine
 		LONG maxW = monitorInfo.rcWork.right  - monitorInfo.rcWork.left;
 		LONG maxW = monitorInfo.rcWork.right  - monitorInfo.rcWork.left;
 		LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 		LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 
 
-		if (*winWidth > (unsigned int)maxW)
+		if (*winWidth > (UINT32)maxW)
 			*winWidth = maxW;
 			*winWidth = maxW;
-		if (*winHeight > (unsigned int)maxH)
+
+		if (*winHeight > (UINT32)maxH)
 			*winHeight = maxH;
 			*winHeight = maxH;
 	}
 	}
 }
 }

+ 29 - 72
BansheeGLRenderSystem/Source/GLSL/include/BsGLSLGpuProgram.h

@@ -3,75 +3,42 @@
 #include "BsGLPrerequisites.h"
 #include "BsGLPrerequisites.h"
 #include "BsGpuProgram.h"
 #include "BsGpuProgram.h"
 
 
-namespace BansheeEngine {
-
-    /** GLSL low level compiled shader object - this class is used to get at the linked program object 
-		and provide an interface for GLRenderSystem calls.  GLSL does not provide access to the
-		low level code of the shader so this class is really just a dummy place holder.
-		GLSL uses a program object to represent the active vertex and fragment programs used
-		but Ogre materials maintain seperate instances of the active vertex and fragment programs
-		which creates a small problem for GLSL integration.  The GLSLGpuProgram class provides the
-		interface between the GLSLLinkProgramManager , GLRenderSystem, and the active GLSLProgram
-		instances.
-	*/
+namespace BansheeEngine 
+{
+	/**
+	 * @brief	GPU program compiled from GLSL and usable by OpenGL.
+	 */
     class BS_RSGL_EXPORT GLSLGpuProgram : public GpuProgram
     class BS_RSGL_EXPORT GLSLGpuProgram : public GpuProgram
     {
     {
 	public:
 	public:
 		~GLSLGpuProgram();
 		~GLSLGpuProgram();
 
 
+		/**
+		 * @copydoc	GpuProgram::isSupported
+		 */
 		bool isSupported() const;
 		bool isSupported() const;
 
 
-		const GLuint getGLHandle() const { return mGLHandle; }
-
-		/** Sets the preprocessor defines use to compile the program. */
-		void setPreprocessorDefines(const String& defines) { mPreprocessorDefines = defines; }
-		/** Sets the preprocessor defines use to compile the program. */
-		const String& getPreprocessorDefines() const { return mPreprocessorDefines; }
-
-		/// Overridden from GpuProgram
+		/**
+		 * @copydoc	GpuProgram::getLanguage
+		 */
 		const String& getLanguage() const;
 		const String& getLanguage() const;
 
 
-		/** Returns the operation type that this geometry program expects to
-		receive as input
-		*/
-		virtual DrawOperationType getInputOperationType() const
-		{
-			return mInputOperationType;
-		}
-		/** Returns the operation type that this geometry program will emit
-		*/
-		virtual DrawOperationType getOutputOperationType() const
-		{
-			return mOutputOperationType;
-		}
-		/** Returns the maximum number of vertices that this geometry program can
-		output in a single run
-		*/
-		virtual int getMaxOutputVertices() const { return mMaxOutputVertices; }
-
-		/** Sets the operation type that this geometry program expects to receive
-		*/
-		virtual void setInputOperationType(DrawOperationType operationType)
-		{
-			mInputOperationType = operationType;
-		}
-		/** Set the operation type that this geometry program will emit
-		*/
-		virtual void setOutputOperationType(DrawOperationType operationType)
-		{
-			mOutputOperationType = operationType;
-		}
-		/** Set the maximum number of vertices that a single run of this geometry program
-		can emit.
-		*/
-		virtual void setMaxOutputVertices(int maxOutputVertices)
-		{
-			mMaxOutputVertices = maxOutputVertices;
-		}
-
+		/**
+		 * @brief	Gets vertex declaration that determines which input attributes does the GPU
+		 *			program expect (and which attributes will it retrieve from the bound vertex buffer). 
+		 *			Only valid for vertex programs.
+		 */
 		const VertexDeclaration& getInputAttributes() const { return *mVertexDeclaration; }
 		const VertexDeclaration& getInputAttributes() const { return *mVertexDeclaration; }
 
 
-		/// Get the assigned GL program id
+		/**
+		 * @brief	Gets internal OpenGL handle to the program.
+		 */
+		const GLuint getGLHandle() const { return mGLHandle; }
+
+		/**
+		 * @brief	Gets an unique index for this GPU program. Each created GPU program is
+		 *			assigned a unique index on creation.
+		 */
 		const UINT32 getProgramID() const { return mProgramID; }
 		const UINT32 getProgramID() const { return mProgramID; }
 
 
 	private:
 	private:
@@ -81,35 +48,25 @@ namespace BansheeEngine {
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired);
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired);
 
 
 		/**
 		/**
-		* @copydoc GpuProgram::initialize_internal()
-		*/
+		 * @copydoc GpuProgram::initialize_internal()
+		 */
 		void initialize_internal();
 		void initialize_internal();
 
 
 		/**
 		/**
-		* @copydoc GpuProgram::destroy_internal()
-		*/
+		 * @copydoc GpuProgram::destroy_internal()
+		 */
 		void destroy_internal();
 		void destroy_internal();
 
 
 	private:
 	private:
 		UINT32 mProgramID;
 		UINT32 mProgramID;
 		GLuint mGLHandle;
 		GLuint mGLHandle;
 
 
-		DrawOperationType mInputOperationType;
-		DrawOperationType mOutputOperationType;
-		int mMaxOutputVertices;
-
-		String mPreprocessorDefines;
 		VertexDeclarationPtr mVertexDeclaration;
 		VertexDeclarationPtr mVertexDeclaration;
 		
 		
-		/// keep track of the number of vertex shaders created
 		static UINT32 mVertexShaderCount;
 		static UINT32 mVertexShaderCount;
-		/// keep track of the number of fragment shaders created
 		static UINT32 mFragmentShaderCount;
 		static UINT32 mFragmentShaderCount;
-		/// keep track of the number of geometry shaders created
 		static UINT32 mGeometryShaderCount;
 		static UINT32 mGeometryShaderCount;
-		/// keep track of the number of hull shaders created
 		static UINT32 mHullShaderCount;
 		static UINT32 mHullShaderCount;
-		/// keep track of the number of domain shaders created
 		static UINT32 mDomainShaderCount;
 		static UINT32 mDomainShaderCount;
 
 
 		/************************************************************************/
 		/************************************************************************/

+ 66 - 538
BansheeGLRenderSystem/Source/GLSL/include/BsGLSLParamParser.h

@@ -8,13 +8,31 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	/**
+	 * @brief	Holds a GLSL program input attribute used in vertex programs.
+	 */
 	struct GLSLAttribute
 	struct GLSLAttribute
 	{
 	{
+		/**
+		 * @brief	Constructs a new attribute from a name and a semantic that represents
+		 *			in which way is the attribute used.
+		 */
 		GLSLAttribute(const String& name, VertexElementSemantic semantic)
 		GLSLAttribute(const String& name, VertexElementSemantic semantic)
-			:mName(name), mSemantic(semantic)
+		:mName(name), mSemantic(semantic)
 		{ }
 		{ }
 
 
+		/**
+		 * @brief	Return true if attribute name matches the specified name
+		 *			and returns optional semantic index if it exists. Start of the
+		 *			two compared strings must match, and the remaining non-matching
+		 *			bit will be assumed to be the semantic index. Returns -1 if no
+		 *			match is made.
+		 */
 		INT32 matchesName(const String& name);
 		INT32 matchesName(const String& name);
+
+		/**
+		 * @brief	Returns the semantic of this attribute.
+		 */
 		VertexElementSemantic getSemantic() const { return mSemantic; }
 		VertexElementSemantic getSemantic() const { return mSemantic; }
 
 
 	private:
 	private:
@@ -22,556 +40,66 @@ namespace BansheeEngine
 		VertexElementSemantic mSemantic;
 		VertexElementSemantic mSemantic;
 	};
 	};
 
 
-	INT32 GLSLAttribute::matchesName(const String& name)
-	{
-		if(name.length() >= mName.length())
-		{
-			if(name.substr(0, mName.length()) == mName)
-			{
-				String indexStr = name.substr(mName.length(), name.length());
-				return parseUnsignedInt(indexStr, 0);
-			}
-		}
-
-		return -1;
-	}
-
-	struct GLSLParamArrayData
-	{
-		Vector<UINT32> arrayIndices;
-	};
-
+	/**
+	 * @brief	Helper class that is able to parse a GLSL GPU program and retrieve
+	 *			used uniforms and input attributes.
+	 */
 	class GLSLParamParser
 	class GLSLParamParser
 	{
 	{
 	public:
 	public:
+		/**
+		 * @brief	Parses a compiled OpenGL program and outputs a parameter description
+		 *			that contains information about used uniforms.
+		 *
+		 * @param	glProgram		OpenGL handle to the GPU program.
+		 * @param	returnParamDesc	Output structure containing the parsed data.
+		 */
 		void buildUniformDescriptions(GLuint glProgram, GpuParamDesc& returnParamDesc);
 		void buildUniformDescriptions(GLuint glProgram, GpuParamDesc& returnParamDesc);
+
+		/**
+		 * @brief	Parses a compiled OpenGL program and outputs vertex element list that
+		 *			describes input attributes to the program. Only valid for vertex programs.
+		 *
+		 * @param	glProgram	OpenGL handle to the GPU program.
+		 */
 		VertexDeclaration::VertexElementList buildVertexDeclaration(GLuint glProgram);
 		VertexDeclaration::VertexElementList buildVertexDeclaration(GLuint glProgram);
 
 
 	private:
 	private:
+		/**
+		 * @brief	Populates information for uniform with the specified index into the
+		 *			provided structure.
+		 *
+		 * @param	desc			Output structure containing the parsed data.
+		 * @param	paramName		Name of the uniform.
+		 * @param	programHandle	Internal OpenGL handle to the GPU program.
+		 * @param	uniformIndex	Unique uniform index to retrieve data from. Obtained from OpenGL parsing methods.
+		 */
 		void determineParamInfo(GpuParamDataDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex);
 		void determineParamInfo(GpuParamDataDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex);
 
 
 		/**
 		/**
-		* @brief	GLSL has no concept of semantics, so we require all shaders to use specific names for attributes
-		* 			so that we know what they are used for.
+		* Attempts to find out a vertex element semantic based on input parameter name.
+		* GLSL has no concept of semantics, so we require all shaders to use specific names for attributes
+		* so that we know what they are used for.
+		*
+		* Valid names and semantics:
+		*  bs_position - VES_POSITION
+		*  bs_normal - VES_NORMAL
+		*  bs_tangent - VES_TANGENT
+		*  bs_bitangent - VES_BITANGENT
+		*  bs_texcoord - VES_TEXCOORD
+		*  bs_color - VES_COLOR
+		*  bs_blendweights - VES_BLEND_WEIGHTS
+		*  bs_blendindices - VES_BLEND_INDICES
+		*
+		* You may append a number to the end of the name to specify semantic index.
 		*
 		*
-		* @return	true if it succeeds, false if it fails.
+		* @return	True if it succeeds, false if it fails.
 		*/
 		*/
 		bool attribNameToElementSemantic(const String& name, VertexElementSemantic& semantic, UINT16& index);
 		bool attribNameToElementSemantic(const String& name, VertexElementSemantic& semantic, UINT16& index);
+
+		/**
+		 * @brief	Converts an OpenGL type to vertex element type.
+		 */
 		VertexElementType glTypeToAttributeType(GLenum glType);
 		VertexElementType glTypeToAttributeType(GLenum glType);
 	};
 	};
-
-	VertexDeclaration::VertexElementList GLSLParamParser::buildVertexDeclaration(GLuint glProgram)
-	{
-		GLint numAttributes = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTES, &numAttributes);
-
-		GLint maxNameSize = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameSize);
-
-		GLchar* attributeName = (GLchar*)bs_alloc<ScratchAlloc>(sizeof(GLchar) * maxNameSize);
-
-		VertexDeclaration::VertexElementList elementList;
-		for(GLint i = 0; i < numAttributes; i++)
-		{
-			GLint attribSize = 0;
-			GLenum attribType = 0;
-			glGetActiveAttrib(glProgram, i, maxNameSize, nullptr, &attribSize, &attribType, attributeName);
-
-			VertexElementSemantic semantic = VES_POSITION;
-			UINT16 index = 0;
-			if(attribNameToElementSemantic(attributeName, semantic, index))
-			{
-				VertexElementType type = glTypeToAttributeType(attribType);
-
-				elementList.push_back(VertexElement(0, i, type, semantic, index));
-			}
-			else
-			{
-				LOGWRN("Cannot determine vertex input attribute type for attribute: " + String(attributeName));
-			}
-		}
-
-		bs_free<ScratchAlloc>(attributeName);
-
-		return elementList;
-	}
-
-	VertexElementType GLSLParamParser::glTypeToAttributeType(GLenum glType)
-	{
-		switch(glType)
-		{
-		case GL_FLOAT:
-			return VET_FLOAT1;
-		case GL_FLOAT_VEC2:
-			return VET_FLOAT2;
-		case GL_FLOAT_VEC3:
-			return VET_FLOAT3;
-		case GL_FLOAT_VEC4:
-			return VET_FLOAT4;
-		default:
-			BS_EXCEPT(NotImplementedException, "OpenGL render system currently only supports float parameters.");
-		}
-	}
-
-	bool GLSLParamParser::attribNameToElementSemantic(const String& name, VertexElementSemantic& semantic, UINT16& index)
-	{
-		static GLSLAttribute attributes[] = 
-		{
-			GLSLAttribute("bs_position", VES_POSITION),
-			GLSLAttribute("bs_normal", VES_NORMAL),
-			GLSLAttribute("bs_tangent", VES_TANGENT),
-			GLSLAttribute("bs_bitangent", VES_BITANGENT),
-			GLSLAttribute("bs_texcoord", VES_TEXCOORD),
-			GLSLAttribute("bs_color", VES_COLOR),
-			GLSLAttribute("bs_blendweights", VES_BLEND_WEIGHTS),
-			GLSLAttribute("bs_blendindices", VES_BLEND_INDICES)
-		};
-
-		static const UINT32 numAttribs = sizeof(attributes) / sizeof(attributes[0]);
-
-		for(UINT32 i = 0; i < numAttribs; i++)
-		{
-			INT32 attribIndex = attributes[i].matchesName(name);
-			if(attribIndex != -1)
-			{
-				index = attribIndex;
-				semantic = attributes[i].getSemantic();
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	void GLSLParamParser::buildUniformDescriptions(GLuint glProgram, GpuParamDesc& returnParamDesc)
-	{
-		// scan through the active uniforms and add them to the reference list
-		GLint maxBufferSize = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxBufferSize);
-
-		GLint maxBlockNameBufferSize = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxBlockNameBufferSize);
-
-		if(maxBlockNameBufferSize > maxBufferSize)
-			maxBufferSize = maxBlockNameBufferSize;
-
-		GLchar* uniformName = (GLchar*)bs_alloc<ScratchAlloc>(sizeof(GLchar) * maxBufferSize);
-
-		GpuParamBlockDesc newGlobalBlockDesc;
-		newGlobalBlockDesc.slot = 0;
-		newGlobalBlockDesc.name = "BS_INTERNAL_Globals";
-		newGlobalBlockDesc.blockSize = 0;
-		newGlobalBlockDesc.isShareable = false;
-
-		UINT32 textureSlot = 0;
-
-		returnParamDesc.paramBlocks[newGlobalBlockDesc.name] = newGlobalBlockDesc;
-		GpuParamBlockDesc& globalBlockDesc = returnParamDesc.paramBlocks[newGlobalBlockDesc.name];
-
-		GLint uniformBlockCount = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &uniformBlockCount);
-
-		Map<UINT32, String> blockSlotToName;
-		Set<String> blockNames;
-		for (GLuint index = 0; index < (GLuint)uniformBlockCount; index++)
-		{
-			GLsizei unusedSize = 0;
-			glGetActiveUniformBlockName(glProgram, index, maxBufferSize, &unusedSize, uniformName);
-
-			GpuParamBlockDesc newBlockDesc;
-			newBlockDesc.slot = index + 1;
-			newBlockDesc.name = uniformName;
-			newBlockDesc.blockSize = 0;
-			newBlockDesc.isShareable = true;
-
-			returnParamDesc.paramBlocks[newBlockDesc.name] = newBlockDesc;
-			blockSlotToName.insert(std::make_pair(newBlockDesc.slot, newBlockDesc.name));
-			blockNames.insert(newBlockDesc.name);
-		}
-
-		Map<String, UINT32> foundFirstArrayIndex; 
-		Map<String, GpuParamDataDesc> foundStructs;
-
-		// get the number of active uniforms
-		GLint uniformCount = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &uniformCount);
-
-		// Loop over each of the active uniforms, and add them to the reference container
-		// only do this for user defined uniforms, ignore built in gl state uniforms
-		for (GLuint index = 0; index < (GLuint)uniformCount; index++)
-		{
-			GLsizei arraySize = 0;
-			glGetActiveUniformName(glProgram, index, maxBufferSize, &arraySize, uniformName);
-
-			String paramName = String(uniformName);
-
-			// Naming rules and packing rules used here are described in
-			// OpenGL Core Specification 2.11.4
-
-			// Check if parameter is a part of a struct
-			Vector<String> nameElements = StringUtil::tokenise(paramName, ".");
-
-			bool inStruct = false;
-			String structName;
-			if(nameElements.size() > 1)
-			{
-				auto uniformBlockFind = blockNames.find(nameElements[0]);
-
-				// Check if the name is not a struct, and instead a Uniform block namespace
-				if(uniformBlockFind != blockNames.end())
-				{
-					// Possibly it's a struct inside a named uniform block
-					if(nameElements.size() > 2)
-					{
-						inStruct = true;
-						structName = nameElements[1];
-					}
-				}
-				else
-				{
-					inStruct = true;
-					structName = nameElements[0];
-				}
-			}
-			
-			String cleanParamName = paramName; // Param name without array indexes
-
-			// Check if the parameter is in an array
-			UINT32 arrayIdx = 0;
-			bool isInArray = false;
-			if(inStruct)
-			{
-				// If the uniform name has a "[" in it then its an array element uniform.
-				String::size_type arrayStart = structName.find("[");
-				String::size_type arrayEnd = structName.find("]");
-				if (arrayStart != String::npos)
-				{
-					String strArrIdx = structName.substr(arrayStart + 1, arrayEnd - (arrayStart + 1));
-					arrayIdx = parseUnsignedInt(strArrIdx, 0);
-					isInArray = true;
-
-					structName = structName.substr(0, arrayStart);
-				}
-			}
-			else
-			{
-				// If the uniform name has a "[" in it then its an array element uniform.
-				String::size_type arrayStart = cleanParamName.find("[");
-				String::size_type arrayEnd = cleanParamName.find("]");
-				if (arrayStart != String::npos)
-				{
-					String strArrIdx = cleanParamName.substr(arrayStart + 1, arrayEnd - (arrayStart + 1));
-					arrayIdx = parseUnsignedInt(strArrIdx, 0);
-					isInArray = true;
-
-					cleanParamName = cleanParamName.substr(0, arrayStart);
-				}
-			}
-
-			if(inStruct)	
-			{
-				// OpenGL makes struct management really difficult, which is why I have given up on implementing this so far
-				// Some of the issues I encountered:
-				//  - Elements will be optimized out if they are not used. This makes it hard to determine proper structure size.
-				//     - If struct is within a Uniform buffer block, then it is possible because the element won't be optimized out of the buffer
-				//     - If the struct is within a global buffer, it is impossible to determine actual size, since the element will be optimized out of the buffer too
-				//     - Same issue happens with arrays, as OpenGL will optimize out array elements. With global buffers this makes it impossible to determine
-				//       actual array size (e.g. suppose OpenGL optimized out few last elements)
-				//        - Normal arrays work fine as OpenGL has utilities for reporting their actual size, but those do not work with structs
-
-				BS_EXCEPT(NotImplementedException, "Structs are not supported.")
-			}
-
-			// GLSL will optimize out unused array indexes, so there's no guarantee that 0 is the first,
-			// so we store the first one here
-			int firstArrayIndex = 0;
-			if(isInArray)
-			{
-				String& nameToSearch = cleanParamName;
-				if(inStruct)
-					nameToSearch = structName;
-
-				auto arrayIndexFind = foundFirstArrayIndex.find(nameToSearch);
-				if(arrayIndexFind == foundFirstArrayIndex.end())
-				{
-					foundFirstArrayIndex[nameToSearch] = arrayIdx;
-				}
-
-				firstArrayIndex = foundFirstArrayIndex[nameToSearch];
-			}
-
-
-			GLint uniformType;
-			glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_TYPE, &uniformType);
-
-			bool isSampler = false;
-			switch(uniformType)
-			{
-			case GL_SAMPLER_1D:
-			case GL_SAMPLER_2D:
-			case GL_SAMPLER_3D:
-			case GL_SAMPLER_CUBE:
-				isSampler = true;
-			}
-
-			if(isSampler)
-			{
-				GpuParamObjectDesc samplerParam;
-				samplerParam.name = paramName;
-				samplerParam.slot = glGetUniformLocation(glProgram, uniformName);
-
-				GpuParamObjectDesc textureParam;
-				textureParam.name = paramName;
-				textureParam.slot = samplerParam.slot;
-
-				switch(uniformType)
-				{
-				case GL_SAMPLER_1D:
-					samplerParam.type = GPOT_SAMPLER1D;
-					textureParam.type = GPOT_TEXTURE1D;
-					break;
-				case GL_SAMPLER_2D:
-					samplerParam.type = GPOT_SAMPLER2D;
-					textureParam.type = GPOT_TEXTURE2D;
-					break;
-				case GL_SAMPLER_3D:
-					samplerParam.type = GPOT_SAMPLER3D;
-					textureParam.type = GPOT_TEXTURE3D;
-					break;
-				case GL_SAMPLER_CUBE:
-					samplerParam.type = GPOT_SAMPLERCUBE;
-					textureParam.type = GPOT_TEXTURECUBE;
-					break;
-				}
-
-				returnParamDesc.samplers.insert(std::make_pair(paramName, samplerParam));
-				returnParamDesc.textures.insert(std::make_pair(paramName, textureParam));
-			}
-			else
-			{
-				// If array index is larger than 0 and uniform is not a part of a struct,
-				// it means we already processed it (struct arrays are processed differently)
-				if(!inStruct && arrayIdx != 0)
-					continue;
-
-				GLint blockIndex;
-				glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
-
-				GpuParamDataDesc gpuParam;
-
-				if(isInArray)
-					gpuParam.name = cleanParamName;
-				else
-					gpuParam.name = paramName;
-
-				determineParamInfo(gpuParam, paramName, glProgram, index);
-
-				if(blockIndex != -1)
-				{
-					GLint blockOffset;
-					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_OFFSET, &blockOffset);
-					blockOffset = blockOffset / 4;
-
-					gpuParam.gpuMemOffset = blockOffset;
-
-					gpuParam.paramBlockSlot = blockIndex + 1; // 0 is reserved for globals
-
-					String& blockName = blockSlotToName[gpuParam.paramBlockSlot];
-					GpuParamBlockDesc& curBlockDesc = returnParamDesc.paramBlocks[blockName];
-
-					gpuParam.cpuMemOffset = blockOffset;
-					curBlockDesc.blockSize = std::max(curBlockDesc.blockSize, gpuParam.cpuMemOffset + gpuParam.arrayElementStride * gpuParam.arraySize);
-				}
-				else
-				{
-					gpuParam.gpuMemOffset = glGetUniformLocation(glProgram, uniformName);
-					gpuParam.paramBlockSlot = 0;
-					gpuParam.cpuMemOffset = globalBlockDesc.blockSize;
-
-					globalBlockDesc.blockSize = std::max(globalBlockDesc.blockSize, gpuParam.cpuMemOffset + gpuParam.arrayElementStride * gpuParam.arraySize);
-				}
-
-				// If parameter is not a part of a struct we're done
-				if(!inStruct)
-				{
-					returnParamDesc.params.insert(std::make_pair(gpuParam.name, gpuParam));
-					continue;
-				}
-
-				// If the parameter is part of a struct, then we need to update the struct definition
-				auto findExistingStruct = foundStructs.find(structName);
-
-				// Create new definition if one doesn't exist
-				if(findExistingStruct == foundStructs.end())
-				{
-					foundStructs[structName] = GpuParamDataDesc();
-					GpuParamDataDesc& structDesc = foundStructs[structName];
-					structDesc.type = GPDT_STRUCT;
-					structDesc.name = structName;
-					structDesc.arraySize = 1;
-					structDesc.elementSize = 0;
-					structDesc.arrayElementStride = 0;
-					structDesc.gpuMemOffset = gpuParam.gpuMemOffset;
-					structDesc.cpuMemOffset = gpuParam.cpuMemOffset;
-					structDesc.paramBlockSlot = gpuParam.paramBlockSlot;
-				}
-
-				// Update struct with size of the new parameter
-				GpuParamDataDesc& structDesc = foundStructs[structName];
-				
-				assert(gpuParam.cpuMemOffset >= structDesc.cpuMemOffset);
-				if(arrayIdx == firstArrayIndex) // Determine element size only using the first array element
-				{
-					structDesc.elementSize = std::max(structDesc.elementSize, (gpuParam.cpuMemOffset - structDesc.cpuMemOffset) + gpuParam.arrayElementStride * gpuParam.arraySize);
-					structDesc.arrayElementStride = structDesc.elementSize;
-				}
-
-				// New array element reached, determine arrayElementStride
-				if(arrayIdx != firstArrayIndex)
-				{
-					UINT32 numElements = arrayIdx - firstArrayIndex;
-					structDesc.arrayElementStride = (gpuParam.cpuMemOffset - structDesc.cpuMemOffset) / numElements; 
-				}
-
-				structDesc.arraySize = std::max(structDesc.arraySize, arrayIdx + 1);
-			}
-		}
-
-		for(auto iter = foundStructs.begin(); iter != foundStructs.end(); ++iter)
-			returnParamDesc.params.insert(std::make_pair(iter->first, iter->second));
-
-		// Param blocks alway needs to be a multiple of 4, so make it so
-		for(auto iter = returnParamDesc.paramBlocks.begin(); iter != returnParamDesc.paramBlocks.end(); ++iter)
-		{
-			GpuParamBlockDesc& blockDesc = iter->second;
-
-			if(blockDesc.blockSize % 4 != 0)
-				blockDesc.blockSize += (4 - (blockDesc.blockSize % 4));
-		}
-
-#if BS_DEBUG_MODE
-		// Check if manually calculated and OpenGL buffer sizes match
-		for(auto iter = returnParamDesc.paramBlocks.begin(); iter != returnParamDesc.paramBlocks.end(); ++iter)
-		{
-			if(iter->second.slot == 0)
-				continue;
-
-			GLint blockSize = 0;
-			glGetActiveUniformBlockiv(glProgram, iter->second.slot - 1, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
-
-			assert (blockSize % 4 == 0);
-			blockSize = blockSize / 4;
-
-			if(iter->second.blockSize != blockSize)
-				BS_EXCEPT(InternalErrorException, "OpenGL specified and manual uniform block buffer sizes don't match!");
-		}
-#endif
-
-		bs_free<ScratchAlloc>(uniformName);
-	}
-
-	void GLSLParamParser::determineParamInfo(GpuParamDataDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex)
-	{
-		GLint arraySize;
-		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
-		desc.arraySize = arraySize;
-
-		GLint uniformType;
-		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_TYPE, &uniformType);
-
-		switch (uniformType)
-		{
-		case GL_BOOL:
-			desc.type = GPDT_BOOL;
-			desc.elementSize = 1;
-			break;
-		case GL_FLOAT:
-			desc.type = GPDT_FLOAT1;
-			desc.elementSize = 1;
-			break;
-		case GL_FLOAT_VEC2:
-			desc.type = GPDT_FLOAT2;
-			desc.elementSize = 2;
-			break;
-		case GL_FLOAT_VEC3:
-			desc.type = GPDT_FLOAT3;
-			desc.elementSize = 3;
-			break;
-		case GL_FLOAT_VEC4:
-			desc.type = GPDT_FLOAT4;
-			desc.elementSize = 4;
-			break;
-		case GL_INT:
-			desc.type = GPDT_INT1;
-			desc.elementSize = 1;
-			break;
-		case GL_INT_VEC2:
-			desc.type = GPDT_INT2;
-			desc.elementSize = 2;
-			break;
-		case GL_INT_VEC3:
-			desc.type = GPDT_INT3;
-			desc.elementSize = 3;
-			break;
-		case GL_INT_VEC4:
-			desc.type = GPDT_INT4;
-			desc.elementSize = 4;
-			break;
-		case GL_FLOAT_MAT2:
-			desc.type = GPDT_MATRIX_2X2;
-			desc.elementSize = 4;
-			break;
-		case GL_FLOAT_MAT3:
-			desc.type = GPDT_MATRIX_3X3;
-			desc.elementSize = 9;
-			break;
-		case GL_FLOAT_MAT4:
-			desc.type = GPDT_MATRIX_4X4;
-			desc.elementSize = 16;
-			break;
-		case GL_FLOAT_MAT2x3:
-			desc.type = GPDT_MATRIX_2X3;
-			desc.elementSize = 6;
-			break;
-		case GL_FLOAT_MAT3x2:
-			desc.type = GPDT_MATRIX_3X2;
-			desc.elementSize = 6;
-			break;
-		case GL_FLOAT_MAT2x4:
-			desc.type = GPDT_MATRIX_2X4;
-			desc.elementSize = 8;
-			break;
-		case GL_FLOAT_MAT4x2:
-			desc.type = GPDT_MATRIX_4X2;
-			desc.elementSize = 8;
-			break;
-		case GL_FLOAT_MAT3x4:
-			desc.type = GPDT_MATRIX_3X4;
-			desc.elementSize = 12;
-			break;
-		case GL_FLOAT_MAT4x3:
-			desc.type = GPDT_MATRIX_4X3;
-			desc.elementSize = 12;
-			break;
-		default:
-			BS_EXCEPT(InternalErrorException, "Invalid shader parameter type: " + toString(uniformType) + " for parameter " + paramName);
-		}
-
-		if(arraySize > 1)
-		{
-			GLint arrayStride;
-			glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE, &arrayStride);
-
-			if(arrayStride > 0)
-			{
-				assert (arrayStride % 4 == 0);
-
-				desc.arrayElementStride = arrayStride / 4;
-			}
-			else
-				desc.arrayElementStride = desc.elementSize;
-		}
-		else
-			desc.arrayElementStride = desc.elementSize;
-	}
 }
 }

+ 0 - 525
BansheeGLRenderSystem/Source/GLSL/include/BsGLSLPreprocessor.h

@@ -1,525 +0,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-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-
-#ifndef __OGRE_CPREPROCESSOR_H__
-#define __OGRE_CPREPROCESSOR_H__
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "BsGLPrerequisites.h"
-
-namespace BansheeEngine {
-
-/**
- * This is a simplistic C/C++-like preprocessor.
- * It takes an non-zero-terminated string on input and outputs a
- * non-zero-terminated string buffer.
- *
- * This preprocessor was designed specifically for GLSL shaders, so
- * if you want to use it for other purposes you might want to check
- * if the feature set it provides is enough for you.
- *
- * Here's a list of supported features:
- * <ul>
- * <li>Fast memory allocation-less operation (mostly).
- * <li>Line continuation (backslash-newline) is swallowed.
- * <li>Line numeration is fully preserved by inserting empty lines where
- *     required. This is crucial if, say, GLSL compiler reports you an error
- *     with a line number.
- * <li>#define: Parametrized and non-parametrized macros. Invoking a macro with
- *     less arguments than it takes assignes empty values to missing arguments.
- * <li>#undef: Forget defined macros
- * <li>#ifdef/#ifndef/#else/#endif: Conditional suppression of parts of code.
- * <li>#if: Supports numeric expression of any complexity, also supports the
- *     defined() pseudo-function.
- * <ul>
- */
-class CPreprocessor
-{
-    /**
-     * A input token.
-     *
-     * For performance reasons most tokens will point to portions of the
-     * input stream, so no unneeded memory allocation is done. However,
-     * in some cases we must allocate different memory for token storage,
-     * in this case this is signalled by setting the Allocated member
-     * to non-zero in which case the destructor will know that it must
-     * free memory on object destruction.
-     *
-     * Again for performance reasons we use malloc/realloc/free here because
-     * C++-style new[] lacks the realloc() counterpart.
-     */
-    class Token
-    {
-    public:
-        enum Kind
-        {
-            TK_EOS,          // End of input stream
-            TK_ERROR,        // An error has been encountered
-            TK_WHITESPACE,   // A whitespace span (but not newline)
-            TK_NEWLINE,      // A single newline (CR & LF)
-            TK_LINECONT,     // Line continuation ('\' followed by LF)
-            TK_NUMBER,       // A number
-            TK_KEYWORD,      // A keyword
-            TK_PUNCTUATION,  // A punctuation character
-            TK_DIRECTIVE,    // A preprocessor directive
-            TK_STRING,       // A string
-            TK_COMMENT,      // A block comment
-            TK_LINECOMMENT,  // A line comment
-            TK_TEXT,         // An unparsed text (cannot be returned from GetToken())
-        };
-
-        /// Token type
-        Kind Type;
-        /// True if string was allocated (and must be freed)
-        mutable size_t Allocated;
-        union
-        {
-            /// A pointer somewhere into the input buffer
-            const char *String;
-            /// A memory-allocated string
-            char *Buffer;
-        };
-        /// Token length in bytes
-        size_t Length;
-
-        Token () : Allocated (0), String (NULL)
-        { }
-
-        Token (Kind iType) : Type (iType), Allocated (0), String (NULL)
-        { }
-
-        Token (Kind iType, const char *iString, size_t iLength) :
-            Type (iType), Allocated (0), String (iString), Length (iLength)
-        { }
-
-        Token (const Token &iOther)
-        {
-            Type = iOther.Type;
-            Allocated = iOther.Allocated;
-            iOther.Allocated = 0; // !!! not quite correct but effective
-            String = iOther.String;
-            Length = iOther.Length;
-        }
-
-        ~Token ()
-        { if (Allocated) free (Buffer); }
-
-        /// Assignment operator
-        Token &operator = (const Token &iOther)
-        {
-            if (Allocated) free (Buffer);
-            Type = iOther.Type;
-            Allocated = iOther.Allocated;
-            iOther.Allocated = 0; // !!! not quite correct but effective
-            String = iOther.String;
-            Length = iOther.Length;
-            return *this;
-        }
-
-        /// Append a string to this token
-        void Append (const char *iString, size_t iLength);
-
-        /// Append a token to this token
-        void Append (const Token &iOther);
-
-        /// Append given number of newlines to this token
-        void AppendNL (int iCount);
-
-        /// Count number of newlines in this token
-        int CountNL ();
-
-        /// Get the numeric value of the token
-        bool GetValue (long &oValue) const;
-
-        /// Set the numeric value of the token
-        void SetValue (long iValue);
-
-        /// Test two tokens for equality
-        bool operator == (const Token &iOther)
-        {
-            if (iOther.Length != Length)
-                return false;
-            return (memcmp (String, iOther.String, Length) == 0);
-        }
-    };
-
-    /// A macro definition
-    class Macro
-    {
-    public:
-        /// Macro name
-        Token Name;
-        /// Number of arguments
-        int NumArgs;
-        /// The names of the arguments
-        Token *Args;
-        /// The macro value
-        Token Value;
-        /// Unparsed macro body (keeps the whole raw unparsed macro body)
-        Token Body;
-        /// Next macro in chained list
-        Macro *Next;
-        /// A pointer to function implementation (if macro is really a func)
-        Token (*ExpandFunc) (CPreprocessor *iParent, int iNumArgs, Token *iArgs);
-        /// true if macro expansion is in progress
-        bool Expanding;
-
-        Macro (const Token &iName) :
-            Name (iName), NumArgs (0), Args (NULL), Next (NULL),
-            ExpandFunc (NULL), Expanding (false)
-        { }
-
-        ~Macro ();
-
-        /// Expand the macro value (will not work for functions)
-        Token Expand (int iNumArgs, Token *iArgs, Macro *iMacros);
-    };
-
-    friend class CPreprocessor::Macro;
-
-    /// The current source text input
-    const char *Source;
-    /// The end of the source text
-    const char *SourceEnd;
-    /// Current line number
-    int Line;
-    /// True if we are at beginning of line
-    bool BOL;
-    /// A stack of 32 booleans packed into one value :)
-    unsigned EnableOutput;
-    /// The list of macros defined so far
-    Macro *MacroList;
-
-    /**
-     * Private constructor to re-parse a single token.
-     */
-    CPreprocessor (const Token &iToken, int iLine);
-
-    /**
-     * Stateless tokenizer: Parse the input text and return the next token.
-     * @param iExpand
-     *     If true, macros will be expanded to their values
-     * @return
-     *     The next token from the input stream
-     */
-    Token GetToken (bool iExpand);
-
-    /**
-     * Handle a preprocessor directive.
-     * @param iToken
-     *     The whole preprocessor directive line (until EOL)
-     * @param iLine
-     *     The line where the directive begins (for error reports)
-     * @return
-     *     The last input token that was not proceeded.
-     */
-    Token HandleDirective (Token &iToken, int iLine);
-
-    /**
-     * Handle a #define directive.
-     * @param iBody
-     *     The body of the directive (everything after the directive
-     *     until end of line).
-     * @param iLine
-     *     The line where the directive begins (for error reports)
-     * @return
-     *     true if everything went ok, false if not
-     */
-    bool HandleDefine (Token &iBody, int iLine);
-
-    /**
-     * Undefine a previously defined macro
-     * @param iBody
-     *     The body of the directive (everything after the directive
-     *     until end of line).
-     * @param iLine
-     *     The line where the directive begins (for error reports)
-     * @return
-     *     true if everything went ok, false if not
-     */
-    bool HandleUnDef (Token &iBody, int iLine);
-
-    /**
-     * Handle an #ifdef directive.
-     * @param iBody
-     *     The body of the directive (everything after the directive
-     *     until end of line).
-     * @param iLine
-     *     The line where the directive begins (for error reports)
-     * @return
-     *     true if everything went ok, false if not
-     */
-    bool HandleIfDef (Token &iBody, int iLine);
-
-    /**
-     * Handle an #if directive.
-     * @param iBody
-     *     The body of the directive (everything after the directive
-     *     until end of line).
-     * @param iLine
-     *     The line where the directive begins (for error reports)
-     * @return
-     *     true if everything went ok, false if not
-     */
-    bool HandleIf (Token &iBody, int iLine);
-
-    /**
-     * Handle an #else directive.
-     * @param iBody
-     *     The body of the directive (everything after the directive
-     *     until end of line).
-     * @param iLine
-     *     The line where the directive begins (for error reports)
-     * @return
-     *     true if everything went ok, false if not
-     */
-    bool HandleElse (Token &iBody, int iLine);
-
-    /**
-     * Handle an #endif directive.
-     * @param iBody
-     *     The body of the directive (everything after the directive
-     *     until end of line).
-     * @param iLine
-     *     The line where the directive begins (for error reports)
-     * @return
-     *     true if everything went ok, false if not
-     */
-    bool HandleEndIf (Token &iBody, int iLine);
-
-    /**
-     * Get a single function argument until next ',' or ')'.
-     * @param oArg
-     *     The argument is returned in this variable.
-     * @param iExpand
-     *     If false, parameters are not expanded and no expressions are
-     *     allowed; only a single keyword is expected per argument.
-     * @return
-     *     The first unhandled token after argument.
-     */
-    Token GetArgument (Token &oArg, bool iExpand);
-
-    /**
-     * Get all the arguments of a macro: '(' arg1 { ',' arg2 { ',' ... }} ')'
-     * @param oNumArgs
-     *     Number of parsed arguments is stored into this variable.
-     * @param oArgs
-     *     This is set to a pointer to an array of parsed arguments.
-     * @param iExpand
-     *     If false, parameters are not expanded and no expressions are
-     *     allowed; only a single keyword is expected per argument.
-     */
-    Token GetArguments (int &oNumArgs, Token *&oArgs, bool iExpand);
-
-    /**
-     * Parse an expression, compute it and return the result.
-     * @param oResult
-     *     A token containing the result of expression
-     * @param iLine
-     *     The line at which the expression starts (for error reports)
-     * @param iOpPriority
-     *     Operator priority (at which operator we will stop if
-     *     proceeding recursively -- used internally. Parser stops
-     *     when it encounters an operator with higher or equal priority).
-     * @return
-     *     The last unhandled token after the expression
-     */
-    Token GetExpression (Token &oResult, int iLine, int iOpPriority = 0);
-
-    /**
-     * Get the numeric value of a token.
-     * If the token was produced by expanding a macro, we will get
-     * an TEXT token which can contain a whole expression; in this
-     * case we will call GetExpression to parse it. Otherwise we
-     * just call the token's GetValue() method.
-     * @param iToken
-     *     The token to get the numeric value of
-     * @param oValue
-     *     The variable to put the value into
-     * @param iLine
-     *     The line where the directive begins (for error reports)
-     * @return
-     *     true if ok, false if not
-     */
-    bool GetValue (const Token &iToken, long &oValue, int iLine);
-
-    /**
-     * Expand the given macro, if it exists.
-     * If macro has arguments, they are collected from source stream.
-     * @param iToken
-     *     A KEYWORD token containing the (possible) macro name.
-     * @return
-     *     The expanded token or iToken if it is not a macro
-     */
-    Token ExpandMacro (const Token &iToken);
-
-    /**
-     * Check if a macro is defined, and if so, return it
-     * @param iToken
-     *     Macro name
-     * @return
-     *     The macro object or NULL if a macro with this name does not exist
-     */
-    Macro *IsDefined (const Token &iToken);
-
-    /**
-     * The implementation of the defined() preprocessor function
-     * @param iParent
-     *     The parent preprocessor object
-     * @param iNumArgs
-     *     Number of arguments
-     * @param iArgs
-     *     The arguments themselves
-     * @return
-     *     The return value encapsulated in a token
-     */
-    static Token ExpandDefined (CPreprocessor *iParent, int iNumArgs, Token *iArgs);
-
-    /**
-     * Parse the input string and return a token containing the whole output.
-     * @param iSource
-     *     The source text enclosed in a token
-     * @return
-     *     The output text enclosed in a token
-     */
-    Token Parse (const Token &iSource);
-
-    /**
-     * Call the error handler
-     * @param iLine
-     *     The line at which the error happened.
-     * @param iError
-     *     The error string.
-     * @param iToken
-     *     If not NULL contains the erroneous token
-     */
-    void Error (int iLine, const char *iError, const Token *iToken = NULL);
-
-public:
-    /// Create an empty preprocessor object
-    CPreprocessor () : MacroList (NULL)
-    { }
-
-    /// Destroy the preprocessor object
-    virtual ~CPreprocessor ();
-
-    /**
-     * Define a macro without parameters.
-     * @param iMacroName
-     *     The name of the defined macro
-     * @param iMacroNameLen
-     *     The length of the name of the defined macro
-     * @param iMacroValue
-     *     The value of the defined macro
-     * @param iMacroValueLen
-     *     The length of the value of the defined macro
-     */
-    void Define (const char *iMacroName, size_t iMacroNameLen,
-                 const char *iMacroValue, size_t iMacroValueLen);
-
-    /**
-     * Define a numerical macro.
-     * @param iMacroName
-     *     The name of the defined macro
-     * @param iMacroNameLen
-     *     The length of the name of the defined macro
-     * @param iMacroValue
-     *     The value of the defined macro
-     */
-    void Define (const char *iMacroName, size_t iMacroNameLen, long iMacroValue);
-
-    /**
-     * Undefine a macro.
-     * @param iMacroName
-     *     The name of the macro to undefine
-     * @param iMacroNameLen
-     *     The length of the name of the macro to undefine
-     * @return
-     *     true if the macro has been undefined, false if macro doesn't exist
-     */
-    bool Undef (const char *iMacroName, size_t iMacroNameLen);
-
-    /**
-     * Parse the input string and return a newly-allocated output string.
-     * @note
-     *     The returned preprocessed string is NOT zero-terminated
-     *     (just like the input string).
-     * @param iSource
-     *     The source text
-     * @param iLength
-     *     The length of the source text in characters
-     * @param oLength
-     *     The length of the output string.
-     * @return
-     *     The output from preprocessor, allocated with malloc().
-     *     The parser can actually allocate more than needed for performance
-     *     reasons, but this should not be a problem unless you will want
-     *     to store the returned pointer for long time in which case you
-     *     might want to realloc() it.
-     *     If an error has been encountered, the function returns NULL.
-     *     In some cases the function may return an unallocated address
-     *     that's *inside* the source buffer. You must free() the result
-     *     string only if the returned address is not inside the source text.
-     */
-    char *Parse (const char *iSource, size_t iLength, size_t &oLength);
-
-    /**
-     * An error handler function type.
-     * The default implementation just drops a note to stderr and
-     * then the parser ends, returning NULL.
-     * @param iData
-     *     User-specific pointer from the corresponding CPreprocessor object.
-     * @param iLine
-     *     The line at which the error happened.
-     * @param iError
-     *     The error string.
-     * @param iToken
-     *     If not NULL contains the erroneous token
-     * @param iTokenLen
-     *     The length of iToken. iToken is never zero-terminated!
-     */
-    typedef void (*ErrorHandlerFunc) (
-        void *iData, int iLine, const char *iError,
-        const char *iToken, size_t iTokenLen);
-
-    /**
-     * A pointer to the preprocessor's error handler.
-     * You can assign the address of your own function to this variable
-     * and implement your own error handling (e.g. throwing an exception etc).
-     */
-    static ErrorHandlerFunc ErrorHandler;
-
-    /// User-specific storage, passed to Error()
-    void *ErrorData;
-};
-
-}
-
-#endif 

+ 15 - 3
BansheeGLRenderSystem/Source/GLSL/include/BsGLSLProgramFactory.h

@@ -5,15 +5,27 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-    /** Factory class for GLSL programs. */
+	/**
+	 * @brief	Factory class that deals with creating GLSL GPU programs.
+	 */
     class BS_RSGL_EXPORT GLSLProgramFactory : public GpuProgramFactory
     class BS_RSGL_EXPORT GLSLProgramFactory : public GpuProgramFactory
     {
     {
     public:
     public:
-		/// Get the name of the language this factory creates programs for
+		/**
+		 * @copydoc	GpuProgramFactory::getLanguage
+		 */
 		const String& getLanguage() const;
 		const String& getLanguage() const;
-		/// create an instance of GLSLProgram
+
+		/**
+		 * @copydoc	GpuProgramFactory::getLanguage(const String&, const String&, GpuProgramType,
+		 *			GpuProgramProfile, const Vector<HGpuProgInclude>*, bool)
+		 */
         GpuProgramPtr create(const String& source, const String& entryPoint, GpuProgramType gptype, 
         GpuProgramPtr create(const String& source, const String& entryPoint, GpuProgramType gptype, 
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requireAdjacency);
 			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requireAdjacency);
+
+		/**
+		 * @copydoc	GpuProgramFactory::create(GpuProgramType)
+		 */
 		GpuProgramPtr create(GpuProgramType type);
 		GpuProgramPtr create(GpuProgramType type);
 
 
 	protected:
 	protected:

+ 24 - 0
BansheeGLRenderSystem/Source/GLSL/include/BsGLSLProgramPipelineManager.h

@@ -4,18 +4,36 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	/**
+	 * @brief	Wrapper around OpenGL pipeline object.
+	 */
 	struct GLSLProgramPipeline
 	struct GLSLProgramPipeline
 	{
 	{
 		GLuint glHandle;
 		GLuint glHandle;
 	};
 	};
 
 
+	/**
+	 * @brief	Managed OpenGL pipeline objects that are used for binding a certain combination
+	 *			of GPU programs to the render system.
+	 *
+	 * @note	In OpenGL you cannot bind GPU programs to the pipeline manually. Instead as a preprocessing step
+	 *			you create a pipeline object containing the programs you plan on using, and then later you bind the
+	 *			previously created pipeline object. 
+	 */
 	class GLSLProgramPipelineManager
 	class GLSLProgramPipelineManager
 	{
 	{
 	public:
 	public:
+		/**
+		 * @brief	Creates or returns an existing pipeline that uses the provided combination of GPU programs. Provide
+		 *			null for unused programs.
+		 */
 		const GLSLProgramPipeline* getPipeline(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* fragmentProgram, 
 		const GLSLProgramPipeline* getPipeline(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* fragmentProgram, 
 			GLSLGpuProgram* geometryProgram, GLSLGpuProgram* hullProgram, GLSLGpuProgram* domainProgram);
 			GLSLGpuProgram* geometryProgram, GLSLGpuProgram* hullProgram, GLSLGpuProgram* domainProgram);
 
 
 	private:
 	private:
+		/**
+		 * @brief	Key that uniquely identifies a pipeline object.
+		 */
 		struct ProgramPipelineKey
 		struct ProgramPipelineKey
 		{
 		{
 			UINT32 vertexProgKey;
 			UINT32 vertexProgKey;
@@ -25,12 +43,18 @@ namespace BansheeEngine
 			UINT32 domainProgKey;
 			UINT32 domainProgKey;
 		};
 		};
 
 
+		/**
+		 * @brief	Used for calculating a hash code from pipeline object key.
+		 */
 		class ProgramPipelineKeyHashFunction 
 		class ProgramPipelineKeyHashFunction 
 		{
 		{
 		public:
 		public:
 			::std::size_t operator()(const ProgramPipelineKey &key) const;
 			::std::size_t operator()(const ProgramPipelineKey &key) const;
 		};
 		};
 
 
+		/**
+		 * @brief	Used for comparing two pipeline objects for equality.
+		 */
 		class ProgramPipelineKeyEqual 
 		class ProgramPipelineKeyEqual 
 		{
 		{
 		public:
 		public:

+ 3 - 74
BansheeGLRenderSystem/Source/GLSL/src/BsGLSLGpuProgram.cpp

@@ -3,13 +3,12 @@
 #include "BsGLSLGpuProgram.h"
 #include "BsGLSLGpuProgram.h"
 #include "BsRenderSystem.h"
 #include "BsRenderSystem.h"
 #include "BsException.h"
 #include "BsException.h"
-#include "BsGLSLPreprocessor.h"
 #include "BsGLSLParamParser.h"
 #include "BsGLSLParamParser.h"
 #include "BsHardwareBufferManager.h"
 #include "BsHardwareBufferManager.h"
 #include "BsGLSLGpuProgramRTTI.h"
 #include "BsGLSLGpuProgramRTTI.h"
 
 
-namespace BansheeEngine {
-
+namespace BansheeEngine 
+{
 	UINT32 GLSLGpuProgram::mVertexShaderCount = 0;
 	UINT32 GLSLGpuProgram::mVertexShaderCount = 0;
 	UINT32 GLSLGpuProgram::mFragmentShaderCount = 0;
 	UINT32 GLSLGpuProgram::mFragmentShaderCount = 0;
 	UINT32 GLSLGpuProgram::mGeometryShaderCount = 0;
 	UINT32 GLSLGpuProgram::mGeometryShaderCount = 0;
@@ -68,13 +67,11 @@ namespace BansheeEngine {
 	GLSLGpuProgram::GLSLGpuProgram(const String& source, const String& entryPoint, GpuProgramType gptype, 
 	GLSLGpuProgram::GLSLGpuProgram(const String& source, const String& entryPoint, GpuProgramType gptype, 
 		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
 		GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool isAdjacencyInfoRequired)
 		:GpuProgram(source, entryPoint, gptype, profile, includes, isAdjacencyInfoRequired),
 		:GpuProgram(source, entryPoint, gptype, profile, includes, isAdjacencyInfoRequired),
-		mInputOperationType(DOT_TRIANGLE_LIST), mOutputOperationType(DOT_TRIANGLE_LIST), mMaxOutputVertices(3),
 		mProgramID(0), mGLHandle(0)
 		mProgramID(0), mGLHandle(0)
     { }
     { }
 
 
     GLSLGpuProgram::~GLSLGpuProgram()
     GLSLGpuProgram::~GLSLGpuProgram()
-    {
-    }
+    { }
 
 
 	void GLSLGpuProgram::initialize_internal()
 	void GLSLGpuProgram::initialize_internal()
 	{
 	{
@@ -87,7 +84,6 @@ namespace BansheeEngine {
 			return;
 			return;
 		}
 		}
 
 
-		// only create a shader object if glsl is supported
 		GLenum shaderType = 0x0000;
 		GLenum shaderType = 0x0000;
 		switch (mType)
 		switch (mType)
 		{
 		{
@@ -113,73 +109,6 @@ namespace BansheeEngine {
 			break;
 			break;
 		}
 		}
 
 
-		// Preprocess the GLSL shader in order to get a clean source
-		CPreprocessor cpp;
-
-		// Pass all user-defined macros to preprocessor
-		if (!mPreprocessorDefines.empty())
-		{
-			String::size_type pos = 0;
-			while (pos != String::npos)
-			{
-				// Find delims
-				String::size_type endPos = mPreprocessorDefines.find_first_of(";,=", pos);
-				if (endPos != String::npos)
-				{
-					String::size_type macro_name_start = pos;
-					size_t macro_name_len = endPos - pos;
-					pos = endPos;
-
-					// Check definition part
-					if (mPreprocessorDefines[pos] == '=')
-					{
-						// set up a definition, skip delim
-						++pos;
-						String::size_type macro_val_start = pos;
-						size_t macro_val_len;
-
-						endPos = mPreprocessorDefines.find_first_of(";,", pos);
-						if (endPos == String::npos)
-						{
-							macro_val_len = mPreprocessorDefines.size() - pos;
-							pos = endPos;
-						}
-						else
-						{
-							macro_val_len = endPos - pos;
-							pos = endPos + 1;
-						}
-						cpp.Define(
-							mPreprocessorDefines.c_str() + macro_name_start, macro_name_len,
-							mPreprocessorDefines.c_str() + macro_val_start, macro_val_len);
-					}
-					else
-					{
-						// No definition part, define as "1"
-						++pos;
-						cpp.Define(
-							mPreprocessorDefines.c_str() + macro_name_start, macro_name_len, 1);
-					}
-				}
-				else
-					pos = endPos;
-			}
-		}
-
-		size_t out_size = 0;
-		const char *src = mSource.c_str();
-		size_t src_len = mSource.size();
-		char *out = cpp.Parse(src, src_len, out_size);
-		if (!out || !out_size)
-		{
-			// Failed to preprocess, break out
-			BS_EXCEPT(RenderingAPIException, "Failed to preprocess shader.");
-		}
-
-		mSource = String(out, out_size);
-		if (out < src || out > src + src_len)
-			free(out);
-
 		// Add preprocessor extras and main source
 		// Add preprocessor extras and main source
 		if (!mSource.empty())
 		if (!mSource.empty())
 		{
 		{

+ 0 - 1301
BansheeGLRenderSystem/Source/GLSL/src/BsGLSLPreprocessor.cpp

@@ -1,1301 +0,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-2011 Torus Knot Software Ltd
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-
-#include "BsGLSLPreprocessor.h"
-
-#include <ctype.h>
-#include <stdio.h>
-#include <assert.h>
-
-namespace BansheeEngine {
-
-// Limit max number of macro arguments to this
-#define MAX_MACRO_ARGS 16
-
-#if BS_PLATFORM == BS_PLATFORM_WIN32 && !defined( __MINGW32__ )
-	#define snprintf _snprintf
-#endif
-
-//---------------------------------------------------------------------------//
-
-/// Return closest power of two not smaller than given number
-static size_t ClosestPow2 (size_t x)
-{
-    if (!(x & (x - 1)))
-        return x;
-    while (x & (x + 1))
-        x |= (x + 1);
-    return x + 1;
-}
-
-void CPreprocessor::Token::Append (const char *iString, size_t iLength)
-{
-    Token t (Token::TK_TEXT, iString, iLength);
-    Append (t);
-}
-
-void CPreprocessor::Token::Append (const Token &iOther)
-{
-    if (!iOther.String)
-        return;
-
-    if (!String)
-    {
-        String = iOther.String;
-        Length = iOther.Length;
-        Allocated = iOther.Allocated;
-        iOther.Allocated = 0; // !!! not quite correct but effective
-        return;
-    }
-
-    if (Allocated)
-    {
-        size_t new_alloc = ClosestPow2 (Length + iOther.Length);
-        if (new_alloc < 64)
-            new_alloc = 64;
-        if (new_alloc != Allocated)
-        {
-            Allocated = new_alloc;
-            Buffer = (char *)realloc (Buffer, Allocated);
-        }
-    }
-    else if (String + Length != iOther.String)
-    {
-        Allocated = ClosestPow2 (Length + iOther.Length);
-        if (Allocated < 64)
-            Allocated = 64;
-        char *newstr = (char *)malloc (Allocated);
-        memcpy (newstr, String, Length);
-        Buffer = newstr;
-    }
-
-    if (Allocated)
-        memcpy (Buffer + Length, iOther.String, iOther.Length);
-    Length += iOther.Length;
-}
-
-bool CPreprocessor::Token::GetValue (long &oValue) const
-{
-    long val = 0;
-    size_t i = 0;
-
-    while (isspace (String [i]))
-        i++;
-
-    long base = 10;
-    if (String [i] == '0')
-        if (Length > i + 1 && String [i + 1] == 'x')
-            base = 16, i += 2;
-        else
-            base = 8;
-
-    for (; i < Length; i++)
-    {
-        long c = long (String [i]);
-        if (isspace (c))
-            // Possible end of number
-            break;
-
-        if (c >= 'a' && c <= 'z')
-            c -= ('a' - 'A');
-
-        c -= '0';
-        if (c < 0)
-            return false;
-
-        if (c > 9)
-            c -= ('A' - '9' - 1);
-
-        if (c >= base)
-            return false;
-
-        val = (val * base) + c;
-    }
-
-    // Check that all other characters are just spaces
-    for (; i < Length; i++)
-        if (!isspace (String [i]))
-            return false;
-
-    oValue = val;
-    return true;
-}
-
-void CPreprocessor::Token::SetValue (long iValue)
-{
-    char tmp [21];
-    int len = snprintf (tmp, sizeof (tmp), "%ld", iValue);
-    Length = 0;
-    Append (tmp, len);
-    Type = TK_NUMBER;
-}
-
-void CPreprocessor::Token::AppendNL (int iCount)
-{
-    static const char newlines [8] =
-    { '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n' };
-
-    while (iCount > 8)
-    {
-        Append (newlines, 8);
-        iCount -= 8;
-    }
-    if (iCount > 0)
-        Append (newlines, iCount);
-}
-
-int CPreprocessor::Token::CountNL ()
-{
-    if (Type == TK_EOS || Type == TK_ERROR)
-        return 0;
-
-    const char *s = String;
-    size_t l = Length;
-    int c = 0;
-    while (l > 0)
-    {
-        const char *n = (const char *)memchr (s, '\n', l);
-        if (!n)
-            return c;
-        c++;
-        l -= (n - s + 1);
-        s = n + 1;
-    }
-    return c;
-}
-
-//---------------------------------------------------------------------------//
-
-CPreprocessor::Token CPreprocessor::Macro::Expand (
-    int iNumArgs, CPreprocessor::Token *iArgs, Macro *iMacros)
-{
-    Expanding = true;
-
-    CPreprocessor cpp;
-    cpp.MacroList = iMacros;
-
-    // Define a new macro for every argument
-    int i;
-    for (i = 0; i < iNumArgs; i++)
-        cpp.Define (Args [i].String, Args [i].Length,
-                    iArgs [i].String, iArgs [i].Length);
-    // The rest arguments are empty
-    for (; i < NumArgs; i++)
-        cpp.Define (Args [i].String, Args [i].Length, "", 0);
-
-    // Now run the macro expansion through the supplimentary preprocessor
-    Token xt = cpp.Parse (Value);
-
-    Expanding = false;
-
-    // Remove the extra macros we have defined
-    for (int j = NumArgs - 1; j >= 0; j--)
-        cpp.Undef (Args [j].String, Args [j].Length);
-
-    cpp.MacroList = NULL;
-
-    return xt;
-}
-
-//---------------------------------------------------------------------------//
-
-static void DefaultError (void *iData, int iLine, const char *iError,
-                          const char *iToken, size_t iTokenLen)
-{
-    (void)iData;
-    char line [1000];
-    if (iToken)
-        snprintf (line, sizeof (line), "line %d: %s: `%.*s'\n",
-                  iLine, iError, int (iTokenLen), iToken);
-    else
-        snprintf (line, sizeof (line), "line %d: %s\n", iLine, iError);
-
-	// TODO LOG PORT - Log this somewhere?
-    //LogManager::getSingleton ().logMessage (line);
-}
-
-//---------------------------------------------------------------------------//
-
-CPreprocessor::ErrorHandlerFunc CPreprocessor::ErrorHandler = DefaultError;
-
-CPreprocessor::Macro::~Macro()
-{ 
-	bs_deleteN<ScratchAlloc>(Args, NumArgs);
-
-	if(Next != nullptr)
-		bs_delete<ScratchAlloc>(Next); 
-}
-
-CPreprocessor::CPreprocessor (const Token &iToken, int iLine) : MacroList (NULL)
-{
-    Source = iToken.String;
-    SourceEnd = iToken.String + iToken.Length;
-    EnableOutput = 1;
-    Line = iLine;
-    BOL = true;
-}
-
-CPreprocessor::~CPreprocessor ()
-{
-	if(MacroList != nullptr)
-		bs_delete<ScratchAlloc>(MacroList);
-}
-
-void CPreprocessor::Error (int iLine, const char *iError, const Token *iToken)
-{
-    if (iToken)
-        ErrorHandler (ErrorData, iLine, iError, iToken->String, iToken->Length);
-    else
-        ErrorHandler (ErrorData, iLine, iError, NULL, 0);
-}
-
-CPreprocessor::Token CPreprocessor::GetToken (bool iExpand)
-{
-    if (Source >= SourceEnd)
-        return Token (Token::TK_EOS);
-
-    const char *begin = Source;
-    char c = *Source++;
-
-
-    if (c == '\n' || (c == '\r' && *Source == '\n'))
-    {
-        Line++;
-        BOL = true;
-        if (c == '\r')
-            Source++;
-        return Token (Token::TK_NEWLINE, begin, Source - begin);
-    }
-    else if (isspace (c))
-    {
-        while (Source < SourceEnd &&
-               *Source != '\r' &&
-               *Source != '\n' &&
-               isspace (*Source))
-            Source++;
-
-        return Token (Token::TK_WHITESPACE, begin, Source - begin);
-    }
-    else if (isdigit (c))
-    {
-        BOL = false;
-        if (c == '0' && Source < SourceEnd && Source [0] == 'x') // hex numbers
-        {
-            Source++;
-            while (Source < SourceEnd && isxdigit (*Source))
-                Source++;
-        }
-        else
-            while (Source < SourceEnd && isdigit (*Source))
-                Source++;
-        return Token (Token::TK_NUMBER, begin, Source - begin);
-    }
-    else if (c == '_' || isalnum (c))
-    {
-        BOL = false;
-        while (Source < SourceEnd && (*Source == '_' || isalnum (*Source)))
-            Source++;
-        Token t (Token::TK_KEYWORD, begin, Source - begin);
-        if (iExpand)
-            t = ExpandMacro (t);
-        return t;
-    }
-    else if (c == '"' || c == '\'')
-    {
-        BOL = false;
-        while (Source < SourceEnd && *Source != c)
-        {
-            if (*Source == '\\')
-            {
-                Source++;
-                if (Source >= SourceEnd)
-                    break;
-            }
-            if (*Source == '\n')
-                Line++;
-            Source++;
-        }
-        if (Source < SourceEnd)
-            Source++;
-        return Token (Token::TK_STRING, begin, Source - begin);
-    }
-    else if (c == '/' && *Source == '/')
-    {
-        BOL = false;
-        Source++;
-        while (Source < SourceEnd && *Source != '\r' && *Source != '\n')
-            Source++;
-        return Token (Token::TK_LINECOMMENT, begin, Source - begin);
-    }
-    else if (c == '/' && *Source == '*')
-    {
-        BOL = false;
-        Source++;
-        while (Source < SourceEnd && (Source [0] != '*' || Source [1] != '/'))
-        {
-            if (*Source == '\n')
-                Line++;
-            Source++;
-        }
-        if (Source < SourceEnd && *Source == '*')
-            Source++;
-        if (Source < SourceEnd && *Source == '/')
-            Source++;
-        return Token (Token::TK_COMMENT, begin, Source - begin);
-    }
-    else if (c == '#' && BOL)
-    {
-        // Skip all whitespaces after '#'
-        while (Source < SourceEnd && isspace (*Source))
-            Source++;
-        while (Source < SourceEnd && !isspace (*Source))
-            Source++;
-        return Token (Token::TK_DIRECTIVE, begin, Source - begin);
-    }
-    else if (c == '\\' && Source < SourceEnd && (*Source == '\r' || *Source == '\n'))
-    {
-        // Treat backslash-newline as a whole token
-        if (*Source == '\r')
-            Source++;
-        if (*Source == '\n')
-            Source++;
-        Line++;
-        BOL = true;
-        return Token (Token::TK_LINECONT, begin, Source - begin);
-    }
-    else
-    {
-        BOL = false;
-        // Handle double-char operators here
-        if (c == '>' && (*Source == '>' || *Source == '='))
-            Source++;
-        else if (c == '<' && (*Source == '<' || *Source == '='))
-            Source++;
-        else if (c == '!' && *Source == '=')
-            Source++;
-        else if (c == '=' && *Source == '=')
-            Source++;
-        else if ((c == '|' || c == '&' || c == '^') && *Source == c)
-            Source++;
-        return Token (Token::TK_PUNCTUATION, begin, Source - begin);
-    }
-}
-
-CPreprocessor::Macro *CPreprocessor::IsDefined (const Token &iToken)
-{
-    for (Macro *cur = MacroList; cur; cur = cur->Next)
-        if (cur->Name == iToken)
-            return cur;
-
-    return NULL;
-}
-
-CPreprocessor::Token CPreprocessor::ExpandMacro (const Token &iToken)
-{
-    Macro *cur = IsDefined (iToken);
-    if (cur && !cur->Expanding)
-    {
-        Token *args = NULL;
-        int nargs = 0;
-        int old_line = Line;
-
-        if (cur->NumArgs != 0)
-        {
-            Token t = GetArguments (nargs, args, cur->ExpandFunc ? false : true);
-            if (t.Type == Token::TK_ERROR)
-            {
-                bs_deleteN<ScratchAlloc>(args, nargs);
-                return t;
-            }
-
-            // Put the token back into the source pool; we'll handle it later
-            if (t.String)
-            {
-                // Returned token should never be allocated on heap
-                assert (t.Allocated == 0);
-                Source = t.String;
-                Line -= t.CountNL ();
-            }
-        }
-
-        if (nargs > cur->NumArgs)
-        {
-            char tmp [60];
-            snprintf (tmp, sizeof (tmp), "Macro `%.*s' passed %d arguments, but takes just %d",
-                      int (cur->Name.Length), cur->Name.String,
-                      nargs, cur->NumArgs);
-            Error (old_line, tmp);
-            return Token (Token::TK_ERROR);
-        }
-
-        Token t = cur->ExpandFunc ?
-            cur->ExpandFunc (this, nargs, args) :
-            cur->Expand (nargs, args, MacroList);
-        t.AppendNL (Line - old_line);
-
-		bs_deleteN<ScratchAlloc>(args, nargs);
-
-        return t;
-    }
-
-    return iToken;
-}
-
-/**
- * Operator priority:
- *  0: Whole expression
- *  1: '(' ')'
- *  2: ||
- *  3: &&
- *  4: |
- *  5: ^
- *  6: &
- *  7: '==' '!='
- *  8: '<' '<=' '>' '>='
- *  9: '<<' '>>'
- * 10: '+' '-'
- * 11: '*' '/' '%'
- * 12: unary '+' '-' '!' '~'
- */
-CPreprocessor::Token CPreprocessor::GetExpression (
-    Token &oResult, int iLine, int iOpPriority)
-{
-    char tmp [40];
-
-    do
-    {
-        oResult = GetToken (true);
-    } while (oResult.Type == Token::TK_WHITESPACE ||
-             oResult.Type == Token::TK_NEWLINE ||
-             oResult.Type == Token::TK_COMMENT ||
-             oResult.Type == Token::TK_LINECOMMENT ||
-             oResult.Type == Token::TK_LINECONT);
-
-    Token op (Token::TK_WHITESPACE, "", 0);
-
-    // Handle unary operators here
-    if (oResult.Type == Token::TK_PUNCTUATION && oResult.Length == 1)
-        if (strchr ("+-!~", oResult.String [0]))
-        {
-            char uop = oResult.String [0];
-            op = GetExpression (oResult, iLine, 12);
-            long val;
-            if (!GetValue (oResult, val, iLine))
-            {
-                snprintf (tmp, sizeof (tmp), "Unary '%c' not applicable", uop);
-                Error (iLine, tmp, &oResult);
-                return Token (Token::TK_ERROR);
-            }
-
-            if (uop == '-')
-                oResult.SetValue (-val);
-            else if (uop == '!')
-                oResult.SetValue (!val);
-            else if (uop == '~')
-                oResult.SetValue (~val);
-        }
-        else if (oResult.String [0] == '(')
-        {
-            op = GetExpression (oResult, iLine, 1);
-            if (op.Type == Token::TK_ERROR)
-                return op;
-            if (op.Type == Token::TK_EOS)
-            {
-                Error (iLine, "Unclosed parenthesis in #if expression");
-                return Token (Token::TK_ERROR);
-            }
-
-            assert (op.Type == Token::TK_PUNCTUATION &&
-                    op.Length == 1 &&
-                    op.String [0] == ')');
-            op = GetToken (true);
-        }
-
-    while (op.Type == Token::TK_WHITESPACE ||
-           op.Type == Token::TK_NEWLINE ||
-           op.Type == Token::TK_COMMENT ||
-           op.Type == Token::TK_LINECOMMENT ||
-           op.Type == Token::TK_LINECONT)
-        op = GetToken (true);
-
-    while (true)
-    {
-        if (op.Type != Token::TK_PUNCTUATION)
-            return op;
-
-        int prio = 0;
-        if (op.Length == 1)
-            switch (op.String [0])
-            {
-                case ')': return op;
-                case '|': prio = 4; break;
-                case '^': prio = 5; break;
-                case '&': prio = 6; break;
-                case '<':
-                case '>': prio = 8; break;
-                case '+':
-                case '-': prio = 10; break;
-                case '*':
-                case '/':
-                case '%': prio = 11; break;
-            }
-        else if (op.Length == 2)
-            switch (op.String [0])
-            {
-                case '|': if (op.String [1] == '|') prio = 2; break;
-                case '&': if (op.String [1] == '&') prio = 3; break;
-                case '=': if (op.String [1] == '=') prio = 7; break;
-                case '!': if (op.String [1] == '=') prio = 7; break;
-                case '<':
-                    if (op.String [1] == '=')
-                        prio = 8;
-                    else if (op.String [1] == '<')
-                        prio = 9;
-                    break;
-                case '>':
-                    if (op.String [1] == '=')
-                        prio = 8;
-                    else if (op.String [1] == '>')
-                        prio = 9;
-                    break;
-            }
-
-        if (!prio)
-        {
-            Error (iLine, "Expecting operator, got", &op);
-            return Token (Token::TK_ERROR);
-        }
-
-        if (iOpPriority >= prio)
-            return op;
-
-        Token rop;
-        Token nextop = GetExpression (rop, iLine, prio);
-        long vlop, vrop;
-        if (!GetValue (oResult, vlop, iLine))
-        {
-            snprintf (tmp, sizeof (tmp), "Left operand of '%.*s' is not a number",
-                      int (op.Length), op.String);
-            Error (iLine, tmp, &oResult);
-            return Token (Token::TK_ERROR);
-        }
-        if (!GetValue (rop, vrop, iLine))
-        {
-            snprintf (tmp, sizeof (tmp), "Right operand of '%.*s' is not a number",
-                      int (op.Length), op.String);
-            Error (iLine, tmp, &rop);
-            return Token (Token::TK_ERROR);
-        }
-
-        switch (op.String [0])
-        {
-            case '|':
-                if (prio == 2)
-                    oResult.SetValue (vlop || vrop);
-                else
-                    oResult.SetValue (vlop | vrop);
-                break;
-            case '&':
-                if (prio == 3)
-                    oResult.SetValue (vlop && vrop);
-                else
-                    oResult.SetValue (vlop & vrop);
-                break;
-            case '<':
-                if (op.Length == 1)
-                    oResult.SetValue (vlop < vrop);
-                else if (prio == 8)
-                    oResult.SetValue (vlop <= vrop);
-                else if (prio == 9)
-                    oResult.SetValue (vlop << vrop);
-                break;
-            case '>':
-                if (op.Length == 1)
-                    oResult.SetValue (vlop > vrop);
-                else if (prio == 8)
-                    oResult.SetValue (vlop >= vrop);
-                else if (prio == 9)
-                    oResult.SetValue (vlop >> vrop);
-                break;
-            case '^': oResult.SetValue (vlop ^ vrop); break;
-            case '!': oResult.SetValue (vlop != vrop); break;
-            case '=': oResult.SetValue (vlop == vrop); break;
-            case '+': oResult.SetValue (vlop + vrop); break;
-            case '-': oResult.SetValue (vlop - vrop); break;
-            case '*': oResult.SetValue (vlop * vrop); break;
-            case '/':
-            case '%':
-                if (vrop == 0)
-                {
-                    Error (iLine, "Division by zero");
-                    return Token (Token::TK_ERROR);
-                }
-                if (op.String [0] == '/')
-                    oResult.SetValue (vlop / vrop);
-                else
-                    oResult.SetValue (vlop % vrop);
-                break;
-        }
-
-        op = nextop;
-    }
-}
-
-bool CPreprocessor::GetValue (const Token &iToken, long &oValue, int iLine)
-{
-    Token r;
-    const Token *vt = &iToken;
-
-    if ((vt->Type == Token::TK_KEYWORD ||
-         vt->Type == Token::TK_TEXT ||
-         vt->Type == Token::TK_NUMBER) &&
-        !vt->String)
-    {
-        Error (iLine, "Trying to evaluate an empty expression");
-        return false;
-    }
-
-    if (vt->Type == Token::TK_TEXT)
-    {
-        CPreprocessor cpp (iToken, iLine);
-        cpp.MacroList = MacroList;
-
-        Token t;
-        t = cpp.GetExpression (r, iLine);
-
-        cpp.MacroList = NULL;
-
-        if (t.Type == Token::TK_ERROR)
-            return false;
-
-        if (t.Type != Token::TK_EOS)
-        {
-            Error (iLine, "Garbage after expression", &t);
-            return false;
-        }
-
-        vt = &r;
-    }
-
-    Macro *m;
-    switch (vt->Type)
-    {
-        case Token::TK_EOS:
-        case Token::TK_ERROR:
-            return false;
-
-        case Token::TK_KEYWORD:
-            // Try to expand the macro
-            if ((m = IsDefined (*vt)) && !m->Expanding)
-            {
-                Token x = ExpandMacro (*vt);
-                m->Expanding = true;
-                bool rc = GetValue (x, oValue, iLine);
-                m->Expanding = false;
-                return rc;
-            }
-
-            // Undefined macro, "expand" to 0 (mimic cpp behaviour)
-            oValue = 0;
-            break;
-
-        case Token::TK_TEXT:
-        case Token::TK_NUMBER:
-            if (!vt->GetValue (oValue))
-            {
-                Error (iLine, "Not a numeric expression", vt);
-                return false;
-            }
-            break;
-
-        default:
-            Error (iLine, "Unexpected token", vt);
-            return false;
-    }
-
-    return true;
-}
-
-CPreprocessor::Token CPreprocessor::GetArgument (Token &oArg, bool iExpand)
-{
-    do
-    {
-        oArg = GetToken (iExpand);
-    } while (oArg.Type == Token::TK_WHITESPACE ||
-             oArg.Type == Token::TK_NEWLINE ||
-             oArg.Type == Token::TK_COMMENT ||
-             oArg.Type == Token::TK_LINECOMMENT ||
-             oArg.Type == Token::TK_LINECONT);
-
-    if (!iExpand)
-        if (oArg.Type == Token::TK_EOS)
-            return oArg;
-        else if (oArg.Type == Token::TK_PUNCTUATION &&
-                 (oArg.String [0] == ',' ||
-                  oArg.String [0] == ')'))
-        {
-            Token t = oArg;
-            oArg = Token (Token::TK_TEXT, "", 0);
-            return t;
-        }
-        else if (oArg.Type != Token::TK_KEYWORD)
-        {
-            Error (Line, "Unexpected token", &oArg);
-            return Token (Token::TK_ERROR);
-        }
-
-    size_t len = oArg.Length;
-    while (true)
-    {
-        Token t = GetToken (iExpand);
-        switch (t.Type)
-        {
-            case Token::TK_EOS:
-                Error (Line, "Unfinished list of arguments");
-            case Token::TK_ERROR:
-                return Token (Token::TK_ERROR);
-            case Token::TK_PUNCTUATION:
-                if (t.String [0] == ',' ||
-                    t.String [0] == ')')
-                {
-                    // Trim whitespaces at the end
-                    oArg.Length = len;
-                    return t;
-                }
-                break;
-            case Token::TK_LINECONT:
-            case Token::TK_COMMENT:
-            case Token::TK_LINECOMMENT:
-            case Token::TK_NEWLINE:
-                // ignore these tokens
-                continue;
-            default:
-                break;
-        }
-
-        if (!iExpand && t.Type != Token::TK_WHITESPACE)
-        {
-            Error (Line, "Unexpected token", &oArg);
-            return Token (Token::TK_ERROR);
-        }
-
-        oArg.Append (t);
-
-        if (t.Type != Token::TK_WHITESPACE)
-            len = oArg.Length;
-    }
-}
-
-CPreprocessor::Token CPreprocessor::GetArguments (int &oNumArgs, Token *&oArgs,
-                                                  bool iExpand)
-{
-    Token args [MAX_MACRO_ARGS];
-    int nargs = 0;
-
-    // Suppose we'll leave by the wrong path
-    oNumArgs = 0;
-    oArgs = NULL;
-
-    Token t;
-    do
-    {
-        t = GetToken (iExpand);
-    } while (t.Type == Token::TK_WHITESPACE ||
-             t.Type == Token::TK_COMMENT ||
-             t.Type == Token::TK_LINECOMMENT);
-
-    if (t.Type != Token::TK_PUNCTUATION || t.String [0] != '(')
-    {
-        oNumArgs = 0;
-        oArgs = NULL;
-        return t;
-    }
-
-    while (true)
-    {
-        if (nargs == MAX_MACRO_ARGS)
-        {
-            Error (Line, "Too many arguments to macro");
-            return Token (Token::TK_ERROR);
-        }
-
-        t = GetArgument (args [nargs++], iExpand);
-
-        switch (t.Type)
-        {
-            case Token::TK_EOS:
-                Error (Line, "Unfinished list of arguments");
-            case Token::TK_ERROR:
-                return Token (Token::TK_ERROR);
-
-            case Token::TK_PUNCTUATION:
-                if (t.String [0] == ')')
-                {
-                    t = GetToken (iExpand);
-                    goto Done;
-                } // otherwise we've got a ','
-                break;
-
-            default:
-                Error (Line, "Unexpected token", &t);
-                break;
-        }
-    }
-
-Done:
-    oNumArgs = nargs;
-    oArgs = bs_newN<Token, ScratchAlloc>(nargs);
-    for (int i = 0; i < nargs; i++)
-        oArgs [i] = args [i];
-    return t;
-}
-
-bool CPreprocessor::HandleDefine (Token &iBody, int iLine)
-{
-    // Create an additional preprocessor to process macro body
-    CPreprocessor cpp (iBody, iLine);
-
-    Token t = cpp.GetToken (false);
-    if (t.Type != Token::TK_KEYWORD)
-    {
-        Error (iLine, "Macro name expected after #define");
-        return false;
-    }
-
-    Macro *m = bs_new<Macro, ScratchAlloc>(t);
-    m->Body = iBody;
-    t = cpp.GetArguments (m->NumArgs, m->Args, false);
-    while (t.Type == Token::TK_WHITESPACE)
-        t = cpp.GetToken (false);
-
-    switch (t.Type)
-    {
-        case Token::TK_NEWLINE:
-        case Token::TK_EOS:
-            // Assign "" to token
-            t = Token (Token::TK_TEXT, "", 0);
-            break;
-
-        case Token::TK_ERROR:
-            bs_delete<ScratchAlloc>(m);
-            return false;
-
-        default:
-            t.Type = Token::TK_TEXT;
-            assert (t.String + t.Length == cpp.Source);
-            t.Length = cpp.SourceEnd - t.String;
-            break;
-    }
-
-    m->Value = t;
-    m->Next = MacroList;
-    MacroList = m;
-    return true;
-}
-
-bool CPreprocessor::HandleUnDef (Token &iBody, int iLine)
-{
-    CPreprocessor cpp (iBody, iLine);
-
-    Token t = cpp.GetToken (false);
-
-    if (t.Type != Token::TK_KEYWORD)
-    {
-        Error (iLine, "Expecting a macro name after #undef, got", &t);
-        return false;
-    }
-
-    // Don't barf if macro does not exist - standard C behaviour
-    Undef (t.String, t.Length);
-
-    do
-    {
-        t = cpp.GetToken (false);
-    } while (t.Type == Token::TK_WHITESPACE ||
-             t.Type == Token::TK_COMMENT ||
-             t.Type == Token::TK_LINECOMMENT);
-
-    if (t.Type != Token::TK_EOS)
-        Error (iLine, "Warning: Ignoring garbage after directive", &t);
-
-    return true;
-}
-
-bool CPreprocessor::HandleIfDef (Token &iBody, int iLine)
-{
-    if (EnableOutput & (1 << 31))
-    {
-        Error (iLine, "Too many embedded #if directives");
-        return false;
-    }
-
-    CPreprocessor cpp (iBody, iLine);
-
-    Token t = cpp.GetToken (false);
-
-    if (t.Type != Token::TK_KEYWORD)
-    {
-        Error (iLine, "Expecting a macro name after #ifdef, got", &t);
-        return false;
-    }
-
-    EnableOutput <<= 1;
-    if (IsDefined (t))
-        EnableOutput |= 1;
-
-    do
-    {
-        t = cpp.GetToken (false);
-    } while (t.Type == Token::TK_WHITESPACE ||
-             t.Type == Token::TK_COMMENT ||
-             t.Type == Token::TK_LINECOMMENT);
-
-    if (t.Type != Token::TK_EOS)
-        Error (iLine, "Warning: Ignoring garbage after directive", &t);
-
-    return true;
-}
-
-CPreprocessor::Token CPreprocessor::ExpandDefined (CPreprocessor *iParent, int iNumArgs, Token *iArgs)
-{
-    if (iNumArgs != 1)
-    {
-        iParent->Error (iParent->Line, "The defined() function takes exactly one argument");
-        return Token (Token::TK_ERROR);
-    }
-
-    const char *v = iParent->IsDefined (iArgs [0]) ? "1" : "0";
-    return Token (Token::TK_NUMBER, v, 1);
-}
-
-bool CPreprocessor::HandleIf (Token &iBody, int iLine)
-{
-    Macro defined (Token (Token::TK_KEYWORD, "defined", 7));
-    defined.Next = MacroList;
-    defined.ExpandFunc = ExpandDefined;
-    defined.NumArgs = 1;
-
-    // Temporary add the defined() function to the macro list
-    MacroList = &defined;
-
-    long val;
-    bool rc = GetValue (iBody, val, iLine);
-
-    // Restore the macro list
-    MacroList = defined.Next;
-    defined.Next = NULL;
-
-    if (!rc)
-        return false;
-
-    EnableOutput <<= 1;
-    if (val)
-        EnableOutput |= 1;
-
-    return true;
-}
-
-bool CPreprocessor::HandleElse (Token &iBody, int iLine)
-{
-    if (EnableOutput == 1)
-    {
-        Error (iLine, "#else without #if");
-        return false;
-    }
-
-    // Negate the result of last #if
-    EnableOutput ^= 1;
-
-    if (iBody.Length)
-        Error (iLine, "Warning: Ignoring garbage after #else", &iBody);
-
-    return true;
-}
-
-bool CPreprocessor::HandleEndIf (Token &iBody, int iLine)
-{
-    EnableOutput >>= 1;
-    if (EnableOutput == 0)
-    {
-        Error (iLine, "#endif without #if");
-        return false;
-    }
-
-    if (iBody.Length)
-        Error (iLine, "Warning: Ignoring garbage after #endif", &iBody);
-
-    return true;
-}
-
-CPreprocessor::Token CPreprocessor::HandleDirective (Token &iToken, int iLine)
-{
-    // Analyze preprocessor directive
-    const char *directive = iToken.String + 1;
-    size_t dirlen = iToken.Length - 1;
-    while (dirlen && isspace (*directive))
-        dirlen--, directive++;
-
-    int old_line = Line;
-
-    // Collect the remaining part of the directive until EOL
-    Token t, last;
-    do
-    {
-        t = GetToken (false);
-        if (t.Type == Token::TK_NEWLINE)
-        {
-            // No directive arguments
-            last = t;
-            t.Length = 0;
-            goto Done;
-        }
-    } while (t.Type == Token::TK_WHITESPACE ||
-             t.Type == Token::TK_LINECONT ||
-             t.Type == Token::TK_COMMENT ||
-             t.Type == Token::TK_LINECOMMENT);
-
-    for (;;)
-    {
-        last = GetToken (false);
-        switch (last.Type)
-        {
-            case Token::TK_EOS:
-                // Can happen and is not an error
-                goto Done;
-
-            case Token::TK_LINECOMMENT:
-            case Token::TK_COMMENT:
-                // Skip comments in macros
-                continue;
-
-            case Token::TK_ERROR:
-                return last;
-
-            case Token::TK_LINECONT:
-                continue;
-
-            case Token::TK_NEWLINE:
-                goto Done;
-
-            default:
-                break;
-        }
-
-        t.Append (last);
-        t.Type = Token::TK_TEXT;
-    }
-Done:
-
-#define IS_DIRECTIVE(s) \
-    ((dirlen == sizeof (s) - 1) && (strncmp (directive, s, sizeof (s) - 1) == 0))
-
-    bool rc;
-    if (IS_DIRECTIVE ("define"))
-        rc = HandleDefine (t, iLine);
-    else if (IS_DIRECTIVE ("undef"))
-        rc = HandleUnDef (t, iLine);
-    else if (IS_DIRECTIVE ("ifdef"))
-        rc = HandleIfDef (t, iLine);
-    else if (IS_DIRECTIVE ("ifndef"))
-    {
-        rc = HandleIfDef (t, iLine);
-        if (rc)
-            EnableOutput ^= 1;
-    }
-    else if (IS_DIRECTIVE ("if"))
-        rc = HandleIf (t, iLine);
-    else if (IS_DIRECTIVE ("else"))
-        rc = HandleElse (t, iLine);
-    else if (IS_DIRECTIVE ("endif"))
-        rc = HandleEndIf (t, iLine);
-    else
-    {
-        //Error (iLine, "Unknown preprocessor directive", &iToken);
-        //return Token (Token::TK_ERROR);
-
-        // Unknown preprocessor directive, roll back and pass through
-        Line = old_line;
-        Source = iToken.String + iToken.Length;
-        iToken.Type = Token::TK_TEXT;
-        return iToken;
-    }
-
-#undef IS_DIRECTIVE
-
-    if (!rc)
-        return Token (Token::TK_ERROR);
-    return last;
-}
-
-void CPreprocessor::Define (const char *iMacroName, size_t iMacroNameLen,
-                            const char *iMacroValue, size_t iMacroValueLen)
-{
-    Macro *m = bs_new<Macro, ScratchAlloc>(Token (Token::TK_KEYWORD, iMacroName, iMacroNameLen));
-    m->Value = Token (Token::TK_TEXT, iMacroValue, iMacroValueLen);
-    m->Next = MacroList;
-    MacroList = m;
-}
-
-void CPreprocessor::Define (const char *iMacroName, size_t iMacroNameLen,
-                            long iMacroValue)
-{
-    Macro *m = bs_new<Macro, ScratchAlloc>(Token (Token::TK_KEYWORD, iMacroName, iMacroNameLen));
-    m->Value.SetValue (iMacroValue);
-    m->Next = MacroList;
-    MacroList = m;
-}
-
-bool CPreprocessor::Undef (const char *iMacroName, size_t iMacroNameLen)
-{
-    Macro **cur = &MacroList;
-    Token name (Token::TK_KEYWORD, iMacroName, iMacroNameLen);
-    while (*cur)
-    {
-        if ((*cur)->Name == name)
-        {
-            Macro *next = (*cur)->Next;
-            (*cur)->Next = NULL;
-            bs_delete<ScratchAlloc>(*cur);
-            *cur = next;
-            return true;
-        }
-
-        cur = &(*cur)->Next;
-    }
-
-    return false;
-}
-
-CPreprocessor::Token CPreprocessor::Parse (const Token &iSource)
-{
-    Source = iSource.String;
-    SourceEnd = Source + iSource.Length;
-    Line = 1;
-    BOL = true;
-    EnableOutput = 1;
-
-    // Accumulate output into this token
-    Token output (Token::TK_TEXT);
-    int empty_lines = 0;
-
-    // Enable output only if all embedded #if's were true
-    bool old_output_enabled = true;
-    bool output_enabled = true;
-    int output_disabled_line = 0;
-
-    while (Source < SourceEnd)
-    {
-        int old_line = Line;
-        Token t = GetToken (true);
-
-    NextToken:
-        switch (t.Type)
-        {
-            case Token::TK_ERROR:
-                return t;
-
-            case Token::TK_EOS:
-                return output; // Force termination
-
-            case Token::TK_COMMENT:
-                // C comments are replaced with single spaces.
-                if (output_enabled)
-                {
-                    output.Append (" ", 1);
-                    output.AppendNL (Line - old_line);
-                }
-                break;
-
-            case Token::TK_LINECOMMENT:
-                // C++ comments are ignored
-                continue;
-
-            case Token::TK_DIRECTIVE:
-                // Handle preprocessor directives
-                t = HandleDirective (t, old_line);
-
-                output_enabled = ((EnableOutput & (EnableOutput + 1)) == 0);
-                if (output_enabled != old_output_enabled)
-                {
-                    if (output_enabled)
-                        output.AppendNL (old_line - output_disabled_line);
-                    else
-                        output_disabled_line = old_line;
-                    old_output_enabled = output_enabled;
-                }
-
-                if (output_enabled)
-                    output.AppendNL (Line - old_line - t.CountNL ());
-                goto NextToken;
-
-            case Token::TK_LINECONT:
-                // Backslash-Newline sequences are deleted, no matter where.
-                empty_lines++;
-                break;
-
-            case Token::TK_NEWLINE:
-                if (empty_lines)
-                {
-                    // Compensate for the backslash-newline combinations
-                    // we have encountered, otherwise line numeration is broken
-                    if (output_enabled)
-                        output.AppendNL (empty_lines);
-                    empty_lines = 0;
-                }
-                // Fallthrough to default
-            case Token::TK_WHITESPACE:
-                // Fallthrough to default
-            default:
-                // Passthrough all other tokens
-                if (output_enabled)
-                    output.Append (t);
-                break;
-        }
-    }
-
-    if (EnableOutput != 1)
-    {
-        Error (Line, "Unclosed #if at end of source");
-        return Token (Token::TK_ERROR);
-    }
-
-    return output;
-}
-
-char *CPreprocessor::Parse (const char *iSource, size_t iLength, size_t &oLength)
-{
-    Token retval = Parse (Token (Token::TK_TEXT, iSource, iLength));
-    if (retval.Type == Token::TK_ERROR)
-        return NULL;
-
-    oLength = retval.Length;
-    retval.Allocated = 0;
-    return retval.Buffer;
-}
-
-}

+ 7 - 0
BansheeGLRenderSystem/Source/win32/BsGLUtil.h

@@ -1,12 +1,19 @@
 #pragma once
 #pragma once
 
 
+#if BS_PLATFORM == BS_PLATFORM_WIN32
+
 #include "BsWin32GLSupport.h"
 #include "BsWin32GLSupport.h"
 #include "BsWin32VideoModeInfo.h"
 #include "BsWin32VideoModeInfo.h"
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
+	/**
+	 * @brief	Helper method that returns a platform specific GL support object.
+	 */
 	GLSupport* getGLSupport()
 	GLSupport* getGLSupport()
 	{
 	{
 		return bs_new<Win32GLSupport>();
 		return bs_new<Win32GLSupport>();
 	}
 	}
 };
 };
+
+#endif

+ 4 - 4
ExampleProject/Main/Main.cpp

@@ -120,14 +120,14 @@ namespace BansheeEngine
 		renderable->setMaterial(exampleMaterial);
 		renderable->setMaterial(exampleMaterial);
 
 
 		// Set up scene camera
 		// Set up scene camera
-		HSceneObject sceneCameraGO = SceneObject::create("SceneCamera");
+		HSceneObject sceneCameraSO = SceneObject::create("SceneCamera");
 
 
 		RenderWindowPtr window = gApplication().getPrimaryWindow();
 		RenderWindowPtr window = gApplication().getPrimaryWindow();
-		sceneCamera = sceneCameraGO->addComponent<Camera>(window, 0.0f, 0.0f, 1.0f, 1.0f);
+		sceneCamera = sceneCameraSO->addComponent<Camera>(window, 0.0f, 0.0f, 1.0f, 1.0f);
 
 
 		sceneCamera->setPriority(1);
 		sceneCamera->setPriority(1);
-		sceneCameraGO->setPosition(Vector3(0, 50, 1240));
-		sceneCameraGO->lookAt(Vector3(0, 50, -300));
+		sceneCameraSO->setPosition(Vector3(0, 50, 1240));
+		sceneCameraSO->lookAt(Vector3(0, 50, -300));
 		sceneCamera->setNearClipDistance(5);
 		sceneCamera->setNearClipDistance(5);
 		sceneCamera->setAspectRatio(resolutionWidth / (float)resolutionHeight); // TODO - This needs to get called whenever resolution changes
 		sceneCamera->setAspectRatio(resolutionWidth / (float)resolutionHeight); // TODO - This needs to get called whenever resolution changes
 
 

+ 1 - 2
Renderer.txt

@@ -1,6 +1,5 @@
 Param matching missing:
 Param matching missing:
- - // TODO - Find parameter gpu name and hook up its handle and "hasWVP"
- - Implement getDefaultShader in BansheeRenderer
+ - Add default DX9/DX11/OpenGL shaders
 
 
 -----------------------------------------------------------
 -----------------------------------------------------------
 NON TRIVIAL BUT SIMPLE
 NON TRIVIAL BUT SIMPLE