Просмотр исходного кода

VertexDeclaration is now immutable

Marko Pintera 11 лет назад
Родитель
Сommit
4782475448
25 измененных файлов с 287 добавлено и 1269 удалено
  1. 8 8
      BansheeMono/Source/BsMonoManager.cpp
  2. 15 1
      BoostPort.txt
  3. 6 39
      CamelotCore/Include/CmHardwareBufferManager.h
  4. 5 106
      CamelotCore/Include/CmVertexData.h
  5. 97 337
      CamelotCore/Include/CmVertexDeclaration.h
  6. 1 1
      CamelotCore/Include/CmVertexDeclarationRTTI.h
  7. 3 1
      CamelotCore/Source/CmCoreObjectManager.cpp
  8. 13 41
      CamelotCore/Source/CmHardwareBufferManager.cpp
  9. 1 158
      CamelotCore/Source/CmVertexData.cpp
  10. 6 3
      CamelotCore/Source/CmVertexDataDesc.cpp
  11. 69 330
      CamelotCore/Source/CmVertexDeclaration.cpp
  12. 2 1
      CamelotD3D11RenderSystem/Include/CmD3D11HLSLParamParser.h
  13. 1 3
      CamelotD3D11RenderSystem/Include/CmD3D11InputLayoutManager.h
  14. 9 3
      CamelotD3D11RenderSystem/Source/CmD3D11GpuProgram.cpp
  15. 5 5
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLParamParser.cpp
  16. 4 25
      CamelotD3D11RenderSystem/Source/CmD3D11InputLayoutManager.cpp
  17. 1 4
      CamelotD3D11RenderSystem/Source/CmD3D11Mappings.cpp
  18. 3 34
      CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.h
  19. 6 60
      CamelotD3D9Renderer/Include/CmD3D9VertexDeclaration.h
  20. 8 36
      CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp
  21. 1 4
      CamelotD3D9Renderer/Source/CmD3D9Mappings.cpp
  22. 10 62
      CamelotD3D9Renderer/Source/CmD3D9VertexDeclaration.cpp
  23. 1 1
      CamelotGLRenderer/Source/CmGLRenderSystem.cpp
  24. 6 3
      CamelotGLRenderer/Source/GLSL/include/CmGLSLParamParser.h
  25. 6 3
      CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp

+ 8 - 8
BansheeMono/Source/BsMonoManager.cpp

@@ -21,19 +21,19 @@ namespace BansheeEngine
 
 	MonoManager::~MonoManager()
 	{
-		//for(auto& entry : mAssemblies)
-		//{
-		//	unloadAssembly(*entry.second); 
-		//	cm_delete(entry.second);
-		//}
-
-		mAssemblies.clear();
-
 		if(mDomain != nullptr)
 		{
 			mono_jit_cleanup(mDomain);
 			mDomain = nullptr;
 		}
+
+		for (auto& entry : mAssemblies)
+		{
+			unloadAssembly(*entry.second);
+			cm_delete(entry.second);
+		}
+
+		mAssemblies.clear();
 	}
 
 	MonoAssembly& MonoManager::loadAssembly(const String& path, const String& name)

+ 15 - 1
BoostPort.txt

@@ -9,4 +9,18 @@ DEBUG CODE in GLRenderSystem::beginDraw()
 I'll probably want a system like PipelineManager where it saves all VS and VB combinations and retuns vertex array for it.
  - Those vertex arrays should probably be saved in the vertex shader
 
-Create a proper git repo of dependencies folder
+Each VertexDeclaration needs unique ID. 
+ - Attempt to make vertex declarations immutable. Once created they get a unique ID.
+ - Do the same for vertex buffers and vertex shaders
+ - Remove hash from vertex declaration and replace it with ID, also fix the comparison functions because
+   in DX11 finding input layout will involve going over every single element in the declaration since it's
+   stored in an unordered map.
+
+Create a proper git repo of dependencies folder
+
+Shutdown issues (can't repro atm but they're there):
+Destroying area sometimes fails
+ - I'm guessing that is because EditorWindows get closed and destroyed before scripts are unloaded. All areas and GUI elements are destroyed with them.
+  - I should try to manually destroy C# editor windows before main window is closed
+
+Native instance is sometimes null when delete is called

+ 6 - 39
CamelotCore/Include/CmHardwareBufferManager.h

@@ -1,42 +1,14 @@
-/*
------------------------------------------------------------------------------
-This source file is part of OGRE
-    (Object-oriented Graphics Rendering Engine)
-For the latest info, see http://www.ogre3d.org/
+#pragma once
 
-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 __HardwareBufferManager__
-#define __HardwareBufferManager__
-
-// Precompiler options
 #include "CmPrerequisites.h"
-
 #include "CmModule.h"
 #include "CmVertexBuffer.h"
 #include "CmIndexBuffer.h"
+#include "CmVertexDeclaration.h"
 #include "CmGpuParamBlock.h"
 
-namespace BansheeEngine {
+namespace BansheeEngine 
+{
 	/** \addtogroup Core
 	*  @{
 	*/
@@ -113,20 +85,15 @@ namespace BansheeEngine {
 			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
 
         /** Creates a new vertex declaration. */
-        virtual VertexDeclarationPtr createVertexDeclaration();
+		virtual VertexDeclarationPtr createVertexDeclaration(const VertexDeclaration::VertexElementList& elements);
 
 	protected:
-		virtual VertexDeclarationPtr createVertexDeclarationImpl();
+		virtual VertexDeclarationPtr createVertexDeclarationImpl(const VertexDeclaration::VertexElementList& elements);
 		virtual VertexBufferPtr createVertexBufferImpl(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut = false) = 0;
 		virtual IndexBufferPtr createIndexBufferImpl(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage) = 0;
 		virtual GpuParamBlockBufferPtr createGpuParamBlockBufferImpl() = 0;
 		virtual GpuBufferPtr createGpuBufferImpl(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferUsage usage, 
 			bool randomGpuWrite = false, bool useCounter = false) = 0;
 	};
-
-	/** @} */
-	/** @} */
 }
 
-#endif
-

+ 5 - 106
CamelotCore/Include/CmVertexData.h

@@ -1,38 +1,11 @@
-/*
------------------------------------------------------------------------------
-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 __VertexIndexData_H__
-#define __VertexIndexData_H__
+#pragma once
 
 #include "CmPrerequisites.h"
 #include "CmVertexDeclaration.h"
 #include "CmVertexBuffer.h"
 
-namespace BansheeEngine {
+namespace BansheeEngine 
+{
 	/** \addtogroup Core
 	*  @{
 	*/
@@ -44,19 +17,7 @@ namespace BansheeEngine {
 	class CM_EXPORT VertexData
 	{
     public:
-		/** Constructor.
-		@note 
-			This constructor creates the VertexDeclaration and VertexBufferBinding
-			automatically, and arranges for their deletion afterwards.
-		@param mgr Optional HardwareBufferManager from which to create resources
-		*/
-        VertexData(HardwareBufferManager* mgr = 0);
-		/** Constructor.
-		@note 
-		This constructor receives the VertexDeclaration from the caller.
-		@param dcl The VertexDeclaration to use
-		*/
-		VertexData(VertexDeclarationPtr dcl);
+        VertexData();
         ~VertexData();
 
 		/** Declaration of the vertex to be used in this operation. 
@@ -77,72 +38,10 @@ namespace BansheeEngine {
 		UINT32 getBufferCount(void) const { return (UINT32)mVertexBuffers.size(); }
 		UINT32 getMaxBufferIndex(void) const { return (UINT32)mVertexBuffers.size(); }
 
-		/** Convert all packed colour values (VET_COLOUR_*) in buffers used to
-			another type.
-		@param srcType The source colour type to assume if the ambiguous VET_COLOUR
-			is encountered.
-		@param destType The destination colour type, must be VET_COLOUR_ABGR or
-			VET_COLOUR_ARGB.
-		*/
-		void convertPackedColour(VertexElementType srcType, VertexElementType destType);
-
     private:
-        /// Protected copy constructor, to prevent misuse
-        VertexData(const VertexData& rhs); /* do nothing, should not use */
-        /// Protected operator=, to prevent misuse
-        VertexData& operator=(const VertexData& rhs); /* do not use */
-
-		HardwareBufferManager* mMgr;
-		bool mOwnsDeclaration;
-
 		/** The vertex buffer bindings to be used. 
 		@remarks Note that this is created for you on construction.
 		*/
 		UnorderedMap<UINT32, VertexBufferPtr> mVertexBuffers;
 	};
-
-	/** Vertex cache profiler.
-	@remarks
-		Utility class for evaluating the effectiveness of the use of the vertex
-		cache by a given index buffer.
-	*/
-	class CM_EXPORT VertexCacheProfiler
-    {
-		public:
-			enum CacheType {
-				FIFO, LRU
-			};
-
-			VertexCacheProfiler(unsigned int cachesize = 16, CacheType cachetype = FIFO )
-				: size ( cachesize ), type ( cachetype ), tail (0), buffersize (0), hit (0), miss (0)
-			{
-				cache = (UINT32*)malloc(sizeof(UINT32) * size);
-			}
-
-			~VertexCacheProfiler()
-			{
-				free(cache);
-			}
-
-			void profile(const IndexBufferPtr& indexBuffer);
-			void reset() { hit = 0; miss = 0; tail = 0; buffersize = 0; }
-			void flush() { tail = 0; buffersize = 0; }
-
-			unsigned int getHits() { return hit; }
-			unsigned int getMisses() { return miss; }
-			unsigned int getSize() { return size; }
-		private:
-			unsigned int size;
-			UINT32 *cache;
-			CacheType type;
-
-			unsigned int tail, buffersize;
-			unsigned int hit, miss;
-
-			bool inCache(unsigned int index);
-	};
-	/** @} */
-	/** @} */
-}
-#endif
-
+}

+ 97 - 337
CamelotCore/Include/CmVertexDeclaration.h

@@ -6,409 +6,169 @@
 
 namespace BansheeEngine
 {
-	/// Vertex element semantics, used to identify the meaning of vertex buffer contents
-	enum VertexElementSemantic {
-		/// Position, 3 reals per vertex
+	/**
+	 * @brief	Semantics that are used for identifying the meaning of
+	 *			vertex buffer elements.
+	 */
+	enum VertexElementSemantic 
+	{
 		VES_POSITION = 1,
-		/// Blending weights
 		VES_BLEND_WEIGHTS = 2,
-        /// Blending indices
         VES_BLEND_INDICES = 3,
-		/// Normal, 3 reals per vertex
 		VES_NORMAL = 4,
-		/// Diffuse colours
 		VES_COLOR = 5,
-		/// Specular colours
-		VES_SPECULAR = 6,
-		/// Texture coordinates
-		VES_TEXCOORD = 7,
-        /// Binormal (Y axis if normal is Z)
-        VES_BITANGENT = 8,
-        /// Tangent (X axis if normal is Z)
-        VES_TANGENT = 9,
-		/// Transformed vertex position
-		VES_POSITIONT = 10,
-		/// Point size
-		VES_PSIZE = 11
+		VES_TEXCOORD = 6,
+        VES_BITANGENT = 7,
+        VES_TANGENT = 8,
+		VES_POSITIONT = 9,
+		VES_PSIZE = 10
 	};
 
-    /// Vertex element type, used to identify the base types of the vertex contents
+	/**
+	 * @brief	Types used to identify base types of vertex element contents
+	 */
     enum VertexElementType
     {
         VET_FLOAT1 = 0,
         VET_FLOAT2 = 1,
         VET_FLOAT3 = 2,
         VET_FLOAT4 = 3,
-        /// alias to more specific color type - use the current rendersystem's color packing
 		VET_COLOR = 4,
 		VET_SHORT1 = 5,
 		VET_SHORT2 = 6,
 		VET_SHORT3 = 7,
 		VET_SHORT4 = 8,
         VET_UBYTE4 = 9,
-        /// D3D style compact color
         VET_COLOR_ARGB = 10,
-        /// GL style compact color
         VET_COLOR_ABGR = 11,
 		VET_UINT4 = 12,
 		VET_SINT4 = 13
     };
 
-    /** This class declares the usage of a single vertex buffer as a component
-        of a complete VertexDeclaration.
-        @remarks
-        Several vertex buffers can be used to supply the input geometry for a
-        rendering operation, and in each case a vertex buffer can be used in
-        different ways for different operations; the buffer itself does not
-        define the semantics (position, normal etc), the VertexElement
-        class does.
-    */
+	/**
+	 * @brief	Describes a single vertex element in a vertex declaration.
+	 */
 	class CM_EXPORT VertexElement
     {
-    protected:
-        /// The source vertex buffer
-        unsigned short mSource;
-        /// The offset in the buffer that this element starts at
-        UINT32 mOffset;
-        /// The type of element
-        VertexElementType mType;
-        /// The meaning of the element
-        VertexElementSemantic mSemantic;
-        /// Index of the item, only applicable for some elements like texture coords
-        unsigned short mIndex;
     public:
-		/// Constructor, should not be called directly, only needed because of list
 		VertexElement() {}
-        /// Constructor, should not be called directly, call VertexDeclaration::addElement
-        VertexElement(unsigned short source, UINT32 offset, VertexElementType theType,
-            VertexElementSemantic semantic, unsigned short index = 0);
-        /// Gets the vertex buffer index from where this element draws it's values
-        unsigned short getStreamIdx(void) const { return mSource; }
-        /// Gets the offset into the buffer where this element starts
-        UINT32 getOffset(void) const { return mOffset; }
-        /// Gets the data format of this element
-        VertexElementType getType(void) const { return mType; }
-        /// Gets the meaning of this element
-        VertexElementSemantic getSemantic(void) const { return mSemantic; }
-        /// Gets the index of this element, only applicable for repeating elements
-        unsigned short getSemanticIdx(void) const { return mIndex; }
-		/// Gets the size of this element in bytes
-		UINT32 getSize(void) const;
-		/// Utility method for helping to calculate offsets
-		static UINT32 getTypeSize(VertexElementType etype);
-		/// Utility method which returns the count of values in a given type
-		static unsigned short getTypeCount(VertexElementType etype);
-		/** Simple converter function which will turn a single-value type into a
-			multi-value type based on a parameter.
-		*/
-		static VertexElementType multiplyTypeCount(VertexElementType baseType, unsigned short count);
-		/** Simple converter function which will a type into it's single-value
-			equivalent - makes switches on type easier.
-		*/
-		static VertexElementType getBaseType(VertexElementType multiType);
+        VertexElement(UINT16 source, UINT32 offset, VertexElementType theType,
+			VertexElementSemantic semantic, UINT16 index = 0);
 
-		/** Utility method for converting colour from
-			one packed 32-bit colour type to another.
-		@param srcType The source type
-		@param dstType The destination type
-		@param ptr Read / write value to change
-		*/
-		static void convertColourValue(VertexElementType srcType,
-			VertexElementType dstType, UINT32* ptr);
+		bool operator== (const VertexElement& rhs) const;
+		bool operator!= (const VertexElement& rhs) const;
 
-		/** Utility method for converting colour to
-			a packed 32-bit colour type.
-		@param src source colour
-		@param dst The destination type
-		*/
-		static UINT32 convertColourValue(const Color& src,
-			VertexElementType dst);
+		/**
+		 * @brief	Returns index of the vertex buffer from which this element is stored.
+		 */
+		UINT16 getStreamIdx() const { return mSource; }
 
-		/** Utility method to get the most appropriate packed colour vertex element format. */
-		static VertexElementType getBestColourVertexElementType(void);
+		/**
+		 * @brief	Returns an offset into the buffer where this vertex is stored. This value
+		 *			might be in bytes but doesn't have to be, it's likely to be render API specific.
+		 */
+        UINT32 getOffset() const { return mOffset; }
 
-        inline bool operator== (const VertexElement& rhs) const
-        {
-            if (mType != rhs.mType ||
-                mIndex != rhs.mIndex ||
-                mOffset != rhs.mOffset ||
-                mSemantic != rhs.mSemantic ||
-                mSource != rhs.mSource)
-                return false;
-            else
-                return true;
-        }
+		/**
+		 * @brief	Gets the base data type of tis element.
+		 */
+        VertexElementType getType() const { return mType; }
 
-		inline bool operator!= (const VertexElement& rhs) const
-		{
-			return !(*this == rhs);
-		}
+		/**
+		 * @brief	Gets a semantic that describes what this element contains.
+		 */
+        VertexElementSemantic getSemantic() const { return mSemantic; }
 
-        /** Adjusts a pointer to the base of a vertex to point at this element.
-        @remarks
-            This variant is for void pointers, passed as a parameter because we can't
-            rely on covariant return types.
-        @param pBase Pointer to the start of a vertex in this buffer.
-        @param pElem Pointer to a pointer which will be set to the start of this element.
-        */
-        inline void baseVertexPointerToElement(void* pBase, void** pElem) const
-        {
-            // The only way we can do this is to cast to char* in order to use byte offset
-            // then cast back to void*.
-            *pElem = static_cast<void*>(
-            	static_cast<unsigned char*>(pBase) + mOffset);
-        }
-        /** Adjusts a pointer to the base of a vertex to point at this element.
-        @remarks
-            This variant is for float pointers, passed as a parameter because we can't
-            rely on covariant return types.
-        @param pBase Pointer to the start of a vertex in this buffer.
-        @param pElem Pointer to a pointer which will be set to the start of this element.
-        */
-        inline void baseVertexPointerToElement(void* pBase, float** pElem) const
-        {
-            // The only way we can do this is to cast to char* in order to use byte offset
-            // then cast back to float*. However we have to go via void* because casting
-            // directly is not allowed
-            *pElem = static_cast<float*>(
-                static_cast<void*>(
-                    static_cast<unsigned char*>(pBase) + mOffset));
-        }
+		/**
+		 * @brief	Gets an index of this element. Only relevant when you have
+		 *			multiple elements with the same semantic, e.g. uv0, uv1.
+		 */
+		UINT16 getSemanticIdx() const { return mIndex; }
 
-        /** Adjusts a pointer to the base of a vertex to point at this element.
-        @remarks
-            This variant is for RGBA pointers, passed as a parameter because we can't
-            rely on covariant return types.
-        @param pBase Pointer to the start of a vertex in this buffer.
-        @param pElem Pointer to a pointer which will be set to the start of this element.
-        */
-        inline void baseVertexPointerToElement(void* pBase, RGBA** pElem) const
-        {
-            *pElem = static_cast<RGBA*>(
-                static_cast<void*>(
-                    static_cast<unsigned char*>(pBase) + mOffset));
-        }
-        /** Adjusts a pointer to the base of a vertex to point at this element.
-        @remarks
-            This variant is for char pointers, passed as a parameter because we can't
-            rely on covariant return types.
-        @param pBase Pointer to the start of a vertex in this buffer.
-        @param pElem Pointer to a pointer which will be set to the start of this element.
-        */
-        inline void baseVertexPointerToElement(void* pBase, unsigned char** pElem) const
-        {
-            *pElem = static_cast<unsigned char*>(pBase) + mOffset;
-        }
+		/**
+		 * @brief	Returns the size of this element in bytes.
+		 */
+		UINT32 getSize() const;
 
-        /** Adjusts a pointer to the base of a vertex to point at this element.
-        @remarks
-        This variant is for UINT16 pointers, passed as a parameter because we can't
-        rely on covariant return types.
-        @param pBase Pointer to the start of a vertex in this buffer.
-        @param pElem Pointer to a pointer which will be set to the start of this element.
-        */
-        inline void baseVertexPointerToElement(void* pBase, unsigned short** pElem) const
-        {
-			*pElem = static_cast<unsigned short*>(
-				static_cast<void*>(
-					static_cast<unsigned char*>(pBase) + mOffset));
-        }
+		/**
+		 * @brief	Returns the size of a base element type.
+		 */
+		static UINT32 getTypeSize(VertexElementType etype);
 
 		/**
-		 * @brief	Calculates a hash value for this element.
+		 * @brief	Returns the number of values in the provided base element type.
+		 *			e.g. float4 has four values.
 		 */
-		size_t calculateHash() const;
+		static UINT16 getTypeCount(VertexElementType etype);
 
+		/**
+		 * @brief	Gets packed color vertex element type used by the active render system.
+		 */
+		static VertexElementType getBestColorVertexElementType();
+
+	protected:
+		UINT16 mSource;
+		UINT32 mOffset;
+		VertexElementType mType;
+		VertexElementSemantic mSemantic;
+		UINT16 mIndex;
     };
 
 	CM_ALLOW_MEMCPY_SERIALIZATION(VertexElement);
 
-    /** This class declares the format of a set of vertex inputs, which
-        can be issued to the rendering API through a RenderOperation.
-	@remarks
-	You should be aware that the ordering and structure of the
-	VertexDeclaration can be very important on DirectX with older
-	cards,so if you want to maintain maximum compatibility with
-	all render systems and all cards you should be careful to follow these
-	rules:<ol>
-	<li>VertexElements should be added in the following order, and the order of the
-	elements within a shared buffer should be as follows:
-	position, blending weights, normals, diffuse colours, specular colours,
-            texture coordinates (in order, with no gaps)</li>
-	<li>You must not have unused gaps in your buffers which are not referenced
-	by any VertexElement</li>
-	<li>You must not cause the buffer & offset settings of 2 VertexElements to overlap</li>
-	</ol>
-	Whilst GL and more modern graphics cards in D3D will allow you to defy these rules,
-	sticking to them will ensure that your buffers have the maximum compatibility.
-	@par
-	Like the other classes in this functional area, these declarations should be created and
-	destroyed using the HardwareBufferManager.
-    */
+	/**
+	 * @brief	Describes a set of vertex elements, used for describing contents of
+	 *			a vertex buffer or inputs to a vertex GPU program.
+	 */
 	class CM_EXPORT VertexDeclaration : public IReflectable, public CoreObject
     {
     public:
-		/// Defines the list of vertex elements that makes up this declaration
         typedef List<VertexElement> VertexElementList;
-        /// Sort routine for vertex elements
-        static bool vertexElementLess(const VertexElement& e1, const VertexElement& e2);
 
+	public:
         virtual ~VertexDeclaration();
 
-        /** Get the number of elements in the declaration. */
-        UINT32 getElementCount(void) { return (UINT32)mElementList.size(); }
-        /** Gets read-only access to the list of vertex elements. */
-        const VertexElementList& getElements(void) const;
-        /** Get a single element. */
-        const VertexElement* getElement(unsigned short index);
+		bool operator== (const VertexDeclaration& rhs) const;
+		bool operator!= (const VertexDeclaration& rhs) const;
 
 		/**
-		 * @brief	Returns a hash value generated by all of the elements in the declaration.
+		 * @brief	Get the number of elements in the declaration.
 		 */
-		size_t getHash() { return mHash; }
-
-        /** Sorts the elements in this list to be compatible with the maximum
-            number of rendering APIs / graphics cards.
-        @remarks
-            Older graphics cards require vertex data to be presented in a more
-            rigid way, as defined in the main documentation for this class. As well
-            as the ordering being important, where shared source buffers are used, the
-            declaration must list all the elements for each source in turn.
-        */
-        void sort(void);
-
-        /** Remove any gaps in the source buffer list used by this declaration.
-        @remarks
-            This is useful if you've modified a declaration and want to remove
-            any gaps in the list of buffers being used. Note, however, that if this
-            declaration is already being used with a VertexBufferBinding, you will
-            need to alter that too. This method is mainly useful when reorganising
-            buffers based on an altered declaration.
-        @note
-            This will cause the vertex declaration to be re-sorted.
-        */
-        void closeGapsInSource(void);
-
-        /** Gets the index of the highest source value referenced by this declaration. */
-        unsigned short getMaxSource(void) const;
-
-
-
-        /** Adds a new VertexElement to this declaration.
-        @remarks
-            This method adds a single element (positions, normals etc) to the end of the
-            vertex declaration. <b>Please read the information in VertexDeclaration about
-	    the importance of ordering and structure for compatibility with older D3D drivers</b>.
-	    @param source The binding index of HardwareVertexBuffer which will provide the source for this element.
-			See VertexBufferBindingState for full information.
-        @param offset The offset in bytes where this element is located in the buffer
-        @param theType The data format of the element (3 floats, a colour etc)
-        @param semantic The meaning of the data (position, normal, diffuse colour etc)
-        @param index Optional index for multi-input elements like texture coordinates
-		@returns A reference to the VertexElement added.
-        */
-        virtual const VertexElement& addElement(unsigned short source, UINT32 offset, VertexElementType theType,
-            VertexElementSemantic semantic, unsigned short index = 0);
-        /** Inserts a new VertexElement at a given position in this declaration.
-        @remarks
-        This method adds a single element (positions, normals etc) at a given position in this
-        vertex declaration. <b>Please read the information in VertexDeclaration about
-        the importance of ordering and structure for compatibility with older D3D drivers</b>.
-        @param source The binding index of HardwareVertexBuffer which will provide the source for this element.
-        See VertexBufferBindingState for full information.
-        @param offset The offset in bytes where this element is located in the buffer
-        @param theType The data format of the element (3 floats, a colour etc)
-        @param semantic The meaning of the data (position, normal, diffuse colour etc)
-        @param index Optional index for multi-input elements like texture coordinates
-        @returns A reference to the VertexElement added.
-        */
-        virtual const VertexElement& insertElement(unsigned short atPosition,
-            unsigned short source, UINT32 offset, VertexElementType theType,
-            VertexElementSemantic semantic, unsigned short index = 0);
-
-        /** Remove the element at the given index from this declaration. */
-        virtual void removeElement(unsigned short elem_index);
-
-        /** Remove the element with the given semantic and usage index.
-        @remarks
-            In this case 'index' means the usage index for repeating elements such
-            as texture coordinates. For other elements this will always be 0 and does
-            not refer to the index in the vector.
-        */
-        virtual void removeElement(VertexElementSemantic semantic, unsigned short index = 0);
-
-		/** Remove all elements. */
-		virtual void removeAllElements(void);
-
-        /** Modify an element in-place, params as addElement.
-	   @remarks
-	   <b>Please read the information in VertexDeclaration about
-	    the importance of ordering and structure for compatibility with older D3D drivers</b>.
-	 */
-        virtual void modifyElement(unsigned short elem_index, unsigned short source, UINT32 offset, VertexElementType theType,
-            VertexElementSemantic semantic, unsigned short index = 0);
-
-		/** Finds a VertexElement with the given semantic, and index if there is more than
-			one element with the same semantic.
-        @remarks
-            If the element is not found, this method returns null.
-		*/
-		virtual const VertexElement* findElementBySemantic(VertexElementSemantic sem, unsigned short index = 0);
-		/** Based on the current elements, gets the size of the vertex for a given buffer source.
-		@param source The buffer binding index for which to get the vertex size.
-		*/
-
-		/** Gets a list of elements which use a given source.
-		@remarks
-			Note that the list of elements is returned by value therefore is separate from
-			the declaration as soon as this method returns.
-		*/
-		virtual VertexElementList findElementsBySource(unsigned short source);
-
-		/** Gets the vertex size defined by this declaration for a given source. */
-        virtual UINT32 getVertexSize(unsigned short source);
+        UINT32 getElementCount() { return (UINT32)mElementList.size(); }
+        
+		/**
+		 * @brief	Returns a list of vertex elements in the declaration.
+		 */
+		const VertexElementList& getElements() const { return mElementList; }
 
-        /** Clones this declaration. 
-		@param mgr Optional HardwareBufferManager to use for creating the clone
-			(if null, use the current default).
-		*/
-        virtual VertexDeclarationPtr clone(HardwareBufferManager* mgr = 0);
+		/**
+		 * @brief	Returns a single vertex element at the specified index.
+		 */
+        const VertexElement* getElement(UINT16 index);
 
-        inline bool operator== (const VertexDeclaration& rhs) const
-        {
-            if (mElementList.size() != rhs.mElementList.size())
-                return false;
+		/**
+		 * @brief	Attempts to find an element by the given semantic and semantic index. If no element
+		 *			can be found null is returned.
+		 */
+		virtual const VertexElement* findElementBySemantic(VertexElementSemantic sem, UINT16 index = 0);
 
-            VertexElementList::const_iterator i, iend, rhsi, rhsiend;
-            iend = mElementList.end();
-            rhsiend = rhs.mElementList.end();
-            rhsi = rhs.mElementList.begin();
-            for (i = mElementList.begin(); i != iend && rhsi != rhsiend; ++i, ++rhsi)
-            {
-                if ( !(*i == *rhsi) )
-                    return false;
-            }
+		/**
+		 * @brief	Returns a list of all elements that use the provided source index.
+		 */
+		virtual VertexElementList findElementsBySource(UINT16 source);
 
-            return true;
-        }
-        inline bool operator!= (const VertexDeclaration& rhs) const
-        {
-            return !(*this == rhs);
-        }
+		/**
+		 * @brief	Returns the total size of all vertex elements using the provided source index.
+		 */
+		virtual UINT32 getVertexSize(UINT16 source);
 
     protected:
 		friend class HardwareBufferManager;
 
-		VertexDeclaration();
-
-		/**
-		 * @brief	Generates a hash value based on all elements in the declaration.
-		 */
-		void recalculateHash();
+		VertexDeclaration(const VertexElementList& elements);
 
 	protected:
 		VertexElementList mElementList;
-		size_t mHash;
 
 		/************************************************************************/
 		/* 								SERIALIZATION                      		*/

+ 1 - 1
CamelotCore/Include/CmVertexDeclarationRTTI.h

@@ -48,7 +48,7 @@ namespace BansheeEngine
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject() 
 		{
-			return HardwareBufferManager::instance().createVertexDeclaration();
+			return HardwareBufferManager::instance().createVertexDeclaration(VertexDeclaration::VertexElementList());
 		}
 
 		virtual const String& getRTTIName() 

+ 3 - 1
CamelotCore/Source/CmCoreObjectManager.cpp

@@ -12,6 +12,7 @@ namespace BansheeEngine
 
 	CoreObjectManager::~CoreObjectManager()
 	{
+#if CM_DEBUG_MODE
 		CM_LOCK_MUTEX(mObjectsMutex);
 
 		if(mObjects.size() > 0)
@@ -20,9 +21,10 @@ namespace BansheeEngine
 			// (Reason: This is called on application shutdown and at that point we also unload any dynamic libraries, 
 			// which will invalidate any pointers to objects created from those libraries. Therefore we require of the user to 
 			// clean up all objects manually before shutting down the application).
-			CM_EXCEPT(InternalErrorException, "Core GPU object manager destroyed, but not all objects were released. User must release ALL " \
+			CM_EXCEPT(InternalErrorException, "Core object manager shut down, but not all objects were released. User must release ALL " \
 				"engine objects before application shutdown.");
 		}
+#endif
 	}
 
 	UINT64 CoreObjectManager::registerObject(CoreObject* object)

+ 13 - 41
CamelotCore/Source/CmHardwareBufferManager.cpp

@@ -1,31 +1,3 @@
-/*
------------------------------------------------------------------------------
-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 "CmHardwareBufferManager.h"
 #include "CmVertexData.h"
 #include "CmIndexData.h"
@@ -33,24 +5,24 @@ THE SOFTWARE.
 #include "CmVertexDeclaration.h"
 #include "CmGpuParamBlockBuffer.h"
 
-namespace BansheeEngine {
-    //-----------------------------------------------------------------------
+namespace BansheeEngine 
+{
     HardwareBufferManager::HardwareBufferManager()
     {
     }
-    //-----------------------------------------------------------------------
+
     HardwareBufferManager::~HardwareBufferManager()
     {
     }
-    //-----------------------------------------------------------------------
-    VertexDeclarationPtr HardwareBufferManager::createVertexDeclaration(void)
+
+	VertexDeclarationPtr HardwareBufferManager::createVertexDeclaration(const VertexDeclaration::VertexElementList& elements)
     {
-        VertexDeclarationPtr decl = createVertexDeclarationImpl();
+        VertexDeclarationPtr decl = createVertexDeclarationImpl(elements);
 		decl->_setThisPtr(decl);
 		decl->initialize();
         return decl;
     }
-	//-----------------------------------------------------------------------
+
 	VertexBufferPtr HardwareBufferManager::createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut)
 	{
 		assert (numVerts > 0);
@@ -60,7 +32,7 @@ namespace BansheeEngine {
 		vbuf->initialize();
 		return vbuf;
 	}
-	//-----------------------------------------------------------------------
+
 	IndexBufferPtr HardwareBufferManager::createIndexBuffer(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage)
 	{
 		assert (numIndexes > 0);
@@ -71,7 +43,7 @@ namespace BansheeEngine {
 		return ibuf;
 
 	}
-	//-----------------------------------------------------------------------
+
 	GpuParamBlockBufferPtr HardwareBufferManager::createGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage)
 	{
 		GpuParamBlockBufferPtr paramBlockPtr = createGpuParamBlockBufferImpl();
@@ -80,7 +52,7 @@ namespace BansheeEngine {
 
 		return paramBlockPtr;
 	}
-	//-----------------------------------------------------------------------
+
 	GpuBufferPtr HardwareBufferManager::createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
 		GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
 	{
@@ -89,9 +61,9 @@ namespace BansheeEngine {
 		gbuf->initialize();
 		return gbuf;
 	}
-	//-----------------------------------------------------------------------
-	VertexDeclarationPtr HardwareBufferManager::createVertexDeclarationImpl(void)
+
+	VertexDeclarationPtr HardwareBufferManager::createVertexDeclarationImpl(const VertexDeclaration::VertexElementList& elements)
 	{
-		return cm_core_ptr<VertexDeclaration, PoolAlloc>(new (cm_alloc<VertexDeclaration, PoolAlloc>()) VertexDeclaration());
+		return cm_core_ptr<VertexDeclaration, PoolAlloc>(new (cm_alloc<VertexDeclaration, PoolAlloc>()) VertexDeclaration(elements));
 	}
 }

+ 1 - 158
CamelotCore/Source/CmVertexData.cpp

@@ -1,31 +1,3 @@
-/*
------------------------------------------------------------------------------
-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 "CmIndexData.h"
 #include "CmVertexData.h"
 #include "CmHardwareBufferManager.h"
@@ -36,24 +8,12 @@ THE SOFTWARE.
 
 namespace BansheeEngine 
 {
-	VertexData::VertexData(HardwareBufferManager* mgr)
-		:mOwnsDeclaration(true)
+	VertexData::VertexData()
 	{
-		mMgr = mgr ? mgr : HardwareBufferManager::instancePtr();
-		vertexDeclaration = mMgr->createVertexDeclaration();
 		vertexCount = 0;
 
 	}
 
-	VertexData::VertexData(VertexDeclarationPtr dcl)
-		:mOwnsDeclaration(false)
-	{
-		// this is a fallback rather than actively used
-		mMgr = HardwareBufferManager::instancePtr();
-		vertexDeclaration = dcl;
-		vertexCount = 0;
-	}
-
 	VertexData::~VertexData()
 	{
 	}
@@ -85,121 +45,4 @@ namespace BansheeEngine
 
 		return false;
 	}
-
-	void VertexData::convertPackedColour(
-		VertexElementType srcType, VertexElementType destType)
-	{
-		if (destType != VET_COLOR_ABGR && destType != VET_COLOR_ARGB)
-		{
-			CM_EXCEPT(InvalidParametersException,
-				"Invalid destType parameter");
-		}
-		if (srcType != VET_COLOR_ABGR && srcType != VET_COLOR_ARGB)
-		{
-			CM_EXCEPT(InvalidParametersException,
-				"Invalid srcType parameter");
-		}
-
-		for (auto iter = mVertexBuffers.begin(); iter != mVertexBuffers.end(); ++iter)
-		{
-			VertexDeclaration::VertexElementList elems = 
-				vertexDeclaration->findElementsBySource(iter->first);
-			bool conversionNeeded = false;
-			VertexDeclaration::VertexElementList::iterator elemi;
-			for (elemi = elems.begin(); elemi != elems.end(); ++elemi)
-			{
-				VertexElement& elem = *elemi;
-				if (elem.getType() == VET_COLOR || 
-					((elem.getType() == VET_COLOR_ABGR || elem.getType() == VET_COLOR_ARGB) 
-					&& elem.getType() != destType))
-				{
-					conversionNeeded = true;
-				}
-			}
-
-			if (conversionNeeded)
-			{
-				void* pBase = iter->second->lock(GBL_READ_WRITE);
-
-				for (UINT32 v = 0; v < iter->second->getNumVertices(); ++v)
-				{
-
-					for (elemi = elems.begin(); elemi != elems.end(); ++elemi)
-					{
-						VertexElement& elem = *elemi;
-						VertexElementType currType = (elem.getType() == VET_COLOR) ?
-							srcType : elem.getType();
-						if (elem.getType() == VET_COLOR || 
-							((elem.getType() == VET_COLOR_ABGR || elem.getType() == VET_COLOR_ARGB) 
-							&& elem.getType() != destType))
-						{
-							UINT32* pRGBA;
-							elem.baseVertexPointerToElement(pBase, &pRGBA);
-							VertexElement::convertColourValue(currType, destType, pRGBA);
-						}
-					}
-					pBase = static_cast<void*>(
-						static_cast<char*>(pBase) + iter->second->getVertexSize());
-				}
-				iter->second->unlock();
-
-				// Modify the elements to reflect the changed type
-				const VertexDeclaration::VertexElementList& allelems = 
-					vertexDeclaration->getElements();
-				VertexDeclaration::VertexElementList::const_iterator ai;
-				unsigned short elemIndex = 0;
-				for (ai = allelems.begin(); ai != allelems.end(); ++ai, ++elemIndex)
-				{
-					const VertexElement& elem = *ai;
-					if (elem.getType() == VET_COLOR || 
-						((elem.getType() == VET_COLOR_ABGR || elem.getType() == VET_COLOR_ARGB) 
-						&& elem.getType() != destType))
-					{
-						vertexDeclaration->modifyElement(elemIndex, 
-							elem.getStreamIdx(), elem.getOffset(), destType, 
-							elem.getSemantic(), elem.getSemanticIdx());
-					}
-				}
-			}
-		} // each buffer
-	}
-
-	void VertexCacheProfiler::profile(const IndexBufferPtr& indexBuffer)
-    {
-		if (indexBuffer->isLocked()) return;
-
-		UINT16 *shortbuffer = (UINT16 *)indexBuffer->lock(GBL_READ_ONLY);
-
-		if (indexBuffer->getType() == IndexBuffer::IT_16BIT)
-			for (unsigned int i = 0; i < indexBuffer->getNumIndexes(); ++i)
-				inCache(shortbuffer[i]);
-		else
-		{
-			UINT32 *buffer = (UINT32 *)shortbuffer;
-			for (unsigned int i = 0; i < indexBuffer->getNumIndexes(); ++i)
-				inCache(buffer[i]);
-		}
-
-		indexBuffer->unlock();
-	}
-
-	bool VertexCacheProfiler::inCache(unsigned int index)
-	{
-		for (unsigned int i = 0; i < buffersize; ++i)
-		{
-			if (index == cache[i])
-			{
-				hit++;
-				return true;
-			}
-		}
-
-		miss++;
-		cache[tail++] = index;
-		tail %= size;
-
-		if (buffersize < size) buffersize++;
-
-		return false;
-	}
 }

+ 6 - 3
CamelotCore/Source/CmVertexDataDesc.cpp

@@ -29,8 +29,6 @@ namespace BansheeEngine
 
 	VertexDeclarationPtr VertexDataDesc::createDeclaration() const
 	{
-		VertexDeclarationPtr declaration = HardwareBufferManager::instance().createVertexDeclaration();
-
 		UINT32 maxStreamIdx = getMaxStreamIdx();
 
 		UINT32 numStreams = maxStreamIdx + 1;
@@ -38,15 +36,20 @@ namespace BansheeEngine
 		for(UINT32 i = 0; i < numStreams; i++)
 			streamOffsets[i] = 0;
 
+		VertexDeclaration::VertexElementList declarationElements;
 		for(auto& vertElem : mVertexElements)
 		{
 			UINT32 streamIdx = vertElem.getStreamIdx();
-			declaration->addElement(streamIdx, streamOffsets[streamIdx], vertElem.getType(), vertElem.getSemantic(), vertElem.getSemanticIdx());
+
+			declarationElements.push_back(VertexElement(streamIdx, streamOffsets[streamIdx], vertElem.getType(),
+				vertElem.getSemantic(), vertElem.getSemanticIdx()));
+
 			streamOffsets[streamIdx] += vertElem.getSize();
 		}
 
 		cm_deleteN<ScratchAlloc>(streamOffsets, numStreams);
 
+		VertexDeclarationPtr declaration = HardwareBufferManager::instance().createVertexDeclaration(declarationElements);
 		return declaration;
 	}
 

+ 69 - 330
CamelotCore/Source/CmVertexDeclaration.cpp

@@ -6,18 +6,17 @@
 
 namespace BansheeEngine
 {
-	VertexElement::VertexElement(unsigned short source, UINT32 offset, 
-		VertexElementType theType, VertexElementSemantic semantic, unsigned short index)
-		: mSource(source), mOffset(offset), mType(theType), 
-		mSemantic(semantic), mIndex(index)
+	VertexElement::VertexElement(UINT16 source, UINT32 offset,
+		VertexElementType theType, VertexElementSemantic semantic, UINT16 index)
+		: mSource(source), mOffset(offset), mType(theType), mSemantic(semantic), mIndex(index)
 	{
 	}
-	//-----------------------------------------------------------------------------
+
 	UINT32 VertexElement::getSize(void) const
 	{
 		return getTypeSize(mType);
 	}
-	//-----------------------------------------------------------------------------
+
 	UINT32 VertexElement::getTypeSize(VertexElementType etype)
 	{
 		switch(etype)
@@ -45,9 +44,10 @@ namespace BansheeEngine
 		case VET_UBYTE4:
 			return sizeof(unsigned char)*4;
 		}
+
 		return 0;
 	}
-	//-----------------------------------------------------------------------------
+
 	unsigned short VertexElement::getTypeCount(VertexElementType etype)
 	{
 		switch (etype)
@@ -75,51 +75,11 @@ namespace BansheeEngine
 		case VET_UBYTE4:
 			return 4;
 		}
+
 		CM_EXCEPT(InvalidParametersException, "Invalid type");
 	}
-	//-----------------------------------------------------------------------------
-	VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType, 
-		unsigned short count)
-	{
-		switch (baseType)
-		{
-		case VET_FLOAT1:
-			switch(count)
-			{
-			case 1:
-				return VET_FLOAT1;
-			case 2:
-				return VET_FLOAT2;
-			case 3:
-				return VET_FLOAT3;
-			case 4:
-				return VET_FLOAT4;
-			default:
-				break;
-			}
-			break;
-		case VET_SHORT1:
-			switch(count)
-			{
-			case 1:
-				return VET_SHORT1;
-			case 2:
-				return VET_SHORT2;
-			case 3:
-				return VET_SHORT3;
-			case 4:
-				return VET_SHORT4;
-			default:
-				break;
-			}
-			break;
-		default:
-			break;
-		}
-		CM_EXCEPT(InvalidParametersException, "Invalid base type");
-	}
-	//--------------------------------------------------------------------------
-	VertexElementType VertexElement::getBestColourVertexElementType(void)
+
+	VertexElementType VertexElement::getBestColorVertexElementType()
 	{
 		// Use the current render system to determine if possible
 		if (BansheeEngine::RenderSystem::instancePtr())
@@ -138,338 +98,117 @@ namespace BansheeEngine
 
 		}
 	}
-	//--------------------------------------------------------------------------
-	void VertexElement::convertColourValue(VertexElementType srcType, 
-		VertexElementType dstType, UINT32* ptr)
-	{
-		if (srcType == dstType)
-			return;
-
-		// Conversion between ARGB and ABGR is always a case of flipping R/B
-		*ptr = 
-			((*ptr&0x00FF0000)>>16)|((*ptr&0x000000FF)<<16)|(*ptr&0xFF00FF00);				
-	}
-	//--------------------------------------------------------------------------
-	UINT32 VertexElement::convertColourValue(const Color& src, 
-		VertexElementType dst)
-	{
-		switch(dst)
-		{
-#if CM_PLATFORM == CM_PLATFORM_WIN32
-		default:
-#endif
-		case VET_COLOR_ARGB:
-			return src.getAsBGRA();
-#if CM_PLATFORM != CM_PLATFORM_WIN32
-		default:
-#endif
-		case VET_COLOR_ABGR: 
-			return src.getAsRGBA();
-		};
 
-	}
-	//-----------------------------------------------------------------------------
-	VertexElementType VertexElement::getBaseType(VertexElementType multiType)
+	bool VertexElement::operator== (const VertexElement& rhs) const
 	{
-		switch (multiType)
+		if (mType != rhs.mType || mIndex != rhs.mIndex || mOffset != rhs.mOffset ||
+			mSemantic != rhs.mSemantic || mSource != rhs.mSource)
 		{
-		case VET_FLOAT1:
-		case VET_FLOAT2:
-		case VET_FLOAT3:
-		case VET_FLOAT4:
-			return VET_FLOAT1;
-		case VET_COLOR:
-			return VET_COLOR;
-		case VET_COLOR_ABGR:
-			return VET_COLOR_ABGR;
-		case VET_COLOR_ARGB:
-			return VET_COLOR_ARGB;
-		case VET_SHORT1:
-		case VET_SHORT2:
-		case VET_SHORT3:
-		case VET_SHORT4:
-			return VET_SHORT1;
-		case VET_UBYTE4:
-			return VET_UBYTE4;
-		};
-		// To keep compiler happy
-		return VET_FLOAT1;
+			return false;
+		}
+		else
+			return true;
 	}
-	//-----------------------------------------------------------------------------
-	size_t VertexElement::calculateHash() const
+
+	bool VertexElement::operator!= (const VertexElement& rhs) const
 	{
-		size_t hash = 0;
-		hash_combine(hash, mSource);
-		hash_combine(hash, mOffset);
-		hash_combine(hash, mType);
-		hash_combine(hash, mSemantic);
-		hash_combine(hash, mIndex);
-
-		return hash;
+		return !(*this == rhs);
 	}
-	//-----------------------------------------------------------------------------
-	VertexDeclaration::VertexDeclaration()
-		:mHash(0)
+
+	VertexDeclaration::VertexDeclaration(const VertexElementList& elements)
 	{
+		for (auto& elem : elements)
+		{
+			VertexElementType type = elem.getType();
+
+			if (elem.getType() == VET_COLOR)
+				type = VertexElement::getBestColorVertexElementType();
+
+			mElementList.push_back(VertexElement(elem.getStreamIdx(), elem.getOffset(), type, elem.getSemantic(), elem.getSemanticIdx()));
+		}
 	}
-	//-----------------------------------------------------------------------------
+
 	VertexDeclaration::~VertexDeclaration()
 	{
 	}
-	//-----------------------------------------------------------------------------
-	const VertexDeclaration::VertexElementList& VertexDeclaration::getElements(void) const
-	{
-		return mElementList;
-	}
-	//-----------------------------------------------------------------------------
-	const VertexElement& VertexDeclaration::addElement(unsigned short source, 
-		UINT32 offset, VertexElementType theType,
-		VertexElementSemantic semantic, unsigned short index)
+
+	bool VertexDeclaration::operator== (const VertexDeclaration& rhs) const
 	{
-		// Refine colour type to a specific type
-		if (theType == VET_COLOR)
-		{
-			theType = VertexElement::getBestColourVertexElementType();
-		}
-		mElementList.push_back(
-			VertexElement(source, offset, theType, semantic, index)
-			);
+		if (mElementList.size() != rhs.mElementList.size())
+			return false;
 
-		recalculateHash();
+		auto myIter = mElementList.begin();
+		auto theirIter = rhs.mElementList.begin();
 
-		return mElementList.back();
-	}
-	//-----------------------------------------------------------------------------
-	const VertexElement& VertexDeclaration::insertElement(unsigned short atPosition,
-		unsigned short source, UINT32 offset, VertexElementType theType,
-		VertexElementSemantic semantic, unsigned short index)
-	{
-		if (atPosition >= mElementList.size())
+		for (; myIter != mElementList.end() && theirIter != rhs.mElementList.end(); ++myIter, ++theirIter)
 		{
-			return addElement(source, offset, theType, semantic, index);
+			if (!(*myIter == *theirIter))
+				return false;
 		}
 
-		VertexElementList::iterator i = mElementList.begin();
-		for (unsigned short n = 0; n < atPosition; ++n)
-			++i;
-
-		i = mElementList.insert(i, 
-			VertexElement(source, offset, theType, semantic, index));
-
-		recalculateHash();
-
-		return *i;
+		return true;
+	}
 
+	bool VertexDeclaration::operator!= (const VertexDeclaration& rhs) const
+	{
+		return !(*this == rhs);
 	}
-	//-----------------------------------------------------------------------------
-	const VertexElement* VertexDeclaration::getElement(unsigned short index)
+
+	const VertexElement* VertexDeclaration::getElement(UINT16 index)
 	{
 		assert(index < mElementList.size() && "Index out of bounds");
 
-		VertexElementList::iterator i = mElementList.begin();
-		for (unsigned short n = 0; n < index; ++n)
-			++i;
+		auto iter = mElementList.begin();
+		for (UINT16 i = 0; i < index; ++i)
+			++iter;
 
-		return &(*i);
-
-	}
-	//-----------------------------------------------------------------------------
-	void VertexDeclaration::removeElement(unsigned short elem_index)
-	{
-		assert(elem_index < mElementList.size() && "Index out of bounds");
-		VertexElementList::iterator i = mElementList.begin();
-		for (unsigned short n = 0; n < elem_index; ++n)
-			++i;
-		mElementList.erase(i);
+		return &(*iter);
 
-		recalculateHash();
 	}
-	//-----------------------------------------------------------------------------
-	void VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
+	
+	const VertexElement* VertexDeclaration::findElementBySemantic(VertexElementSemantic sem, UINT16 index)
 	{
-		VertexElementList::iterator ei, eiend;
-		eiend = mElementList.end();
-		for (ei = mElementList.begin(); ei != eiend; ++ei)
+		for (auto& elem : mElementList)
 		{
-			if (ei->getSemantic() == semantic && ei->getSemanticIdx() == index)
+			if (elem.getSemantic() == sem && elem.getSemanticIdx() == index)
 			{
-				mElementList.erase(ei);
-				break;
+				return &elem;
 			}
 		}
 
-		recalculateHash();
+		return nullptr;
 	}
-	//-----------------------------------------------------------------------------
-	void VertexDeclaration::removeAllElements(void)
-	{
-		mElementList.clear();
 
-		recalculateHash();
-	}
-	//-----------------------------------------------------------------------------
-	void VertexDeclaration::modifyElement(unsigned short elem_index, 
-		unsigned short source, UINT32 offset, VertexElementType theType,
-		VertexElementSemantic semantic, unsigned short index)
+	VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource(UINT16 source)
 	{
-		assert(elem_index < mElementList.size() && "Index out of bounds");
-		VertexElementList::iterator i = mElementList.begin();
-		std::advance(i, elem_index);
-		(*i) = VertexElement(source, offset, theType, semantic, index);
+		VertexElementList retList;
 
-		recalculateHash();
-	}
-	//-----------------------------------------------------------------------------
-	const VertexElement* VertexDeclaration::findElementBySemantic(
-		VertexElementSemantic sem, unsigned short index)
-	{
-		VertexElementList::const_iterator ei, eiend;
-		eiend = mElementList.end();
-		for (ei = mElementList.begin(); ei != eiend; ++ei)
+		for (auto& elem : mElementList)
 		{
-			if (ei->getSemantic() == sem && ei->getSemanticIdx() == index)
+			if (elem.getStreamIdx() == source)
 			{
-				return &(*ei);
+				retList.push_back(elem);
 			}
 		}
 
-		return NULL;
-	}
-	//-----------------------------------------------------------------------------
-	VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource(
-		unsigned short source)
-	{
-		VertexElementList retList;
-		VertexElementList::const_iterator ei, eiend;
-		eiend = mElementList.end();
-		for (ei = mElementList.begin(); ei != eiend; ++ei)
-		{
-			if (ei->getStreamIdx() == source)
-			{
-				retList.push_back(*ei);
-			}
-		}
 		return retList;
 	}
-	//-----------------------------------------------------------------------------
-	UINT32 VertexDeclaration::getVertexSize(unsigned short source)
-	{
-		VertexElementList::const_iterator i, iend;
-		iend = mElementList.end();
-		UINT32 sz = 0;
-
-		for (i = mElementList.begin(); i != iend; ++i)
-		{
-			if (i->getStreamIdx() == source)
-			{
-				sz += i->getSize();
 
-			}
-		}
-		return sz;
-	}
-	//-----------------------------------------------------------------------------
-	VertexDeclarationPtr VertexDeclaration::clone(HardwareBufferManager* mgr)
+	UINT32 VertexDeclaration::getVertexSize(UINT16 source)
 	{
-		HardwareBufferManager* pManager = mgr ? mgr : HardwareBufferManager::instancePtr(); 
-		VertexDeclarationPtr ret = pManager->createVertexDeclaration();
-
-		VertexElementList::const_iterator i, iend;
-		iend = mElementList.end();
-		for (i = mElementList.begin(); i != iend; ++i)
-		{
-			ret->addElement(i->getStreamIdx(), i->getOffset(), i->getType(), i->getSemantic(), i->getSemanticIdx());
-		}
+		UINT32 size = 0;
 
-		ret->mHash = mHash;
-		return ret;
-	}
-	//-----------------------------------------------------------------------------
-	// Sort routine for VertexElement
-	bool VertexDeclaration::vertexElementLess(const VertexElement& e1, const VertexElement& e2)
-	{
-		// Sort by source first
-		if (e1.getStreamIdx() < e2.getStreamIdx())
+		for (auto& elem : mElementList)
 		{
-			return true;
-		}
-		else if (e1.getStreamIdx() == e2.getStreamIdx())
-		{
-			// Use ordering of semantics to sort
-			if (e1.getSemantic() < e2.getSemantic())
-			{
-				return true;
-			}
-			else if (e1.getSemantic() == e2.getSemantic())
+			if (elem.getStreamIdx() == source)
 			{
-				// Use index to sort
-				if (e1.getSemanticIdx() < e2.getSemanticIdx())
-				{
-					return true;
-				}
+				size += elem.getSize();
 			}
 		}
-		return false;
-	}
-	void VertexDeclaration::sort(void)
-	{
-		mElementList.sort(VertexDeclaration::vertexElementLess);
-	}
-	//-----------------------------------------------------------------------------
-	void VertexDeclaration::closeGapsInSource(void)
-	{
-		if (mElementList.empty())
-			return;
-
-		// Sort first
-		sort();
-
-		VertexElementList::iterator i, iend;
-		iend = mElementList.end();
-		unsigned short targetIdx = 0;
-		unsigned short lastIdx = getElement(0)->getStreamIdx();
-		unsigned short c = 0;
-		for (i = mElementList.begin(); i != iend; ++i, ++c)
-		{
-			VertexElement& elem = *i;
-			if (lastIdx != elem.getStreamIdx())
-			{
-				targetIdx++;
-				lastIdx = elem.getStreamIdx();
-			}
-			if (targetIdx != elem.getStreamIdx())
-			{
-				modifyElement(c, targetIdx, elem.getOffset(), elem.getType(), 
-					elem.getSemantic(), elem.getSemanticIdx());
-			}
 
-		}
+		return size;
 	}
-	//-----------------------------------------------------------------------------
-	unsigned short VertexDeclaration::getMaxSource(void) const
-	{
-		VertexElementList::const_iterator i, iend;
-		iend = mElementList.end();
-		unsigned short ret = 0;
-		for (i = mElementList.begin(); i != iend; ++i)
-		{
-			if (i->getStreamIdx() > ret)
-			{
-				ret = i->getStreamIdx();
-			}
 
-		}
-		return ret;
-	}
-	//----------------------------------------------------------------------------
-	void VertexDeclaration::recalculateHash()
-	{
-		mHash = 0;
-		for(auto iter = mElementList.begin(); iter != mElementList.end(); ++iter)
-		{
-			hash_combine(mHash, iter->calculateHash());
-		}
-	}
 	/************************************************************************/
 	/* 								SERIALIZATION                      		*/
 	/************************************************************************/

+ 2 - 1
CamelotD3D11RenderSystem/Include/CmD3D11HLSLParamParser.h

@@ -1,13 +1,14 @@
 #pragma once
 
 #include "CmD3D11Prerequisites.h"
+#include "CmVertexDeclaration.h"
 
 namespace BansheeEngine
 {
 	class D3D11HLSLParamParser
 	{
 	public:
-		void parse(ID3DBlob* microcode, GpuParamDesc& desc, VertexDeclarationPtr& inputParams);
+		void parse(ID3DBlob* microcode, GpuParamDesc& desc, VertexDeclaration::VertexElementList* inputParams);
 
 	private:
 		void parseBuffer(ID3D11ShaderReflectionConstantBuffer* bufferReflection, GpuParamDesc& desc);

+ 1 - 3
CamelotD3D11RenderSystem/Include/CmD3D11InputLayoutManager.h

@@ -10,10 +10,8 @@ namespace BansheeEngine
 	public:
 		struct VertexDeclarationKey
 		{
-			size_t bufferDeclHash;
+			UINT64 vertxDeclId;
 			UINT32 vertexProgramId;
-
-			List<VertexElement>* bufferDeclElements;
 		};
 
 		class HashFunc 

+ 9 - 3
CamelotD3D11RenderSystem/Source/CmD3D11GpuProgram.cpp

@@ -127,11 +127,17 @@ namespace BansheeEngine
 		assert(microcode != nullptr);
 
 		D3D11HLSLParamParser parser;
-
 		if (mType == GPT_VERTEX_PROGRAM)
-			mInputDeclaration = HardwareBufferManager::instance().createVertexDeclaration();
+		{
+			VertexDeclaration::VertexElementList inputParams;
+			parser.parse(microcode, mParametersDesc, &inputParams);
 
-		parser.parse(microcode, mParametersDesc, mInputDeclaration);
+			mInputDeclaration = HardwareBufferManager::instance().createVertexDeclaration(inputParams);
+		}
+		else
+		{
+			parser.parse(microcode, mParametersDesc, nullptr);
+		}
 	}
 
 	GpuParamsPtr D3D11GpuProgram::createParameters()

+ 5 - 5
CamelotD3D11RenderSystem/Source/CmD3D11HLSLParamParser.cpp

@@ -6,7 +6,7 @@
 
 namespace BansheeEngine
 {
-	void D3D11HLSLParamParser::parse(ID3DBlob* microcode, GpuParamDesc& desc, VertexDeclarationPtr& inputParams)
+	void D3D11HLSLParamParser::parse(ID3DBlob* microcode, GpuParamDesc& desc, VertexDeclaration::VertexElementList* inputParams)
 	{
 		const char* commentString = nullptr;
 		ID3DBlob* pIDisassembly = nullptr;
@@ -33,7 +33,7 @@ namespace BansheeEngine
 		if (FAILED(hr))
 			CM_EXCEPT(RenderingAPIException, "Cannot reflect D3D11 high-level shader.");
 
-		if(inputParams != nullptr)
+		if (inputParams != nullptr)
 		{
 			D3D11_SIGNATURE_PARAMETER_DESC inputParamDesc;
 			for (UINT32 i = 0; i < shaderDesc.InputParameters; i++)
@@ -43,8 +43,8 @@ namespace BansheeEngine
 				if (FAILED(hr))
 					CM_EXCEPT(RenderingAPIException, "Cannot get input param desc with index: " + toString(i));
 
-				inputParams->addElement(inputParamDesc.Stream, inputParamDesc.Register, 
-					D3D11Mappings::getInputType(inputParamDesc.ComponentType), D3D11Mappings::get(inputParamDesc.SemanticName), inputParamDesc.SemanticIndex);
+				inputParams->push_back(VertexElement(inputParamDesc.Stream, inputParamDesc.Register,
+					D3D11Mappings::getInputType(inputParamDesc.ComponentType), D3D11Mappings::get(inputParamDesc.SemanticName), inputParamDesc.SemanticIndex));
 			}
 		}
 
@@ -68,7 +68,7 @@ namespace BansheeEngine
 		}
 
 		// TODO - Parse:
-		//  - Tex arrays,  RW tex arrays and MS textures
+		//  - Tex arrays, RW tex arrays and MS textures
 		//	- UINT8, UINT and double values
 
 		shaderReflection->Release();

+ 4 - 25
CamelotD3D11RenderSystem/Source/CmD3D11InputLayoutManager.cpp

@@ -13,7 +13,7 @@ namespace BansheeEngine
 		(const D3D11InputLayoutManager::VertexDeclarationKey &key) const
 	{
 		size_t hash = 0;
-		hash_combine(hash, key.bufferDeclHash);
+		hash_combine(hash, key.vertxDeclId);
 		hash_combine(hash, key.vertexProgramId);
 
 		return hash;
@@ -23,20 +23,9 @@ namespace BansheeEngine
 		(const D3D11InputLayoutManager::VertexDeclarationKey &a, const D3D11InputLayoutManager::VertexDeclarationKey &b) const
 		
 	{
-		if(a.bufferDeclElements->size() != b.bufferDeclElements->size())
+		if (a.vertxDeclId != b.vertxDeclId)
 			return false;
 
-		{
-			auto iter1 = a.bufferDeclElements->begin();
-			auto iter2 = b.bufferDeclElements->begin();
-
-			for(; iter1 != a.bufferDeclElements->end(); ++iter1, ++iter2)
-			{
-				if((*iter1) != (*iter2))
-					return false;
-			}
-		}
-
 		if(a.vertexProgramId != b.vertexProgramId)
 			return false;
 
@@ -55,7 +44,6 @@ namespace BansheeEngine
 		{
 			auto firstElem = mInputLayoutMap.begin();
 
-			cm_delete<PoolAlloc>(firstElem->first.bufferDeclElements);
 			SAFE_RELEASE(firstElem->second->inputLayout);
 			cm_delete<PoolAlloc>(firstElem->second);
 
@@ -66,8 +54,7 @@ namespace BansheeEngine
 	ID3D11InputLayout* D3D11InputLayoutManager::retrieveInputLayout(VertexDeclarationPtr vertexShaderDecl, VertexDeclarationPtr vertexBufferDecl, D3D11GpuProgram& vertexProgram)
 	{
 		VertexDeclarationKey pair;
-		pair.bufferDeclHash = vertexBufferDecl->getHash();
-		pair.bufferDeclElements = const_cast<List<VertexElement>*>(&vertexBufferDecl->getElements());
+		pair.vertxDeclId = vertexBufferDecl->getInternalID();
 		pair.vertexProgramId = vertexProgram.getProgramId();
 
 		auto iterFind = mInputLayoutMap.find(pair);
@@ -133,15 +120,9 @@ namespace BansheeEngine
 
 		// Create key and add to the layout map
 		VertexDeclarationKey pair;
-		pair.bufferDeclHash = vertexBufferDecl->getHash();
-
-		List<VertexElement>* bufferDeclElements = cm_new<List<VertexElement>, PoolAlloc>(); 
-		pair.bufferDeclElements = bufferDeclElements;
+		pair.vertxDeclId = vertexBufferDecl->getInternalID();
 		pair.vertexProgramId = vertexProgram.getProgramId();
 
-		for(auto iter = vertexBufferDecl->getElements().begin(); iter != vertexBufferDecl->getElements().end(); ++iter)
-			bufferDeclElements->push_back(*iter);
-
 		mInputLayoutMap[pair] = newEntry;
 	}
 
@@ -160,13 +141,11 @@ namespace BansheeEngine
 		for(auto iter = mInputLayoutMap.begin(); iter != mInputLayoutMap.end(); ++iter)
 			leastFrequentlyUsedMap[iter->second->lastUsedIdx] = iter->first;
 
-
 		UINT32 elemsRemoved = 0;
 		for(auto iter = leastFrequentlyUsedMap.begin(); iter != leastFrequentlyUsedMap.end(); ++iter)
 		{
 			auto inputLayoutIter = mInputLayoutMap.find(iter->second);
 
-			cm_delete<PoolAlloc>(inputLayoutIter->first.bufferDeclElements);
 			SAFE_RELEASE(inputLayoutIter->second->inputLayout);
 			cm_delete<PoolAlloc>(inputLayoutIter->second);
 

+ 1 - 4
CamelotD3D11RenderSystem/Source/CmD3D11Mappings.cpp

@@ -361,10 +361,7 @@ namespace BansheeEngine
 			return "BLENDWEIGHT";
 			break;
 		case VES_COLOR:
-			return "COLOR"; // NB index will differentiate
-			break;
-		case VES_SPECULAR:
-			return "COLOR"; // NB index will differentiate
+			return "COLOR";
 			break;
 		case VES_NORMAL:
 			return "NORMAL";

+ 3 - 34
CamelotD3D9Renderer/Include/CmD3D9HardwareBufferManager.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 __D3D9HARWAREBUFFERMANAGER_H__
-#define __D3D9HARWAREBUFFERMANAGER_H__
+#pragma once
 
 #include "CmD3D9Prerequisites.h"
 #include "CmHardwareBufferManager.h"
@@ -42,7 +14,7 @@ namespace BansheeEngine {
 
 	protected:     
 		/// Internal method for creates a new vertex declaration, may be overridden by certain rendering APIs
-		VertexDeclarationPtr createVertexDeclarationImpl();
+		VertexDeclarationPtr createVertexDeclarationImpl(const VertexDeclaration::VertexElementList& elements);
 
 		/**
 		 * @copydoc HardwareBufferManager::createVertexBufferImpl
@@ -65,7 +37,4 @@ namespace BansheeEngine {
 		GpuBufferPtr createGpuBufferImpl(UINT32 elementCount, UINT32 elementSize, 
 			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
     };
-}
-
-
-#endif
+}

+ 6 - 60
CamelotD3D9Renderer/Include/CmD3D9VertexDeclaration.h

@@ -1,68 +1,17 @@
-/*
------------------------------------------------------------------------------
-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 __D3D9VERTEXDECLARATION_H__
-#define __D3D9VERTEXDECLARATION_H__
+#pragma once
 
 #include "CmD3D9Prerequisites.h"
 #include "CmVertexDeclaration.h"
 #include "CmD3D9Resource.h"
 
-namespace BansheeEngine { 
-
+namespace BansheeEngine 
+{ 
     /** Specialisation of VertexDeclaration for D3D9 */
     class CM_D3D9_EXPORT D3D9VertexDeclaration : public VertexDeclaration, public D3D9Resource
     {
     public:
         ~D3D9VertexDeclaration();
         
-        /** See VertexDeclaration */
-        const VertexElement& addElement(unsigned short source, UINT32 offset, VertexElementType theType,
-            VertexElementSemantic semantic, unsigned short index = 0);
-
-        /** See VertexDeclaration */
-        const VertexElement& insertElement(unsigned short atPosition,
-            unsigned short source, UINT32 offset, VertexElementType theType,
-            VertexElementSemantic semantic, unsigned short index = 0);
-
-        /** See VertexDeclaration */
-        void removeElement(unsigned short elem_index);
-		
-		/** See VertexDeclaration */
-		void removeElement(VertexElementSemantic semantic, unsigned short index = 0);
-
-		/** See VertexDeclaration */
-		void removeAllElements(void);
-
-
-        /** See VertexDeclaration */
-        void modifyElement(unsigned short elem_index, unsigned short source, UINT32 offset, VertexElementType theType,
-            VertexElementSemantic semantic, unsigned short index = 0);
-
 		// Called immediately after the Direct3D device has been created.
 		virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device);
 
@@ -70,12 +19,12 @@ namespace BansheeEngine {
 		virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device);
 
         /** Gets the D3D9-specific vertex declaration. */
-        IDirect3DVertexDeclaration9* getD3DVertexDeclaration(void);
+        IDirect3DVertexDeclaration9* getD3DVertexDeclaration();
 
 	protected:
 		friend class D3D9HardwareBufferManager;
 
-		D3D9VertexDeclaration();
+		D3D9VertexDeclaration(const VertexDeclaration::VertexElementList& elements);
 
 		void releaseDeclaration();
 
@@ -90,7 +39,4 @@ namespace BansheeEngine {
 
 		DeviceToDeclarationMap		mMapDeviceToDeclaration;
     };
-
-}
-
-#endif
+}

+ 8 - 36
CamelotD3D9Renderer/Source/CmD3D9HardwareBufferManager.cpp

@@ -1,30 +1,3 @@
-/*
------------------------------------------------------------------------------
-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 "CmD3D9HardwareBufferManager.h"
 #include "CmD3D9VertexBuffer.h"
 #include "CmD3D9IndexBuffer.h"
@@ -35,15 +8,14 @@ THE SOFTWARE.
 
 namespace BansheeEngine 
 {
-    //-----------------------------------------------------------------------
     D3D9HardwareBufferManager::D3D9HardwareBufferManager()       
     {
     }
-    //-----------------------------------------------------------------------
+
     D3D9HardwareBufferManager::~D3D9HardwareBufferManager()
     {
     }
-    //-----------------------------------------------------------------------
+
     VertexBufferPtr D3D9HardwareBufferManager::createVertexBufferImpl(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut)
     {
 		assert (numVerts > 0);
@@ -51,7 +23,7 @@ namespace BansheeEngine
         D3D9VertexBuffer* buffer = new (cm_alloc<D3D9VertexBuffer, PoolAlloc>()) D3D9VertexBuffer(this, vertexSize, numVerts, usage, false);
 		return cm_core_ptr<D3D9VertexBuffer, PoolAlloc>(buffer);
     }
-    //-----------------------------------------------------------------------
+
 	IndexBufferPtr D3D9HardwareBufferManager::createIndexBufferImpl(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage)
     {
 		assert (numIndexes > 0);
@@ -59,23 +31,23 @@ namespace BansheeEngine
 		D3D9IndexBuffer* buffer = new (cm_alloc<D3D9IndexBuffer, PoolAlloc>()) D3D9IndexBuffer(this, itype, numIndexes, usage, false);
 		return cm_core_ptr<D3D9IndexBuffer, PoolAlloc>(buffer);
     }
-	//-----------------------------------------------------------------------
+
 	GpuParamBlockBufferPtr D3D9HardwareBufferManager::createGpuParamBlockBufferImpl()
 	{
 		GpuParamBlockBuffer* paramBlockBuffer = new (cm_alloc<GenericGpuParamBlockBuffer, PoolAlloc>()) GenericGpuParamBlockBuffer();
 		return cm_core_ptr<GpuParamBlockBuffer, PoolAlloc>(paramBlockBuffer);
 	}
-	//-----------------------------------------------------------------------
+
 	GpuBufferPtr D3D9HardwareBufferManager::createGpuBufferImpl(UINT32 elementCount, UINT32 elementSize, 
 		GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter)
 	{
 		D3D9GpuBuffer* buffer = new (cm_alloc<D3D9GpuBuffer, PoolAlloc>()) D3D9GpuBuffer(elementCount, elementSize, type, usage, randomGpuWrite, useCounter);
 		return cm_core_ptr<D3D9GpuBuffer, PoolAlloc>(buffer);
 	}
-    //-----------------------------------------------------------------------
-    VertexDeclarationPtr D3D9HardwareBufferManager::createVertexDeclarationImpl(void)
+
+	VertexDeclarationPtr D3D9HardwareBufferManager::createVertexDeclarationImpl(const VertexDeclaration::VertexElementList& elements)
     {
-        D3D9VertexDeclaration* decl = new (cm_alloc<D3D9VertexDeclaration, PoolAlloc>()) D3D9VertexDeclaration();
+		D3D9VertexDeclaration* decl = new (cm_alloc<D3D9VertexDeclaration, PoolAlloc>()) D3D9VertexDeclaration(elements);
 		return cm_core_ptr<D3D9VertexDeclaration, PoolAlloc>(decl);
     }
 }

+ 1 - 4
CamelotD3D9Renderer/Source/CmD3D9Mappings.cpp

@@ -400,10 +400,7 @@ namespace BansheeEngine
 			return D3DDECLUSAGE_BLENDWEIGHT;
 			break;
 		case VES_COLOR:
-			return D3DDECLUSAGE_COLOR; // NB index will differentiate
-			break;
-		case VES_SPECULAR:
-			return D3DDECLUSAGE_COLOR; // NB index will differentiate
+			return D3DDECLUSAGE_COLOR;
 			break;
 		case VES_NORMAL:
 			return D3DDECLUSAGE_NORMAL;

+ 10 - 62
CamelotD3D9Renderer/Source/CmD3D9VertexDeclaration.cpp

@@ -31,73 +31,27 @@ THE SOFTWARE.
 #include "CmD3D9RenderSystem.h"
 #include "CmD3D9ResourceManager.h"
 
-namespace BansheeEngine {
+namespace BansheeEngine 
+{
+	D3D9VertexDeclaration::D3D9VertexDeclaration(const VertexDeclaration::VertexElementList& elements)
+		:VertexDeclaration(elements)
+    { }
 
-    //-----------------------------------------------------------------------
-    D3D9VertexDeclaration::D3D9VertexDeclaration()         
-    {
-
-    }
-    //-----------------------------------------------------------------------
     D3D9VertexDeclaration::~D3D9VertexDeclaration()
     {    }
-	//-----------------------------------------------------------------------
+
 	void D3D9VertexDeclaration::destroy_internal()
 	{
 		releaseDeclaration();
 
 		VertexDeclaration::destroy_internal();
 	}
-    //-----------------------------------------------------------------------
-    const VertexElement& D3D9VertexDeclaration::addElement(unsigned short source, 
-        UINT32 offset, VertexElementType theType,
-        VertexElementSemantic semantic, unsigned short index)
-    {
-        releaseDeclaration();   
-        return VertexDeclaration::addElement(source, offset, theType, semantic, index);
-    }
-    //-----------------------------------------------------------------------------
-    const VertexElement& D3D9VertexDeclaration::insertElement(unsigned short atPosition,
-        unsigned short source, UINT32 offset, VertexElementType theType,
-        VertexElementSemantic semantic, unsigned short index)
-    {
-        releaseDeclaration();   
-        return VertexDeclaration::insertElement(atPosition, source, offset, theType, semantic, index);
-    }
-    //-----------------------------------------------------------------------
-    void D3D9VertexDeclaration::removeElement(unsigned short elem_index)
-    {
-        VertexDeclaration::removeElement(elem_index);
-        releaseDeclaration();   
-    }
-	//-----------------------------------------------------------------------
-	void D3D9VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
-	{
-		VertexDeclaration::removeElement(semantic, index);
-		releaseDeclaration();   
-	}
-	//-----------------------------------------------------------------------
-	void D3D9VertexDeclaration::removeAllElements(void)
-	{
-		VertexDeclaration::removeAllElements();
-		releaseDeclaration();   
-	}
-    //-----------------------------------------------------------------------
-    void D3D9VertexDeclaration::modifyElement(unsigned short elem_index, 
-        unsigned short source, UINT32 offset, VertexElementType theType,
-        VertexElementSemantic semantic, unsigned short index)
-    {
-        VertexDeclaration::modifyElement(elem_index, source, offset, theType, semantic, index);
-		releaseDeclaration();       
-    }
 
-	 //-----------------------------------------------------------------------
 	void D3D9VertexDeclaration::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
 	{
 		
 	}
 
-	 //-----------------------------------------------------------------------
 	void D3D9VertexDeclaration::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
 	{
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
@@ -111,8 +65,7 @@ namespace BansheeEngine {
 		}
 	}
 
-    //-----------------------------------------------------------------------
-    IDirect3DVertexDeclaration9* D3D9VertexDeclaration::getD3DVertexDeclaration(void)
+    IDirect3DVertexDeclaration9* D3D9VertexDeclaration::getD3DVertexDeclaration()
     {
 		IDirect3DDevice9* pCurDevice   = D3D9RenderSystem::getActiveD3D9Device();
 		DeviceToDeclarationIterator it = mMapDeviceToDeclaration.find(pCurDevice);
@@ -133,13 +86,8 @@ namespace BansheeEngine {
 				d3delems[idx].Stream = i->getStreamIdx();
 				d3delems[idx].Type = D3D9Mappings::get(i->getType());
 				d3delems[idx].Usage = D3D9Mappings::get(i->getSemantic());
-				// NB force index if colours since D3D uses the same usage for 
-				// diffuse & specular
-				if (i->getSemantic() == VES_SPECULAR)
-				{
-					d3delems[idx].UsageIndex = 1;
-				}
-				else if (i->getSemantic() == VES_COLOR)
+
+				if (i->getSemantic() == VES_COLOR)
 				{
 					d3delems[idx].UsageIndex = 0;
 				}
@@ -177,7 +125,7 @@ namespace BansheeEngine {
 		
         return lpVertDecl;
     }
-    //-----------------------------------------------------------------------
+
 	void D3D9VertexDeclaration::releaseDeclaration()
 	{
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION

+ 1 - 1
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -1321,7 +1321,7 @@ namespace BansheeEngine
 			auto iterFind = mBoundVertexBuffers.find(elem->getStreamIdx());
 
 			if(iterFind == mBoundVertexBuffers.end() || iterFind->second == nullptr)
-				continue; // skip unbound elements
+				continue; // Skip unbound elements
 
 			VertexBufferPtr vertexBuffer = iterFind->second;
 

+ 6 - 3
CamelotGLRenderer/Source/GLSL/include/CmGLSLParamParser.h

@@ -45,7 +45,7 @@ namespace BansheeEngine
 	{
 	public:
 		void buildUniformDescriptions(GLuint glProgram, GpuParamDesc& returnParamDesc);
-		void buildVertexDeclaration(GLuint glProgram, VertexDeclaration& declaration);
+		VertexDeclaration::VertexElementList buildVertexDeclaration(GLuint glProgram);
 
 	private:
 		void determineParamInfo(GpuParamDataDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex);
@@ -60,7 +60,7 @@ namespace BansheeEngine
 		VertexElementType glTypeToAttributeType(GLenum glType);
 	};
 
-	void GLSLParamParser::buildVertexDeclaration(GLuint glProgram, VertexDeclaration& declaration)
+	VertexDeclaration::VertexElementList GLSLParamParser::buildVertexDeclaration(GLuint glProgram)
 	{
 		GLint numAttributes = 0;
 		glGetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTES, &numAttributes);
@@ -70,6 +70,7 @@ namespace BansheeEngine
 
 		GLchar* attributeName = (GLchar*)cm_alloc<ScratchAlloc>(sizeof(GLchar) * maxNameSize);
 
+		VertexDeclaration::VertexElementList elementList;
 		for(GLint i = 0; i < numAttributes; i++)
 		{
 			GLint attribSize = 0;
@@ -82,7 +83,7 @@ namespace BansheeEngine
 			{
 				VertexElementType type = glTypeToAttributeType(attribType);
 
-				declaration.addElement(0, i, type, semantic, index);
+				elementList.push_back(VertexElement(0, i, type, semantic, index));
 			}
 			else
 			{
@@ -91,6 +92,8 @@ namespace BansheeEngine
 		}
 
 		cm_free<ScratchAlloc>(attributeName);
+
+		return elementList;
 	}
 
 	VertexElementType GLSLParamParser::glTypeToAttributeType(GLenum glType)

+ 6 - 3
CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp

@@ -87,8 +87,6 @@ namespace BansheeEngine {
 			return;
 		}
 
-		mVertexDeclaration = HardwareBufferManager::instance().createVertexDeclaration();
-
 		// only create a shader object if glsl is supported
 		GLenum shaderType = 0x0000;
 		switch (mType)
@@ -196,7 +194,12 @@ namespace BansheeEngine {
 		{
 			GLSLParamParser paramParser;
 			paramParser.buildUniformDescriptions(mGLHandle, mParametersDesc);
-			paramParser.buildVertexDeclaration(mGLHandle, *mVertexDeclaration);
+
+			if (mType == GPT_VERTEX_PROGRAM)
+			{
+				VertexDeclaration::VertexElementList elementList = paramParser.buildVertexDeclaration(mGLHandle);
+				mVertexDeclaration = HardwareBufferManager::instance().createVertexDeclaration(elementList);
+			}
 		}
 
 		GpuProgram::initialize_internal();