Beispiel #1
0
        public IEnumerable <IRenderable> UpdatePerFrameResources(IRendererContext context, IEnumerable <IRenderable> renderables)
        {
            var c  = (VeldridRendererContext)context;
            var gd = c.GraphicsDevice;

            if (!(renderables.FirstOrDefault() is SkyboxRenderable skybox))
            {
                yield break;
            }

            ITextureManager      textureManager = Resolve <ITextureManager>();
            IDeviceObjectManager objectManager  = Resolve <IDeviceObjectManager>();

            textureManager?.PrepareTexture(skybox.Texture, context);
            TextureView textureView = (TextureView)textureManager?.GetTexture(skybox.Texture);

            var resourceSet = objectManager.Get <ResourceSet>((skybox, textureView));

            if (resourceSet == null)
            {
                resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
                                                                       _resourceLayout,
                                                                       gd.PointSampler,
                                                                       textureView,
                                                                       _uniformBuffer));
                resourceSet.Name = $"RS_Sky:{skybox.Texture.Name}";
                PerfTracker.IncrementFrameCounter("Create ResourceSet");
                objectManager.Set((skybox, textureView), resourceSet);
            }

            yield return(skybox);
        }
Beispiel #2
0
        public IEnumerable <IRenderable> UpdatePerFrameResources(GraphicsDevice gd, CommandList cl, SceneContext sc, IEnumerable <IRenderable> renderables)
        {
            ITextureManager      textureManager = Resolve <ITextureManager>();
            IDeviceObjectManager dom            = Resolve <IDeviceObjectManager>();

            foreach (var sprite in renderables.OfType <MultiSprite>())
            {
                if (sprite.ActiveInstances == 0)
                {
                    continue;
                }

                uint bufferSize = (uint)sprite.Instances.Length * SpriteInstanceData.StructSize;
                var  buffer     = dom.Prepare((sprite, sprite),
                                              () =>
                {
                    var newBuffer  = gd.ResourceFactory.CreateBuffer(new BufferDescription(bufferSize, BufferUsage.VertexBuffer));
                    newBuffer.Name = $"B_SpriteInst:{sprite.Name}";
                    PerfTracker.IncrementFrameCounter("Create InstanceBuffer");
                    return(newBuffer);
                }, existing => existing.SizeInBytes != bufferSize);

                if (sprite.InstancesDirty)
                {
                    cl.UpdateBuffer(buffer, 0, sprite.Instances);
                    PerfTracker.IncrementFrameCounter("Update InstanceBuffers");
                }

                textureManager?.PrepareTexture(sprite.Key.Texture, gd);
                TextureView textureView = textureManager?.GetTexture(sprite.Key.Texture);
                dom.Prepare((sprite, textureView),
                            () =>
                {
                    var resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
                                                                               _perSpriteResourceLayout,
                                                                               gd.PointSampler,
                                                                               textureView,
                                                                               _uniformBuffer));
                    resourceSet.Name = $"RS_Sprite:{sprite.Key.Texture.Name}";
                    PerfTracker.IncrementFrameCounter("Create ResourceSet");
                    return(resourceSet);
                }, _ => false
                            );

                sprite.InstancesDirty = false;
                yield return(sprite);
            }

            Resolve <ISpriteManager>().Cleanup();
        }
Beispiel #3
0
        public IEnumerable <IRenderable> UpdatePerFrameResources(IRendererContext context, IEnumerable <IRenderable> renderables)
        {
            var c  = (VeldridRendererContext)context;
            var cl = c.CommandList;
            var gd = c.GraphicsDevice;
            var sc = c.SceneContext;

            ITextureManager      textureManager = Resolve <ITextureManager>();
            IDeviceObjectManager objectManager  = Resolve <IDeviceObjectManager>();
            EngineFlags          engineFlags    = Resolve <IEngineSettings>().Flags;

            foreach (var renderable in renderables)
            {
                var sprite = (MultiSprite)renderable;
                if (sprite.ActiveInstances == 0)
                {
                    continue;
                }

                var shaderKey = new SpriteShaderKey(sprite, engineFlags);
                if (!_pipelines.ContainsKey(shaderKey))
                {
                    _pipelines.Add(shaderKey, BuildPipeline(gd, sc, shaderKey));
                }

                uint bufferSize = (uint)sprite.Instances.Length * SpriteInstanceData.StructSize;
                var  buffer     = objectManager.Get <DeviceBuffer>((sprite, sprite));
                if (buffer?.SizeInBytes != bufferSize)
                {
                    buffer      = gd.ResourceFactory.CreateBuffer(new BufferDescription(bufferSize, BufferUsage.VertexBuffer));
                    buffer.Name = $"B_SpriteInst:{sprite.Name}";
                    PerfTracker.IncrementFrameCounter("Create InstanceBuffer");
                    objectManager.Set((sprite, sprite), buffer);
                }

                if (sprite.InstancesDirty)
                {
                    cl.UpdateBuffer(buffer, 0, sprite.Instances);
                    PerfTracker.IncrementFrameCounter("Update InstanceBuffers");
                }

                textureManager?.PrepareTexture(sprite.Key.Texture, context);
                TextureView textureView = (TextureView)textureManager?.GetTexture(sprite.Key.Texture);

                var resourceSet = objectManager.Get <ResourceSet>((sprite, textureView));
                if (resourceSet == null)
                {
                    resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
                                                                           _perSpriteResourceLayout,
                                                                           gd.PointSampler,
                                                                           textureView,
                                                                           _uniformBuffer));
                    resourceSet.Name = $"RS_Sprite:{sprite.Key.Texture.Name}";
                    PerfTracker.IncrementFrameCounter("Create ResourceSet");
                    objectManager.Set((sprite, textureView), resourceSet);
                }

                sprite.InstancesDirty = false;
                yield return(sprite);
            }

            Resolve <ISpriteManager>().Cleanup();
        }
Beispiel #4
0
        public void UpdatePerFrameResources(IRendererContext context, IEnumerable <IRenderable> renderables, IList <IRenderable> results)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (renderables == null)
            {
                throw new ArgumentNullException(nameof(renderables));
            }
            if (results == null)
            {
                throw new ArgumentNullException(nameof(results));
            }

            var c              = (VeldridRendererContext)context;
            var cl             = c.CommandList;
            var gd             = c.GraphicsDevice;
            var textureManager = Resolve <ITextureManager>();
            var objectManager  = Resolve <IDeviceObjectManager>();
            var engineFlags    = Resolve <IEngineSettings>().Flags;

            foreach (var renderable in renderables)
            {
                var sprite = (MultiSprite)renderable;
                if (sprite.ActiveInstances == 0)
                {
                    continue;
                }

                cl.PushDebugGroup(sprite.Name);
                var shaderKey = new SpriteShaderKey(sprite, engineFlags);
                if (!_pipelines.ContainsKey(shaderKey))
                {
                    _pipelines.Add(shaderKey, BuildPipeline(gd, c.SceneContext, shaderKey));
                }

                uint bufferSize = (uint)sprite.Instances.Length * SpriteInstanceData.StructSize;
                var  buffer     = objectManager.GetDeviceObject <DeviceBuffer>((sprite, sprite, "InstanceBuffer"));
                if (buffer?.SizeInBytes != bufferSize)
                {
                    buffer      = gd.ResourceFactory.CreateBuffer(new BufferDescription(bufferSize, BufferUsage.VertexBuffer));
                    buffer.Name = $"B_Inst:{sprite.Name}";
                    PerfTracker.IncrementFrameCounter("Create InstanceBuffer");
                    objectManager.SetDeviceObject((sprite, sprite, "InstanceBuffer"), buffer);
                    sprite.InstancesDirty = true;
                }

                if (sprite.InstancesDirty)
                {
                    var instances = sprite.Instances;
                    VeldridUtil.UpdateBufferSpan(cl, buffer, instances);
                    PerfTracker.IncrementFrameCounter("Update InstanceBuffers");
                }

                textureManager?.PrepareTexture(sprite.Key.Texture, context);
                TextureView textureView = (TextureView)textureManager?.GetTexture(sprite.Key.Texture);

                var uniformBuffer = objectManager.GetDeviceObject <DeviceBuffer>((sprite, textureView, "UniformBuffer"));
                if (uniformBuffer == null)
                {
                    uniformBuffer      = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <SpriteUniformInfo>(), BufferUsage.UniformBuffer));
                    uniformBuffer.Name = $"B_SpriteUniform:{sprite.Name}";
                    PerfTracker.IncrementFrameCounter("Create sprite uniform buffer");
                    objectManager.SetDeviceObject((sprite, textureView, "UniformBuffer"), uniformBuffer);

                    var uniformInfo = new SpriteUniformInfo
                    {
                        Flags         = sprite.Key.Flags,
                        TextureWidth  = textureView?.Target.Width ?? 1,
                        TextureHeight = textureView?.Target.Height ?? 1
                    };
                    cl.UpdateBuffer(uniformBuffer, 0, uniformInfo);
                }

                var resourceSet = objectManager.GetDeviceObject <ResourceSet>((sprite, textureView, "ResourceSet"));
                if (resourceSet == null)
                {
                    resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
                                                                           _perSpriteResourceLayout,
                                                                           textureView,
                                                                           gd.PointSampler,
                                                                           uniformBuffer));
                    resourceSet.Name = $"RS_Sprite:{sprite.Key.Texture.Name}";
                    PerfTracker.IncrementFrameCounter("Create ResourceSet");
                    objectManager.SetDeviceObject((sprite, textureView, "ResourceSet"), resourceSet);
                }

                sprite.InstancesDirty = false;
                results.Add(sprite);
                cl.PopDebugGroup();
            }

            Resolve <ISpriteManager>().Cleanup();
        }
        public void UpdatePerFrameResources(IRendererContext context, IEnumerable <IRenderable> renderables, IList <IRenderable> results)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (renderables == null)
            {
                throw new ArgumentNullException(nameof(renderables));
            }
            if (results == null)
            {
                throw new ArgumentNullException(nameof(results));
            }

            var c             = (VeldridRendererContext)context;
            var cl            = c.CommandList;
            var gd            = c.GraphicsDevice;
            var objectManager = Resolve <IDeviceObjectManager>();

            foreach (var renderable in renderables)
            {
                var overlay = (InfoOverlay)renderable;
                // Only render if an overlay is being shown
                if (overlay.ExamineOpacity + overlay.ManipulateOpacity + overlay.TalkOpacity + overlay.TakeOpacity <= 0)
                {
                    continue;
                }

                cl.PushDebugGroup("Info Overlay");
                var tiles  = overlay.Tiles;
                var buffer = objectManager.GetDeviceObject <DeviceBuffer>((overlay, overlay, "Tiles"));
                if (buffer?.SizeInBytes != tiles.Length)
                {
                    var size = 16 * (((uint)tiles.Length + 15) / 16);
                    buffer      = gd.ResourceFactory.CreateBuffer(new BufferDescription(size, BufferUsage.StructuredBufferReadOnly, 4));
                    buffer.Name = "B_InfoOverlayTiles";
                    objectManager.SetDeviceObject((overlay, overlay, "Tiles"), buffer);
                    overlay.BufferDirty = true;
                }

                if (overlay.BufferDirty)
                {
                    VeldridUtil.UpdateBufferSpan(cl, buffer, tiles);
                    PerfTracker.IncrementFrameCounter("Update InstanceBuffers");
                }

                var uniformBuffer = objectManager.GetDeviceObject <DeviceBuffer>((overlay, overlay, "UniformBuffer"));
                if (uniformBuffer == null)
                {
                    uniformBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription(
                                                                        (uint)Unsafe.SizeOf <InfoOverlayUniforms>(), BufferUsage.UniformBuffer));
                    uniformBuffer.Name = "InfoOverlayUniformBuffer";
                    PerfTracker.IncrementFrameCounter("Create info overlay uniform buffer");
                    objectManager.SetDeviceObject((overlay, overlay, "UniformBuffer"), uniformBuffer);
                }

                var uniformInfo = new InfoOverlayUniforms
                {
                    Examine    = overlay.ExamineOpacity,
                    Manipulate = overlay.ManipulateOpacity,
                    Talk       = overlay.TalkOpacity,
                    Take       = overlay.TakeOpacity,
                    Width      = overlay.Width,
                    Height     = overlay.Height,
                    TileWidth  = overlay.TileWidth,
                    TileHeight = overlay.TileHeight,
                };
                cl.UpdateBuffer(uniformBuffer, 0, uniformInfo);

                var resourceSet = objectManager.GetDeviceObject <ResourceSet>((overlay, overlay, "ResourceSet"));
                if (resourceSet == null)
                {
                    resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
                                                                           _perSpriteResourceLayout,
                                                                           buffer,
                                                                           uniformBuffer));
                    resourceSet.Name = "RS_InfoOverlay";
                    PerfTracker.IncrementFrameCounter("Create ResourceSet");
                    objectManager.SetDeviceObject((overlay, overlay, "ResourceSet"), resourceSet);
                }

                results.Add(overlay);
                overlay.BufferDirty = false;
                cl.PopDebugGroup();
            }
        }