Created
June 4, 2020 13:47
-
-
Save TinkerWorX/d4c06aadd16aff9b29bd0cd8a601eaf1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Numerics; | |
using System.Text; | |
using Veldrid; | |
using Veldrid.SPIRV; | |
namespace Desolation.Graphics | |
{ | |
public unsafe class QuadRenderer : IDisposable | |
{ | |
private const string VertexCode = @" | |
#version 450 | |
layout (location = 0) in vec3 Position; | |
layout (location = 1) in vec4 Color; | |
layout (location = 2) in vec2 TexCoords; | |
layout(set = 0, binding = 0) uniform vTransformBuffer | |
{ | |
mat4x4 transform; | |
}; | |
layout (location = 0) out vec4 fColor; | |
layout (location = 1) out vec2 fTexCoords; | |
void main() | |
{ | |
gl_Position = transform * vec4(Position, 1.00); | |
fColor = Color; | |
fTexCoords = TexCoords; | |
}"; | |
private const string FragmentCode = @" | |
#version 450 | |
layout (location = 0) in vec4 fColor; | |
layout (location = 1) in vec2 fTexCoords; | |
layout(set = 1, binding = 0) uniform texture2D fTexture; | |
layout(set = 1, binding = 1) uniform sampler fTextureSampler; | |
layout (location = 0) out vec4 fOutColor; | |
void main() | |
{ | |
fOutColor = texture(sampler2D(fTexture, fTextureSampler), fTexCoords) * fColor; | |
}"; | |
private readonly DeviceBuffer vertexBuffer; | |
private readonly DeviceBuffer indexBuffer; | |
private readonly DeviceBuffer transformBuffer; | |
private readonly Shader[] shaders; | |
private readonly Pipeline pipeline; | |
private readonly ResourceSet transformSet; | |
private readonly ResourceSet textureSet; | |
public QuadRenderer(GraphicsDevice graphicsDevice, Texture texture, TextureView textureView) | |
{ | |
var factory = graphicsDevice.ResourceFactory; | |
this.transformBuffer = factory.CreateBuffer(new BufferDescription((uint)sizeof(Matrix4x4), BufferUsage.UniformBuffer)); | |
var quadVertices = new[] | |
{ | |
new VertexPositionColorTexCoords(new Vector3(-0.75f, -0.75f, 0.00f), RgbaByte.Blue, new Vector2(0.00f, 0.00f)), | |
new VertexPositionColorTexCoords(new Vector3(+0.75f, -0.75f, 0.00f), RgbaByte.Yellow, new Vector2(1.00f, 0.00f)), | |
new VertexPositionColorTexCoords(new Vector3(-0.75f, +0.75f, 0.00f), RgbaByte.Red, new Vector2(0.00f, 1.00f)), | |
new VertexPositionColorTexCoords(new Vector3(+0.75f, +0.75f, 0.00f), RgbaByte.Green, new Vector2(1.00f, 1.00f)), | |
}; | |
this.vertexBuffer = factory.CreateBuffer(new BufferDescription((uint)(quadVertices.Length * sizeof(VertexPositionColorTexCoords)), BufferUsage.VertexBuffer)); | |
graphicsDevice.UpdateBuffer(this.vertexBuffer, 0, quadVertices); | |
ushort[] quadIndices = { 0, 1, 2, 1, 3, 2 }; | |
this.indexBuffer = factory.CreateBuffer(new BufferDescription((uint)(quadIndices.Length * sizeof(ushort)), BufferUsage.IndexBuffer)); | |
graphicsDevice.UpdateBuffer(this.indexBuffer, 0, quadIndices); | |
var vertexShaderDesc = new ShaderDescription(ShaderStages.Vertex, Encoding.UTF8.GetBytes(VertexCode), "main"); | |
var fragmentShaderDesc = new ShaderDescription(ShaderStages.Fragment, Encoding.UTF8.GetBytes(FragmentCode), "main"); | |
this.shaders = factory.CreateFromSpirv(vertexShaderDesc, fragmentShaderDesc, new CrossCompileOptions(false, true)); | |
var transformLayout = factory.CreateResourceLayout( | |
new ResourceLayoutDescription( | |
new ResourceLayoutElementDescription("vTransformBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex))); | |
this.transformSet = factory.CreateResourceSet(new ResourceSetDescription(transformLayout, this.transformBuffer)); | |
var textureLayout = factory.CreateResourceLayout( | |
new ResourceLayoutDescription( | |
new ResourceLayoutElementDescription("fTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment), | |
new ResourceLayoutElementDescription("fTextureSampler", ResourceKind.Sampler, ShaderStages.Fragment))); | |
this.textureSet = factory.CreateResourceSet(new ResourceSetDescription(textureLayout, textureView, graphicsDevice.Aniso4xSampler)); | |
// Create pipeline | |
var pipelineDescription = new GraphicsPipelineDescription | |
{ | |
BlendState = BlendStateDescription.SingleOverrideBlend, | |
DepthStencilState = new DepthStencilStateDescription(depthTestEnabled: true, depthWriteEnabled: true, comparisonKind: ComparisonKind.LessEqual), | |
RasterizerState = new RasterizerStateDescription(cullMode: FaceCullMode.None, fillMode: PolygonFillMode.Solid, frontFace: FrontFace.Clockwise, depthClipEnabled: true, scissorTestEnabled: false), | |
PrimitiveTopology = PrimitiveTopology.TriangleStrip, | |
ShaderSet = new ShaderSetDescription(vertexLayouts: new[] { VertexPositionColorTexCoords.VertexLayoutDescription }, shaders: this.shaders), | |
ResourceLayouts = new[] { transformLayout, textureLayout }, | |
Outputs = graphicsDevice.SwapchainFramebuffer.OutputDescription, | |
}; | |
this.pipeline = factory.CreateGraphicsPipeline(pipelineDescription); | |
} | |
public void Render(CommandList commandList) | |
{ | |
commandList.UpdateBuffer(this.transformBuffer, 0, Matrix4x4.Identity); | |
// Set all relevant state to draw our quad. | |
commandList.SetVertexBuffer(0, this.vertexBuffer); | |
commandList.SetIndexBuffer(this.indexBuffer, IndexFormat.UInt16); | |
commandList.SetPipeline(this.pipeline); | |
commandList.SetGraphicsResourceSet(0, this.transformSet); | |
commandList.SetGraphicsResourceSet(1, this.textureSet); | |
// Issue a Draw command for a single instance with 6 indices. | |
commandList.DrawIndexed(indexCount: 6, instanceCount: 1, indexStart: 0, vertexOffset: 0, instanceStart: 0); | |
} | |
public void Dispose() | |
{ | |
this.pipeline.Dispose(); | |
foreach (var shader in this.shaders) | |
{ | |
shader.Dispose(); | |
} | |
this.indexBuffer.Dispose(); | |
this.vertexBuffer.Dispose(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment