Beispiel #1
0
        public ParticleRenderer(Graphics g, Texture2D tex, Sprite sprite, string vertexShader, string fragmentShader, int maxParticles = 1024)
        {
            MaxParticles  = maxParticles;
            Graphics      = g;
            Texture       = tex;
            Sprite        = sprite;
            Instances     = VKBuffer.InstanceInfo <ParticleInfo>(g, maxParticles);
            UProjection   = VKBuffer.UniformBuffer <ViewProjection>(g, 1);
            UTime         = VKBuffer.UniformBuffer <float>(g, 1);
            USpriteCoords = VKBuffer.UniformBuffer <SpriteCoords>(g, 1);
            UColor        = VKBuffer.UniformBuffer <Color4>(g, 1);
            var spriteCoords = new SpriteCoords
            {
                LeftTop     = sprite.LeftTop / Texture.SizeF,
                RightBottom = sprite.RightBottom / Texture.SizeF,
                Center      = sprite.TextureCenter
            };

            USpriteCoords.Write(ref spriteCoords);
            var color = Color4.White;

            UColor.Write(ref color);

            Pipeline = new PipelineController(Graphics);
            Pipeline.ClearDepthOnBeginPass = true;
            Pipeline.DepthTest             = false;
            Pipeline.DepthWrite            = false;
            Pipeline.BlendMode             = BlendMode.AlphaPremultiplied;
            Pipeline.Instancing            = true;
            Pipeline.InstanceInfoType      = typeof(ParticleInfo);
            Pipeline.Shaders         = new[] { vertexShader, fragmentShader };
            Pipeline.DescriptorItems = new[] {
                DescriptorItem.UniformBuffer(DescriptorItem.ShaderType.Vertex, UProjection),
                DescriptorItem.UniformBuffer(DescriptorItem.ShaderType.Vertex, UTime),
                DescriptorItem.UniformBuffer(DescriptorItem.ShaderType.Vertex, USpriteCoords),
                DescriptorItem.UniformBuffer(DescriptorItem.ShaderType.Fragment, UColor),
                DescriptorItem.CombinedImageSampler(DescriptorItem.ShaderType.Fragment, tex, DescriptorItem.SamplerFilter.Nearest, DescriptorItem.SamplerFilter.Nearest)
            };
        }
Beispiel #2
0
        public CharRenderer(Graphics g, Texture2D tex, string vertexShader, string fragmentShader, int maxChars = 1024)
        {
            MaxChars    = maxChars;
            Graphics    = g;
            Texture     = tex;
            Instances   = VKBuffer.InstanceInfo <CharInfo>(g, MaxChars);
            UProjection = VKBuffer.UniformBuffer <ViewProjection>(g, 1);
            UTime       = VKBuffer.UniformBuffer <float>(g, 1);

            Pipeline = new PipelineController(Graphics);
            Pipeline.ClearDepthOnBeginPass = true;
            Pipeline.DepthTest             = false;
            Pipeline.DepthWrite            = false;
            Pipeline.BlendMode             = BlendMode.AlphaPremultiplied;
            Pipeline.Instancing            = true;
            Pipeline.InstanceInfoType      = typeof(CharInfo);
            Pipeline.Shaders         = new[] { vertexShader, fragmentShader };
            Pipeline.DescriptorItems = new[] {
                DescriptorItem.UniformBuffer(DescriptorItem.ShaderType.Vertex, UProjection),
                DescriptorItem.UniformBuffer(DescriptorItem.ShaderType.Vertex, UTime),
                DescriptorItem.CombinedImageSampler(DescriptorItem.ShaderType.Fragment, tex, DescriptorItem.SamplerFilter.Nearest, DescriptorItem.SamplerFilter.Nearest)
            };
        }
Beispiel #3
0
        protected override void OnInit()
        {
            base.OnInit();

            var rot = Matrix4.CreateRotationX(0) * Matrix4.CreateRotationY(0) * Matrix4.CreateRotationZ(90);

            Console.WriteLine(rot);
            Console.WriteLine(Matrix4.CreateRotation(new Angle(30f, 45f, 30f)).Rotation);

            Positions = new Vector3[Billboards];
            var rand = new Random();

            for (var i = 0; i < Billboards; i++)
            {
                Positions[i] = new Vector3(-200f + (float)rand.NextDouble() * 400f, -200f + (float)rand.NextDouble() * 400f, 0f);
            }

            Instances = VKBuffer.InstanceInfo <InstanceInfo>(Graphics, Billboards);
            Instances.Write(Positions);
            BViewProjection = VKBuffer.UniformBuffer <ViewProjection>(Graphics, 1);
            var testImg = Content.Get <Image>("Data/tex.png");

            using (var imgBuilder = new ImageBuilder(testImg))
            {
                var data = imgBuilder.GetData();
                for (var i = 0; i < data.Length; i += 4)
                {
                    data[i + 2] += 128;
                }
                imgBuilder.SetData(data);
                imgBuilder.Finish();
                TestTex = Texture2D.FromBitmap(Graphics, imgBuilder, new Rectangle[] { new Rectangle(Point.Empty, testImg.Size) });
            }

            Pipeline                  = new PipelineController(Graphics);
            Pipeline.DepthTest        = true;
            Pipeline.DepthWrite       = true;
            Pipeline.BlendMode        = BlendMode.Alpha;
            Pipeline.Instancing       = true;
            Pipeline.InstanceInfoType = typeof(InstanceInfo);
            Pipeline.Shaders          = new[] { "Data/billboard.vert.spv", "Data/billboard.frag.spv" };
            Pipeline.DescriptorItems  = new[] {
                DescriptorItem.UniformBuffer(DescriptorItem.ShaderType.Vertex, BViewProjection),
                DescriptorItem.CombinedImageSampler(DescriptorItem.ShaderType.Fragment, TestTex, DescriptorItem.SamplerFilter.Nearest, DescriptorItem.SamplerFilter.Nearest)
            };
            Pipeline.Build();

            /*var font = SpriteFont.FromSprites(
             *  Graphics, Content.Get<Texture2D>("Data/ascii.png"), new Vector2(10f, 18f), Vector2.Zero, new Vector2(16f, 16f), 256 / 16,
             *  " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
             * );*/
            var font = SpriteFont.FromFont(Graphics, "Arial", FontStyle.Regular, 20.0f, 20f, true, '\n', (char)127, 16);

            TextRenderer = new TextRenderer(Graphics, font, "Data/text.vert.spv", "Data/text.frag.spv", 128);
            TextRenderer.BuildPipeline();
            TextInstances = new[] { new TextRenderer.TextInstance(Vector2.Zero, Vector2.One, Color4.LightGray, 1, new Color4(0f, 0f, 0f, 1f), new Vector2(0f, 0f), Vector2.Zero, "N/A") };

            MeshRenderer = new MeshRenderer(Graphics, Content.Get <Texture2D>("Data/tex.png"), "Data/mesh.vert.spv", "Data/mesh.frag.spv", 32, 4);
            MeshRenderer.BuildPipeline();
            MeshRenderer.SetMeshInfo(
                new[] {
                MeshRenderer.CreateMeshInfo(
                    Mesh.FromPolygon(Graphics, new[]
                {
                    new Vertex(new Vector3(-180f, -90f, 0f), new Vector3(0f, 0f, 1f), new Vector2(0f, 0f), Color4.White),
                    new Vertex(new Vector3(0f, -180f, 0f), new Vector3(0f, 0f, 1f), new Vector2(0.5f, 0f), Color4.White),
                    new Vertex(new Vector3(180f, 0f, 0f), new Vector3(0f, 0f, 1f), new Vector2(1f, 0.2f), Color4.White),
                    new Vertex(new Vector3(0f, 120f, 0f), new Vector3(0f, 0f, 1f), new Vector2(0f, 1f), Color4.White),
                    new Vertex(new Vector3(-180f, 90f, 0f), new Vector3(0f, 0f, 1f), new Vector2(0.1f, 1f), Color4.White)
                }),
                    new Sprite(new Vector2(0f, 0f), new Vector2(64f, 64f)),
                    new Vector3(400f, 300f, 0f),
                    Vector3.One,
                    Matrix4.CreateRotationZ(0f),
                    Vector3.Zero
                    ),
                MeshRenderer.CreateMeshInfo(
                    new Mesh(
                        Graphics,
                        new Vertex[]
                {
                    new Vertex(new Vector3(-180f, -90f, 0f), new Vector3(0f, 0f, 1f), new Vector2(0f, 0f), Color4.White),
                    new Vertex(new Vector3(0f, -90f, 0f), new Vector3(0f, 0f, 1f), new Vector2(1f, 0f), Color4.White),
                    new Vertex(new Vector3(180f, 90f, 0f), new Vector3(0f, 0f, 1f), new Vector2(1f, 1f), Color4.White),
                    new Vertex(new Vector3(0f, 90f, 0f), new Vector3(0f, 0f, 1f), new Vector2(0f, 1f), Color4.White)
                },
                        new int[] { 0, 1, 2, 2, 3, 0 }
                        ),
                    new Sprite(new Vector2(0f, 0f), new Vector2(64f, 64f)),
                    new Vector3(580f, 300f, 0f),
                    Vector3.One,
                    Matrix4.CreateRotationZ(0f),
                    Vector3.Zero
                    )
            },
                2
                );

            ParticleRenderer = new ParticleRenderer(
                Graphics, Content.Get <Texture2D>("Data/fire.png"),
                new Sprite(Vector2.Zero, new Vector2(64f, 64f), new Vector2(64f, 64f)),
                "Data/particle.vert.spv", "Data/particle.frag.spv", 900000
                );
            ParticleRenderer.BlendMode = BlendMode.Add;
            ParticleRenderer.BuildPipeline();
        }
Beispiel #4
0
        private void RecreateInstanceBuffers()
        {
            // Create sets
            var listInd = 0;

            foreach (var keyList in InstanceLists.Where(e => e.Value.Count > 0))
            {
                var list = keyList.Value;
                VKBuffer <SpriteInstanceInfo> computeBuffer;
                if (!ComputeInstanceBuffers.TryGetValue(list, out computeBuffer))
                {
                    computeBuffer = VKBuffer <SpriteInstanceInfo> .StorageBuffer(
                        $"{nameof(SpriteEffect)} compute instance buffer for list {list}",
                        Graphics,
                        MaxSprites
                        );

                    ComputeInstanceBuffers.Add(list, computeBuffer);
                }
                VKBuffer <VertexInstance> vertexBuffer;
                if (!VertexInstanceBuffers.TryGetValue(list, out vertexBuffer))
                {
                    vertexBuffer = VKBuffer <VertexInstance> .StorageBuffer(
                        $"{nameof(SpriteEffect)} vertex instance buffer for list {list}",
                        Graphics,
                        MaxSprites
                        );

                    VertexInstanceBuffers.Add(list, vertexBuffer);
                }
                using (var stagingBuffer = VKBuffer <SpriteInstanceInfo> .StagingBuffer(
                           $"{nameof(SpriteEffect)}.{nameof(RecreateInstanceBuffers)} staging buffer",
                           Graphics,
                           list.Count
                           ))
                {
                    unsafe
                    {
                        var ptr = stagingBuffer.Map(0, list.Count);
                        if (list.Updated)
                        {
                            var i = 0;
                            foreach (SpriteInstance inst in list.AllInstances)
                            {
                                if (i > MaxSprites)
                                {
                                    throw new InvalidOperationException("Too many similar sprites; raise the sprite limit on the effect");
                                }
                                *ptr = new SpriteInstanceInfo
                                {
                                    Time          = 0f,
                                    Position      = inst.StoredPosition,
                                    Velocity      = inst.StoredVelocity,
                                    Scale         = inst.StoredScale,
                                    Rotation      = inst.StoredRotation,
                                    ListIndex     = listInd,
                                    Rectangle     = inst.Rectangle,
                                    AnimationTime = inst.AnimationTime
                                };
                                ptr++;
                                i++;
                            }
                        }
                        else
                        {
                            foreach (SpriteInstance inst in list.AllInstances)
                            {
                                (*ptr).ListIndex = listInd;
                                ptr++;
                            }
                        }
                        stagingBuffer.Unmap();
                    }
                    using (var stagingFence = Graphics.Device.CreateFence(new FenceCreateInfo()))
                    {
                        using (var stagingCommands = Graphics.TransferQueueFamily.CreateCommandBuffers(CommandBufferLevel.Primary, 1)[0])
                        {
                            stagingCommands.Begin();
                            stagingCommands.CmdPipelineBarrier(
                                PipelineStages.TopOfPipe, PipelineStages.Transfer,
                                bufferMemoryBarriers: new BufferMemoryBarrier[]
                            {
                                new BufferMemoryBarrier(
                                    computeBuffer.Buffer,
                                    Accesses.None, Accesses.TransferWrite,
                                    0L, stagingBuffer.Size
                                    )
                            }
                                );
                            stagingCommands.CmdCopyBuffer(
                                stagingBuffer.Buffer,
                                computeBuffer.Buffer,
                                new BufferCopy[] { new BufferCopy(stagingBuffer.Size) }
                                );
                            stagingCommands.CmdPipelineBarrier(
                                PipelineStages.Transfer, PipelineStages.ComputeShader,
                                bufferMemoryBarriers: new BufferMemoryBarrier[]
                            {
                                new BufferMemoryBarrier(
                                    computeBuffer.Buffer,
                                    Accesses.TransferWrite, Accesses.ShaderRead,
                                    0L, stagingBuffer.Size
                                    )
                            }
                                );
                            stagingCommands.CmdPipelineBarrier(
                                PipelineStages.Transfer, PipelineStages.VertexInput,
                                bufferMemoryBarriers: new BufferMemoryBarrier[]
                            {
                                new BufferMemoryBarrier(
                                    vertexBuffer.Buffer,
                                    Accesses.TransferWrite, Accesses.VertexAttributeRead
                                    )
                            }
                                );
                            stagingCommands.End();

                            Graphics.TransferQueueFamily.HighestPriority.Submit(
                                new SubmitInfo(
                                    commandBuffers: new CommandBuffer[] { stagingCommands }
                                    ),
                                stagingFence
                                );
                            stagingFence.Wait();
                        }
                    }
                }
                listInd++;
            }
        }
Beispiel #5
0
        public override void OnStart()
        {
            ComputeShader  = Graphics.Content.LoadShaderModule(Path.Combine("Sprites", "BasicSprites.comp.spv"));
            VertexShader   = Graphics.Content.LoadShaderModule(Path.Combine("Sprites", "BasicSprites.vert.spv"));
            FragmentShader = Graphics.Content.LoadShaderModule(Path.Combine("Sprites", "BasicSprites.frag.spv"));
            TextureSampler = Graphics.Device.CreateSampler(new SamplerCreateInfo
            {
                MinFilter = Filter.Linear,
                MagFilter = Filter.Linear
            });
            GraphicsDescriptorPool = Graphics.Device.CreateDescriptorPool(new DescriptorPoolCreateInfo(
                                                                              MaxSets, new DescriptorPoolSize[]
            {
                new DescriptorPoolSize(DescriptorType.UniformBuffer, MaxSets),
                new DescriptorPoolSize(DescriptorType.CombinedImageSampler, MaxSets),
                new DescriptorPoolSize(DescriptorType.UniformBuffer, MaxSets)
            },
                                                                              DescriptorPoolCreateFlags.FreeDescriptorSet
                                                                              ));
            ComputeDescriptorPool = Graphics.Device.CreateDescriptorPool(new DescriptorPoolCreateInfo(
                                                                             MaxSets, new DescriptorPoolSize[]
            {
                new DescriptorPoolSize(DescriptorType.StorageBuffer, MaxSets),
                new DescriptorPoolSize(DescriptorType.UniformBuffer, MaxSets),
                new DescriptorPoolSize(DescriptorType.UniformBuffer, MaxSets)
            },
                                                                             DescriptorPoolCreateFlags.FreeDescriptorSet
                                                                             ));
            GraphicsDescriptorSetLayout = Graphics.Device.CreateDescriptorSetLayout(new DescriptorSetLayoutCreateInfo(
                                                                                        new[]
            {
                new DescriptorSetLayoutBinding(
                    binding: 0,
                    descriptorType: DescriptorType.UniformBuffer,
                    descriptorCount: 1,
                    stageFlags: ShaderStages.Vertex
                    ),
                new DescriptorSetLayoutBinding(
                    binding: 1,
                    descriptorType: DescriptorType.CombinedImageSampler,
                    descriptorCount: 1,
                    stageFlags: ShaderStages.Fragment
                    ),
                new DescriptorSetLayoutBinding(
                    binding: 2,
                    descriptorType: DescriptorType.UniformBuffer,
                    descriptorCount: 1,
                    stageFlags: ShaderStages.Vertex
                    )
            }
                                                                                        ));
            ComputeDescriptorSetLayout = Graphics.Device.CreateDescriptorSetLayout(new DescriptorSetLayoutCreateInfo(
                                                                                       new[]
            {
                new DescriptorSetLayoutBinding(
                    binding: 0,
                    descriptorType: DescriptorType.StorageBuffer,
                    descriptorCount: 1,
                    stageFlags: ShaderStages.Compute
                    ),
                new DescriptorSetLayoutBinding(
                    binding: 1,
                    descriptorType: DescriptorType.StorageBuffer,
                    descriptorCount: 1,
                    stageFlags: ShaderStages.Compute
                    ),
                new DescriptorSetLayoutBinding(
                    binding: 2,
                    descriptorType: DescriptorType.UniformBuffer,
                    descriptorCount: 1,
                    stageFlags: ShaderStages.Compute
                    ),
                new DescriptorSetLayoutBinding(
                    binding: 3,
                    descriptorType: DescriptorType.UniformBuffer,
                    descriptorCount: 1,
                    stageFlags: ShaderStages.Compute
                    )
            }
                                                                                       ));
            GraphicsPipelineLayout = Graphics.Device.CreatePipelineLayout(new PipelineLayoutCreateInfo(
                                                                              setLayouts: new[] { GraphicsDescriptorSetLayout }
                                                                              ));
            ComputePipelineLayout = Graphics.Device.CreatePipelineLayout(new PipelineLayoutCreateInfo(
                                                                             setLayouts: new[] { ComputeDescriptorSetLayout }
                                                                             ));
            GraphicsPipeline = Graphics.Device.CreateGraphicsPipeline(new GraphicsPipelineCreateInfo(
                                                                          layout: GraphicsPipelineLayout,
                                                                          renderPass: RenderPass.RenderPass,
                                                                          subpass: 0,
                                                                          stages: new[]
            {
                new PipelineShaderStageCreateInfo(ShaderStages.Vertex, VertexShader, "main"),
                new PipelineShaderStageCreateInfo(ShaderStages.Fragment, FragmentShader, "main")
            },
                                                                          inputAssemblyState: new PipelineInputAssemblyStateCreateInfo(PrimitiveTopology.TriangleList),
                                                                          vertexInputState: new PipelineVertexInputStateCreateInfo(
                                                                              new VertexInputBindingDescription[]
            {
                new VertexInputBindingDescription(
                    0,
                    Interop.SizeOf <VertexInstance>(),
                    VertexInputRate.Instance
                    )
            },
                                                                              new VertexInputAttributeDescription[]
            {
                new VertexInputAttributeDescription(                 // Transform matrix row 0
                    0, 0, Format.R32G32B32A32SFloat, 0
                    ),
                new VertexInputAttributeDescription(                 // Transform matrix row 1
                    1, 0, Format.R32G32B32A32SFloat, 16
                    ),
                new VertexInputAttributeDescription(                 // Transform matrix row 2
                    2, 0, Format.R32G32B32A32SFloat, 32
                    ),
                new VertexInputAttributeDescription(                 // Transform matrix row 03
                    3, 0, Format.R32G32B32A32SFloat, 48
                    ),
                new VertexInputAttributeDescription(                 // Rectangle
                    4, 0, Format.R32G32B32A32SFloat, 64
                    )
            }
                                                                              ),
                                                                          rasterizationState: new PipelineRasterizationStateCreateInfo(
                                                                              polygonMode: PolygonMode.Fill,
                                                                              cullMode: CullModes.None,
                                                                              frontFace: FrontFace.Clockwise,
                                                                              lineWidth: 1f
                                                                              ),
                                                                          viewportState: new PipelineViewportStateCreateInfo(
                                                                              new Viewport(0f, 0f, Graphics.Window.Size.X, Graphics.Window.Size.Y),
                                                                              new Rect2D(0, 0, (int)Graphics.Window.Size.X, (int)Graphics.Window.Size.Y)
                                                                              ),
                                                                          multisampleState: new PipelineMultisampleStateCreateInfo(
                                                                              rasterizationSamples: SampleCounts.Count1,
                                                                              minSampleShading: 1
                                                                              ),
                                                                          colorBlendState: new PipelineColorBlendStateCreateInfo(
                                                                              attachments: new[]
            {
                BlendStates.AlphaPremultiplied
            }
                                                                              )
                                                                          ));
            ComputePipeline = Graphics.Device.CreateComputePipeline(new ComputePipelineCreateInfo(
                                                                        stage: new PipelineShaderStageCreateInfo(ShaderStages.Compute, ComputeShader, "main"),
                                                                        layout: ComputePipelineLayout,
                                                                        flags: PipelineCreateFlags.None
                                                                        ));
            CameraUniform = VKBuffer <CameraUniformBlock> .UniformBuffer(
                $"{nameof(SpriteEffect)}.{nameof(CameraUniform)}",
                Graphics,
                1
                );

            TimeUniform = VKBuffer <ListTime> .UniformBuffer(
                $"{nameof(SpriteEffect)}.{nameof(TimeUniform)}",
                Graphics,
                MaxSets
                );

            AnimationUniform = VKBuffer <Animation.ComputeInstruction> .UniformBuffer(
                $"{nameof(SpriteEffect)}.{nameof(AnimationUniform)}",
                Graphics,
                Animation.MaxInstructions *MaxSets
                );

            ComputeSemaphore = Graphics.Device.CreateSemaphore();
            SetCamera(Vector2.Zero, new Vector2(Graphics.Window.Size.X, -Graphics.Window.Size.Y));
        }