} // 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
/// <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