/// <summary>
            /// Create renderable mesh
            /// </summary>
            /// <param name="setVertexBuffer">Set vertex buffer</param>
            /// <param name="setIndexBuffer">Set index buffer</param>
            /// <param name="setMaterial">Set material</param>
            /// <param name="setUsedTechnique">Set used technique</param>
            /// <param name="setWorldParameter">Set world parameter</param>
            /// <param name="setVertexDeclaration">Set vertex declaration</param>
            /// <param name="setStreamOffset">Set stream offset</param>
            /// <param name="setVertexStride">Set vertex stride</param>
            /// <param name="setBaseVertex">Set base vertex</param>
            /// <param name="setNumVertices">Set number vertices</param>
            /// <param name="setStartIndex">Set start index</param>
            /// <param name="setPrimitiveCount">Set primitive count</param>
            public RenderableMesh(VertexBuffer setVertexBuffer,
				IndexBuffer setIndexBuffer, Material setMaterial,
				EffectTechnique setUsedTechnique,
				//EffectParameter setWorldParameter,
				VertexDeclaration setVertexDeclaration,
				int setStreamOffset, int setVertexStride, int setBaseVertex,
				int setNumVertices, int setStartIndex, int setPrimitiveCount)
            {
                vertexBuffer = setVertexBuffer;
                indexBuffer = setIndexBuffer;
                material = setMaterial;
                usedTechnique = setUsedTechnique;
                vertexDeclaration = setVertexDeclaration;
                streamOffset = setStreamOffset;
                vertexStride = setVertexStride;
                baseVertex = setBaseVertex;
                numVertices = setNumVertices;
                startIndex = setStartIndex;
                primitiveCount = setPrimitiveCount;
            }
        /// <summary>
        /// Add model mesh part with the used effect to our sortedMeshes list.
        /// Neither the model mesh part nor the effect is directly used,
        /// we will extract all data from the model and only render the
        /// index and vertex buffers later.
        /// The model mesh part must use the TangentVertex format.
        /// </summary>
        /// <param name="vertexBuffer">Vertex buffer</param>
        /// <param name="indexBuffer">Index buffer</param>
        /// <param name="part">Part</param>
        /// <param name="effect">Effect</param>
        /// <returns>Renderable mesh</returns>
        public RenderableMesh Add(VertexBuffer vertexBuffer,
			IndexBuffer indexBuffer, ModelMeshPart part, Effect effect)
        {
            string techniqueName = effect.CurrentTechnique.Name;

            // Does this technique already exists?
            MeshesPerMaterialPerTechniques foundList = null;
            //obs: foreach (MeshesPerMaterialPerTechniques list in sortedMeshes)
            for (int listNum = 0; listNum < sortedMeshes.Count; listNum++)
            {
                MeshesPerMaterialPerTechniques list = sortedMeshes[listNum];

                if (list.technique != null &&
                    list.technique.Name == techniqueName)
                {
                    foundList = list;
                    break;
                } // if (list.technique.Name)
            } // for (listNum)

            // Did not found list? Create new one
            if (foundList == null)
            {
                EffectTechnique technique =
                    BaseGame.ParallaxShader.GetTechnique(techniqueName);

                // Make sure we always have a valid technique
                if (technique == null)
                {
                    if (BaseGame.CanUsePS20)
                        techniqueName = "Diffuse20";//"Specular20";
                    else
                        techniqueName = "Diffuse";//"Specular";
                    technique = BaseGame.ParallaxShader.GetTechnique(techniqueName);
                } // if

                foundList = new MeshesPerMaterialPerTechniques(technique);
                sortedMeshes.Add(foundList);
            } // if (foundList)

            // Create new material from the current effect parameters.
            // This will create duplicate materials if the same material is used
            // multiple times, we check this later.
            Material material = new Material(effect);

            // Search for material inside foundList.
            //obs: foreach (MeshesPerMaterial innerList in foundList.meshesPerMaterials)
            for (int innerListNum = 0; innerListNum <
                foundList.meshesPerMaterials.Count; innerListNum++)
            {
                MeshesPerMaterial innerList =
                    foundList.meshesPerMaterials[innerListNum];

                // Check if this is the same material and we can use it instead.
                // For our purposes it is sufficiant if we check textures and colors.
                if (innerList.material.diffuseTexture == material.diffuseTexture &&
                    innerList.material.normalTexture == material.normalTexture &&
                    innerList.material.ambientColor == material.ambientColor &&
                    innerList.material.diffuseColor == material.diffuseColor &&
                    innerList.material.specularColor == material.specularColor &&
                    innerList.material.specularPower == material.specularPower)
                {
                    // Reuse this material and quit this search
                    material = innerList.material;
                    break;
                } // if (innerList.material.diffuseTexture)
            } // foreach (innerList)

            // Build new RenderableMesh object
            RenderableMesh mesh = new RenderableMesh(
                vertexBuffer, indexBuffer, material, foundList.technique,
                part.VertexDeclaration,
                part.StreamOffset, part.VertexStride, part.BaseVertex,
                part.NumVertices, part.StartIndex, part.PrimitiveCount);
            foundList.Add(mesh);
            return mesh;
        }
 /// <summary>
 /// Create meshes per material for the setMaterial.
 /// </summary>
 /// <param name="setMaterial">Set material</param>
 public MeshesPerMaterial(Material setMaterial)
 {
     material = setMaterial;
 }
 /// <summary>
 /// Dispose
 /// </summary>
 /// <param name="someObject">Some object</param>
 public static void Dispose(ref Material someObject)
 {
     if (someObject != null)
         someObject.Dispose();
     someObject = null;
 }
        /// <summary>
        /// Set parameters, this overload sets all material parameters too.
        /// </summary>
        public virtual void SetParametersOptimized(Material setMat)
        {
            // No need to set world matrix, will be done later in mesh rendering
            // in the MeshRenderManager. All the rest is set with help of the
            // SetParametersOptimizedGeneral above.

            // Only update ambient, diffuse, specular and the textures, the rest
            // will not change for a material change in MeshRenderManager.
            ambientColor.SetValue(setMat.ambientColor.ToVector4());
            diffuseColor.SetValue(setMat.diffuseColor.ToVector4());
            specularColor.SetValue(setMat.specularColor.ToVector4());
            if (setMat.diffuseTexture != null)
                diffuseTexture.SetValue(setMat.diffuseTexture.XnaTexture);
            if (setMat.normalTexture != null)
                normalTexture.SetValue(setMat.normalTexture.XnaTexture);
        }
        /// <summary>
        /// Set parameters, this overload sets all material parameters too.
        /// </summary>
        public virtual void SetParameters(Material setMat)
        {
            if (worldViewProj != null)
                worldViewProj.SetValue(BaseGame.WorldViewProjectionMatrix);
            if (viewProj != null)
                viewProj.SetValue(BaseGame.ViewProjectionMatrix);
            if (world != null)
                world.SetValue(BaseGame.WorldMatrix);
            if (viewInverse != null)
                viewInverse.SetValue(BaseGame.InverseViewMatrix);
            if (lightDir != null)
                lightDir.SetValue(BaseGame.LightDirection);

            /*TODO?
            // Set the reflection cube texture only once
            if (lastUsedReflectionCubeTexture == null &&
                reflectionCubeTexture != null)
            {
                ReflectionCubeTexture = TextureFont.SkyCubeMapTexture;
            } // if (lastUsedReflectionCubeTexture)
             */

            // Set all material properties
            if (setMat != null)
            {
                AmbientColor = setMat.ambientColor;
                DiffuseColor = setMat.diffuseColor;
                SpecularColor = setMat.specularColor;
                SpecularPower = setMat.specularPower;
                DiffuseTexture = setMat.diffuseTexture;
                NormalTexture = setMat.normalTexture;
                HeightTexture = setMat.heightTexture;
                //unusupported: ParallaxAmount = setMat.parallaxAmount;
                DetailTexture = setMat.detailTexture;
            } // if (setMat)
        }
        /*unused, always specify a technique name
        /// <summary>
        /// Render
        /// </summary>
        /// <param name="renderDelegate">Render delegate</param>
        public void Render(BaseGame.RenderDelegate renderDelegate)
        {
            SetParameters();

            //not supported or bug, no multiple techniques possible yet:
            //effect.Technique = "SpecularPerPixel";

            // Start shader
            effect.Begin(EffectStateOptions.Default);
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                // Render each pass
                pass.Begin();
                renderDelegate();
                pass.End();
            } // foreach (pass)

            // End shader
            effect.End();
        } // Render(renderDelegate)
         */
        /*unused, always specify a technique name
        /// <summary>
        /// Render
        /// </summary>
        /// <param name="setMat">Set matrix</param>
        /// <param name="renderDelegate">Render delegate</param>
        public void Render(Material setMat,
            BaseGame.RenderDelegate renderDelegate)
        {
            SetParameters(setMat);

            //not supported or bug, no multiple techniques possible yet:
            //effect.Technique = "SpecularPerPixel";

            // Start shader
            effect.Begin(EffectStateOptions.Default);
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                // Render each pass
                pass.Begin();
                renderDelegate();
                pass.End();
            } // foreach (pass)

            // End shader
            effect.End();
        } // Render(setMat, renderDelegate)
         */
        /// <summary>
        /// Render
        /// </summary>
        /// <param name="setMat">Set matrix</param>
        /// <param name="passName">Pass name</param>
        /// <param name="renderDelegate">Render delegate</param>
        public void Render(Material setMat,
			string techniqueName,
			BaseGame.RenderDelegate renderDelegate)
        {
            SetParameters(setMat);

            // Can we do the requested technique?
            // For graphic cards not supporting ps2.0, fall back to ps1.1
            if (BaseGame.CanUsePS20 == false &&
                techniqueName.EndsWith("20"))
                // Use same technique without the 20 ending!
                techniqueName = techniqueName.Substring(0, techniqueName.Length - 2);

            // Start shader
            effect.CurrentTechnique = effect.Techniques[techniqueName];
            effect.Begin(SaveStateMode.None);

            // Render all passes (usually just one)
            //foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            for (int num = 0; num < effect.CurrentTechnique.Passes.Count; num++)
            {
                EffectPass pass = effect.CurrentTechnique.Passes[num];

                pass.Begin();
                renderDelegate();
                pass.End();
            } // foreach (pass)

            // End shader
            effect.End();
        }