public Future <Texture2D> CreateTextureAsync(RenderCoordinator coordinator, bool mainThread, bool padToPowerOfTwo, bool sRGB = false) { if (IsDisposed) { throw new ObjectDisposedException("Image"); } // FIXME: Channel count int width = padToPowerOfTwo ? Arithmetic.NextPowerOfTwo(Width) : Width; var height = padToPowerOfTwo ? Arithmetic.NextPowerOfTwo(Height) : Height; Texture2D tex; lock (coordinator.CreateResourceLock) { tex = new Texture2D(coordinator.Device, width, height, MipChain != null, GetFormat(sRGB, ChannelCount)) { Tag = "STB.Image" }; coordinator.AutoAllocatedTextureResources.Add(tex); } // FIXME: FP mips, 16bit mips Future <Texture2D> result; if ((MipChain != null) && !IsFloatingPoint && !Is16Bit) { result = UploadWithMips(coordinator, tex, true, mainThread); } else { result = UploadDirect(coordinator, tex, true, mainThread); } return(result); }
protected ResourceProvider( IResourceProviderStreamSource source, RenderCoordinator coordinator, bool enableThreadedPreload, bool enableThreadedCreate ) { if (coordinator == null) { throw new ArgumentNullException("A render coordinator is required", "coordinator"); } StreamSource = source; Coordinator = coordinator; EnableThreadedPreload = enableThreadedPreload; switch (coordinator.GraphicsBackendName) { case "D3D9": case "D3D11": case "Vulkan": EnableThreadedCreate = enableThreadedCreate && true; break; default: EnableThreadedCreate = enableThreadedCreate && false; break; } PreloadQueue = coordinator.ThreadGroup.GetQueueForType <PreloadWorkItem>(forMainThread: !EnableThreadedPreload); CreateQueue = coordinator.ThreadGroup.GetQueueForType <CreateWorkItem>(forMainThread: !EnableThreadedCreate); }
public FreeTypeFont(RenderCoordinator rc, Stream stream, int faceIndex = 0) { RenderCoordinator = rc; var buffer = new byte[stream.Length]; stream.Read(buffer, 0, (int)stream.Length); Face = new Face(new Library(), buffer, faceIndex); Initialize(); }
public ScratchRenderTarget(RenderCoordinator coordinator, UIContext context) { Context = context; int width = (int)(context.CanvasSize.X * context.ScratchScaleFactor), height = (int)(context.CanvasSize.Y * context.ScratchScaleFactor); Instance = new AutoRenderTarget( coordinator, width, height, false, Context.ScratchSurfaceFormat, DepthFormat.Depth24Stencil8 ); }
private Future <Texture2D> UploadDirect(RenderCoordinator coordinator, Texture2D result, bool async, bool mainThread) { if (IsDisposed) { throw new ObjectDisposedException("Image"); } // FIXME: async? UploadTimer.Restart(); lock (coordinator.UseResourceLock) Evil.TextureUtils.SetDataFast(result, 0, Data, new Rectangle(0, 0, Width, Height), (uint)(Width * SizeofPixel)); if (UploadTimer.Elapsed.TotalMilliseconds > 1) { Debug.Print($"Uploading non-mipped texture took {UploadTimer.Elapsed.TotalMilliseconds}ms"); } return(new Future <Texture2D>(result)); }
public LightingRenderer(ContentManager content, RenderCoordinator coordinator, DefaultMaterialSet materials, LightingEnvironment environment) { Materials = materials; Coordinator = coordinator; IlluminantMaterials = new IlluminantMaterials(materials); StoreScissorRect = _StoreScissorRect; RestoreScissorRect = _RestoreScissorRect; ShadowBatchSetup = _ShadowBatchSetup; IlluminationBatchSetup = _IlluminationBatchSetup; IlluminantMaterials.ClearStencil = materials.Get( materials.Clear, rasterizerState: RasterizerState.CullNone, depthStencilState: new DepthStencilState { StencilEnable = true, StencilMask = StencilTrue, StencilWriteMask = StencilTrue, ReferenceStencil = StencilFalse, StencilFunction = CompareFunction.Always, StencilPass = StencilOperation.Replace, StencilFail = StencilOperation.Replace, }, blendState: BlendState.Opaque ); materials.Add( IlluminantMaterials.DebugOutlines = materials.WorldSpaceGeometry.SetStates( blendState: BlendState.AlphaBlend ) ); // If stencil == false, paint point light at this location PointLightStencil = new DepthStencilState { DepthBufferEnable = false, StencilEnable = true, StencilMask = StencilTrue, StencilWriteMask = StencilFalse, StencilFunction = CompareFunction.Equal, StencilPass = StencilOperation.Keep, StencilFail = StencilOperation.Keep, ReferenceStencil = StencilFalse }; { var dBegin = new[] { MaterialUtil.MakeDelegate( rasterizerState: RenderStates.ScissorOnly, depthStencilState: PointLightStencil ) }; var dEnd = new[] { MaterialUtil.MakeDelegate( rasterizerState: RasterizerState.CullNone, depthStencilState: DepthStencilState.None ) }; #if SDL2 materials.Add(IlluminantMaterials.PointLightExponential = new DelegateMaterial( PointLightMaterialsInner[0] = new Squared.Render.EffectMaterial( content.Load <Effect>("PointLightExponential"), "PointLightExponential" ), dBegin, dEnd )); materials.Add(IlluminantMaterials.PointLightLinear = new DelegateMaterial( PointLightMaterialsInner[1] = new Squared.Render.EffectMaterial( content.Load <Effect>("PointLightLinear"), "PointLightLinear" ), dBegin, dEnd )); materials.Add(IlluminantMaterials.PointLightExponentialRampTexture = new DelegateMaterial( PointLightMaterialsInner[2] = new Squared.Render.EffectMaterial( content.Load <Effect>("PointLightExponentialRampTexture"), "PointLightExponentialRampTexture" ), dBegin, dEnd )); materials.Add(IlluminantMaterials.PointLightLinearRampTexture = new DelegateMaterial( PointLightMaterialsInner[3] = new Squared.Render.EffectMaterial( content.Load <Effect>("PointLightLinearRampTexture"), "PointLightLinearRampTexture" ), dBegin, dEnd )); #else materials.Add(IlluminantMaterials.PointLightExponential = new DelegateMaterial( PointLightMaterialsInner[0] = new Squared.Render.EffectMaterial( content.Load <Effect>("Illumination"), "PointLightExponential" ), dBegin, dEnd )); materials.Add(IlluminantMaterials.PointLightLinear = new DelegateMaterial( PointLightMaterialsInner[1] = new Squared.Render.EffectMaterial( content.Load <Effect>("Illumination"), "PointLightLinear" ), dBegin, dEnd )); materials.Add(IlluminantMaterials.PointLightExponentialRampTexture = new DelegateMaterial( PointLightMaterialsInner[2] = new Squared.Render.EffectMaterial( content.Load <Effect>("Illumination"), "PointLightExponentialRampTexture" ), dBegin, dEnd )); materials.Add(IlluminantMaterials.PointLightLinearRampTexture = new DelegateMaterial( PointLightMaterialsInner[3] = new Squared.Render.EffectMaterial( content.Load <Effect>("Illumination"), "PointLightLinearRampTexture" ), dBegin, dEnd )); #endif } // If stencil == false: set stencil to true. // If stencil == true: leave stencil alone, don't paint this pixel ShadowStencil = new DepthStencilState { DepthBufferEnable = false, StencilEnable = true, StencilMask = StencilTrue, StencilWriteMask = StencilTrue, StencilFunction = CompareFunction.NotEqual, StencilPass = StencilOperation.Replace, StencilFail = StencilOperation.Keep, ReferenceStencil = StencilTrue }; materials.Add(IlluminantMaterials.Shadow = new DelegateMaterial( ShadowMaterialInner = new Squared.Render.EffectMaterial( #if SDL2 content.Load <Effect>("Shadow"), "Shadow" #else content.Load <Effect>("Illumination"), "Shadow" #endif ), new[] { MaterialUtil.MakeDelegate( rasterizerState: RenderStates.ScissorOnly, depthStencilState: ShadowStencil, blendState: RenderStates.DrawNone ) }, new[] { MaterialUtil.MakeDelegate( rasterizerState: RasterizerState.CullNone, depthStencilState: DepthStencilState.None ) } )); #if SDL2 materials.Add(IlluminantMaterials.ScreenSpaceGammaCompressedBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("ScreenSpaceGammaCompressedBitmap"), "ScreenSpaceGammaCompressedBitmap" )); materials.Add(IlluminantMaterials.WorldSpaceGammaCompressedBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("WorldSpaceGammaCompressedBitmap"), "WorldSpaceGammaCompressedBitmap" )); materials.Add(IlluminantMaterials.ScreenSpaceToneMappedBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("ScreenSpaceToneMappedBitmap"), "ScreenSpaceToneMappedBitmap" )); materials.Add(IlluminantMaterials.WorldSpaceToneMappedBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("WorldSpaceToneMappedBitmap"), "WorldSpaceToneMappedBitmap" )); #else materials.Add(IlluminantMaterials.ScreenSpaceGammaCompressedBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("HDRBitmap"), "ScreenSpaceGammaCompressedBitmap" )); materials.Add(IlluminantMaterials.WorldSpaceGammaCompressedBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("HDRBitmap"), "WorldSpaceGammaCompressedBitmap" )); materials.Add(IlluminantMaterials.ScreenSpaceToneMappedBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("HDRBitmap"), "ScreenSpaceToneMappedBitmap" )); materials.Add(IlluminantMaterials.WorldSpaceToneMappedBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("HDRBitmap"), "WorldSpaceToneMappedBitmap" )); materials.Add(IlluminantMaterials.ScreenSpaceRampBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("RampBitmap"), "ScreenSpaceRampBitmap" )); materials.Add(IlluminantMaterials.WorldSpaceRampBitmap = new Squared.Render.EffectMaterial( content.Load <Effect>("RampBitmap"), "WorldSpaceRampBitmap" )); #endif Environment = environment; // Reduce garbage created by BufferPool<>.Allocate when creating cached sectors BufferPool <ShadowVertex> .MaxBufferSize = 1024 * 16; BufferPool <short> .MaxBufferSize = 1024 * 32; }
public PongMaterials(RenderCoordinator coordinator) : base(coordinator) { var addBs = new BlendState { AlphaBlendFunction = BlendFunction.Add, ColorBlendFunction = BlendFunction.Add, AlphaSourceBlend = Blend.One, ColorSourceBlend = Blend.One, AlphaDestinationBlend = Blend.One, ColorDestinationBlend = Blend.One }; var ds = new DepthStencilState { DepthBufferEnable = false }; // Set up various blending modes by changing render states var additiveBlend = new Action <DeviceManager>[] { (dm) => { dm.Device.BlendState = addBs; dm.Device.DepthStencilState = ds; } }; var subBs = new BlendState { AlphaBlendFunction = BlendFunction.ReverseSubtract, ColorBlendFunction = BlendFunction.ReverseSubtract, AlphaSourceBlend = Blend.One, ColorSourceBlend = Blend.One, AlphaDestinationBlend = Blend.One, ColorDestinationBlend = Blend.One }; var subtractiveBlend = new Action <DeviceManager>[] { (dm) => { dm.Device.BlendState = subBs; dm.Device.DepthStencilState = ds; } }; var alphaBs = new BlendState { AlphaBlendFunction = BlendFunction.Add, ColorBlendFunction = BlendFunction.Add, AlphaSourceBlend = Blend.SourceAlpha, ColorSourceBlend = Blend.SourceAlpha, AlphaDestinationBlend = Blend.InverseSourceAlpha, ColorDestinationBlend = Blend.InverseSourceAlpha }; var alphaBlend = new Action <DeviceManager>[] { (dm) => { dm.Device.BlendState = alphaBs; dm.Device.DepthStencilState = ds; } }; // Create a couple custom materials Trail = base.ScreenSpaceBitmap.WrapWithHandlers(additiveBlend); SubtractiveGeometry = base.ScreenSpaceGeometry.WrapWithHandlers(subtractiveBlend); // Replace the default materials with ones that set up our custom render states ScreenSpaceBitmap = base.ScreenSpaceBitmap.WrapWithHandlers(alphaBlend); ScreenSpaceGeometry = base.ScreenSpaceGeometry.WrapWithHandlers(alphaBlend); }
public FreeTypeFont(RenderCoordinator rc, byte[] buffer, int faceIndex = 0) { RenderCoordinator = rc; Face = new Face(new Library(), buffer, faceIndex); Initialize(); }
public FreeTypeFont(RenderCoordinator rc, string filename, int faceIndex = 0) { RenderCoordinator = rc; Face = new Face(new Library(), filename, faceIndex); Initialize(); }
private unsafe Future <Texture2D> UploadWithMips(RenderCoordinator coordinator, Texture2D result, bool async, bool mainThread) { var pPreviousLevelData = Data; var pLevelData = Data; int levelWidth = Width, levelHeight = Height; int previousLevelWidth = Width, previousLevelHeight = Height; if (MipChain == null) { throw new Exception("Mip chain not generated or already uploaded"); } UploadTimer.Restart(); var f = new Future <Texture2D>(); int itemsPending = 1; var queue = coordinator.ThreadGroup.GetQueueForType <UploadMipWorkItem>(mainThread); for (uint level = 0; (levelWidth >= 1) && (levelHeight >= 1); level++) { if (IsDisposed) { throw new ObjectDisposedException("Image"); } byte[] mip; uint mipPitch; if (level > 0) { mip = MipChain[level - 1]; mipPitch = (uint)(levelWidth * SizeofPixel); } else { mip = null; mipPitch = (uint)(Width * SizeofPixel); } var workItem = new UploadMipWorkItem { Coordinator = coordinator, Image = this, Mip = mip, MipPitch = mipPitch, Texture = result, Level = level, LevelWidth = levelWidth, LevelHeight = levelHeight }; if (async) { // FIXME Interlocked.Increment(ref itemsPending); queue.Enqueue(workItem, OnItemComplete); } else { workItem.Execute(); } previousLevelWidth = levelWidth; previousLevelHeight = levelHeight; var newWidth = levelWidth / 2; var newHeight = levelHeight / 2; levelWidth = newWidth; levelHeight = newHeight; } Interlocked.Decrement(ref itemsPending); if (!async) { f.SetResult(result, null); } if (UploadTimer.Elapsed.TotalMilliseconds > 2) { Debug.Print($"Uploading mipped texture took {UploadTimer.Elapsed.TotalMilliseconds}ms"); } return(f); void OnItemComplete(ref UploadMipWorkItem wi) { if (Interlocked.Decrement(ref itemsPending) != 0) { return; } f.SetResult(result, null); } }