} // LookupTable

        #endregion

        #region Create

        /// <summary>
        /// Creates the lookup table.
        /// </summary>
        private void Create(string filename)
        {
            // If I use a create-dispose method, the texture can't be used again, that could mean a potential ObjectDisposedException.
            AssetContentManager userContentManager     = AssetContentManager.CurrentContentManager;
            AssetContentManager temporalContentManager = new AssetContentManager {
                Name = "Temporal Content Manager", Hidden = true
            };

            AssetContentManager.CurrentContentManager = temporalContentManager;
            Texture lookupTableTexture2D = new Texture("LookupTables\\" + filename);
            // SideSize is inaccurate because Math.Pow is a bad way to calculate cube roots.
            int sideSize = (int)Math.Pow(lookupTableTexture2D.Width * lookupTableTexture2D.Height, 1 / 3.0);

            // hence this second step to snap to nearest power of 2.
            Size = (int)Math.Pow(2, Math.Round(Math.Log(sideSize, 2)));
            //Create the cube lut and dump the 2d lut into it
            Color[] colors = new Color[Size * Size * Size];
            Resource = new Texture3D(EngineManager.Device, Size, Size, Size, false, SurfaceFormat.Color);
            lookupTableTexture2D.Resource.GetData(colors);
            Resource.SetData(colors);
            Resource.Name = filename;

            // Dispose the temporal content manager and restore the user content manager.
            temporalContentManager.Dispose();
            AssetContentManager.CurrentContentManager = userContentManager;
        } // Create
        } // SetUniqueName

        #endregion

        #region Recreate Content Managers

        /// <summary>
        /// Useful when the XNA device is disposed.
        /// </summary>
        internal static void RecreateContentManagers()
        {
            AssetContentManager temp = CurrentContentManager;

            foreach (AssetContentManager contentManager in ContentManagers)
            {
                CurrentContentManager = contentManager;
                // Unload resources.
                contentManager.XnaContentManager.Unload();
                // Load them again.
                foreach (Asset asset in contentManager.Assets)
                {
                    if (!(asset is Shader))
                    {
                        asset.RecreateResource();
                    }
                }
                // Some shaders create its own textures, I want that this textures are recreated first.
                foreach (Asset asset in contentManager.Assets)
                {
                    if (asset is Shader)
                    {
                        asset.RecreateResource();
                    }
                }
            }
            CurrentContentManager = temp;
        } // RecreateContentManagers
        } // Fetch

        /// <summary>
        /// Fetch a multiple render target.
        /// </summary>
        public static RenderTargetBinding Fetch(Size size, SurfaceFormat surfaceFormat1, DepthFormat depthFormat, SurfaceFormat surfaceFormat2, SurfaceFormat surfaceFormat3)
        {
            RenderTargetBinding renderTargetBinding;
            for (int i = 0; i < multipleRenderTargets.Count; i++)
            {
                renderTargetBinding = multipleRenderTargets[i];
                // If is a multiple render target of three render targets.
                if (renderTargetBinding.RenderTargets.Length == 3)
                {
                    if (renderTargetBinding.RenderTargets[0].Size == size && renderTargetBinding.RenderTargets[0].SurfaceFormat == surfaceFormat1 &&
                        renderTargetBinding.RenderTargets[0].DepthFormat == depthFormat &&
                        renderTargetBinding.RenderTargets[1].SurfaceFormat == surfaceFormat2 &&
                        renderTargetBinding.RenderTargets[2].SurfaceFormat == surfaceFormat3 &&
                        !renderTargetBinding.RenderTargets[0].looked)
                    {
                        renderTargetBinding.RenderTargets[0].looked = true;
                        return renderTargetBinding;
                    }
                }
            }
            // If there is not one unlook or present we create one.
            AssetContentManager userContentManager = AssetContentManager.CurrentContentManager;
            AssetContentManager.CurrentContentManager = AssetContentManager.SystemContentManager;
            RenderTarget renderTarget1 = new RenderTarget(size, surfaceFormat1, depthFormat, AntialiasingType.NoAntialiasing);
            RenderTarget renderTarget2 = new RenderTarget(size, surfaceFormat2, false, AntialiasingType.NoAntialiasing);
            RenderTarget renderTarget3 = new RenderTarget(size, surfaceFormat3, false, AntialiasingType.NoAntialiasing);
            renderTargetBinding = BindRenderTargets(renderTarget1, renderTarget2, renderTarget3);
            AssetContentManager.CurrentContentManager = userContentManager;
            multipleRenderTargets.Add(renderTargetBinding);
            renderTargetBinding.RenderTargets[0].looked = true;
            return renderTargetBinding;
        } // Fetch
        } // Unload

        #endregion

        #region Sort

        /// <summary>
        /// This comparation allows to sort the content managers by their names.
        /// </summary>
        protected static int CompareContentManagers(AssetContentManager contentManager1, AssetContentManager contentManager2)
        {
            // If they are the same asset then return equals.
            if (contentManager1 == contentManager2)
            {
                return(0);
            }

            string x = contentManager1.Name;
            string y = contentManager2.Name;

            if (x == null)
            {
                if (y == null)
                {
                    // If x is null and y is null, they're equal.
                    return(0);
                }
                else
                {
                    // If x is null and y is not null, y is greater.
                    return(-1);
                }
            }
            else
            {
                // If x is not null...
                if (y == null)
                {
                    // ...and y is null, x is greater.
                    return(1);
                }
                else
                {
                    // ...and y is not null, compare the two strings.
                    int retval = x.CompareTo(y);

                    if (retval != 0)
                    {
                        // If the strings are not of equal length,
                        // the longer string is greater.
                        return(retval);
                    }
                    else
                    {
                        // Create a new unique name for the second asset and do a comparation again.
                        contentManager2.SetUniqueName(y);
                        y = contentManager2.Name;
                        // If the strings are of equal length,
                        // sort them with ordinary string comparison.
                        return(x.CompareTo(y));
                    }
                }
            }
        } // CompareContentManagers
Exemple #5
0
 /// <summary>
 /// There is a pool of render targets to avoid wasting unnecessary graphic memory.
 /// The idea is that a render target has also a flag that tell us if the content is still need or not.
 /// So, when a shader needs a render target it search in the pool for an unused render target with the right characteristics (size, surface format, etc.)
 /// The problem if someone has to turn the flag false when the render target’s content is unnecessary and this could be somehow ugly. 
 /// But the graphic pipeline performance is critical, it’s not an area for the user and its complexity was diminished thanks to the new code’s restructuring.
 /// The pool should be used in the filters, shadow maps and similar shaders. Not everything.
 /// Use the Release method to return a render target to the pool.
 /// </summary>
 public static RenderTargetCube Fetch(int size, SurfaceFormat surfaceFormat, DepthFormat depthFormat, RenderTarget.AntialiasingType antialiasingType, bool mipMap = false)
 {
     RenderTargetCube renderTarget;
     for (int i = 0; i < renderTargets.Count; i++)
     {
         renderTarget = renderTargets[i];
         if (renderTarget.Size == size && renderTarget.SurfaceFormat == surfaceFormat &&
             renderTarget.DepthFormat == depthFormat && renderTarget.Antialiasing == antialiasingType && renderTarget.MipMap == mipMap && !renderTarget.looked)
         {
             renderTarget.looked = true;
             return renderTarget;
         }
     }
     // If there is not one unlook or present we create one.
     AssetContentManager userContentManager = AssetContentManager.CurrentContentManager;
     AssetContentManager.CurrentContentManager = AssetContentManager.SystemContentManager;
     renderTarget = new RenderTargetCube(size, surfaceFormat, depthFormat, antialiasingType, mipMap);
     AssetContentManager.CurrentContentManager = userContentManager;
     renderTargets.Add(renderTarget);
     renderTarget.looked = true;
     return renderTarget;
 } // Fetch