void RenderTriangle(CommandBuffer cmdBuffer, VertexData vertexData, RenderPass renderPass, Pipeline pipeline, Framebuffer framebuffer, uint width, uint height) { // Set the viewport var viewport = new Viewport(0, 0, width, height, 0, 0); cmdBuffer.SetViewport(0, new[] { viewport }); // Begin the render pass. Just as all commands must be issued between a Begin() // and End() call, certain commands can only be called bewteen BeginRenderPass() // and EndRenderPass() var renderArea = new Rect2D(new Offset2D(0, 0), new Extent2D(width, height)); var renderPassBegin = new RenderPassBeginInfo(renderPass, framebuffer, renderArea, null); cmdBuffer.BeginRenderPass(renderPassBegin, SubpassContents.Inline); renderPassBegin.Dispose(); cmdBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline); // Render the triangle cmdBuffer.BindVertexBuffers(0, new[] { vertexData.Buffer }, new DeviceSize[] { 0 }); cmdBuffer.Draw(3, 1, 0, 0); // End the RenderPass cmdBuffer.EndRenderPass(); }
void RenderTriangle(CommandBuffer cmdBuffer, VertexData vertexData, RenderPass renderPass, Framebuffer framebuffer, Pipeline pipeline, uint width, uint height) { // Set the viewport var viewport = new Viewport(0, 0, width, height, 0, 0); cmdBuffer.SetViewport(0, new[] { viewport }); var renderArea = new Rect2D(new Offset2D(0, 0), new Extent2D(width, height)); var renderPassBegin = new RenderPassBeginInfo(renderPass, framebuffer, renderArea, null); cmdBuffer.BeginRenderPass(renderPassBegin, SubpassContents.Inline); renderPassBegin.Dispose(); cmdBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline); // Render the triangle cmdBuffer.BindVertexBuffers(0, new[] { vertexData.Buffer }, new DeviceSize[] { 0 }); cmdBuffer.Draw(3, 1, 0, 0); // End the RenderPass cmdBuffer.EndRenderPass(); }
void RenderTexturedQuad(CommandBuffer cmdBuffer, VertexData vertexData, ImageData imageData, PipelineLayout pipelineLayout, DescriptorSet descriptorSet, RenderPass renderPass, Pipeline pipeline, Framebuffer framebuffer, uint width, uint height) { var viewport = new Viewport(0, 0, width, height, 0, 1); cmdBuffer.SetViewport(0, new[] { viewport }); var renderArea = new Rect2D(new Offset2D(0, 0), new Extent2D(width, height)); var renderPassBegin = new RenderPassBeginInfo(renderPass, framebuffer, renderArea, null); cmdBuffer.BeginRenderPass(renderPassBegin, SubpassContents.Inline); renderPassBegin.Dispose(); cmdBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, new[] { descriptorSet }, null); cmdBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline); cmdBuffer.BindVertexBuffers(0, new[] { vertexData.Buffer }, new DeviceSize[] { 0 }); cmdBuffer.BindIndexBuffer(vertexData.IndexBuffer, 0, IndexType.Uint32); cmdBuffer.DrawIndexed((uint)vertexData.Indicies.Length, 1, 0, 0, 1); cmdBuffer.EndRenderPass(); }
private void DrawInternal() { // Update descriptors var descriptorSets = stackalloc DescriptorSet[2]; var setLayouts = stackalloc DescriptorSetLayout[2]; setLayouts[0] = setLayouts[1] = descriptorSetLayout; var allocateInfo = new DescriptorSetAllocateInfo { StructureType = StructureType.DescriptorSetAllocateInfo, DescriptorPool = descriptorPool, DescriptorSetCount = 2, SetLayouts = new IntPtr(setLayouts), }; device.AllocateDescriptorSets(ref allocateInfo, descriptorSets); var bufferInfo = new DescriptorBufferInfo { Buffer = uniformBuffer, Range = Vulkan.WholeSize }; var write = new WriteDescriptorSet { StructureType = StructureType.WriteDescriptorSet, DescriptorCount = 1, DestinationSet = descriptorSets[0], DestinationBinding = 0, DescriptorType = DescriptorType.UniformBuffer, BufferInfo = new IntPtr(&bufferInfo) }; var copy = new CopyDescriptorSet { StructureType = StructureType.CopyDescriptorSet, DescriptorCount = 1, SourceBinding = 0, DestinationBinding = 0, SourceSet = descriptorSets[0], DestinationSet = descriptorSets[1] }; device.UpdateDescriptorSets(1, &write, 0, null); device.UpdateDescriptorSets(0, null, 1, ©); // Post-present transition var memoryBarrier = new ImageMemoryBarrier { StructureType = StructureType.ImageMemoryBarrier, Image = backBuffers[currentBackBufferIndex], SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1), OldLayout = ImageLayout.PresentSource, NewLayout = ImageLayout.ColorAttachmentOptimal, SourceAccessMask = AccessFlags.MemoryRead, DestinationAccessMask = AccessFlags.ColorAttachmentWrite }; commandBuffer.PipelineBarrier(PipelineStageFlags.TopOfPipe, PipelineStageFlags.TopOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier); // Clear render target var clearRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1); commandBuffer.ClearColorImage(backBuffers[currentBackBufferIndex], ImageLayout.TransferDestinationOptimal, new RawColor4(0, 0, 0, 1), 1, &clearRange); // Begin render pass var renderPassBeginInfo = new RenderPassBeginInfo { StructureType = StructureType.RenderPassBeginInfo, RenderPass = renderPass, Framebuffer = framebuffers[currentBackBufferIndex], RenderArea = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height), }; commandBuffer.BeginRenderPass(ref renderPassBeginInfo, SubpassContents.Inline); // Bind pipeline commandBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline); // Bind descriptor sets commandBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, 1, descriptorSets + 1, 0, null); // Set viewport and scissor var viewport = new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height); commandBuffer.SetViewport(0, 1, &viewport); var scissor = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height); commandBuffer.SetScissor(0, 1, &scissor); // Bind vertex buffer var vertexBufferCopy = vertexBuffer; ulong offset = 0; commandBuffer.BindVertexBuffers(0, 1, &vertexBufferCopy, &offset); // Draw vertices commandBuffer.Draw(3, 1, 0, 0); // End render pass commandBuffer.EndRenderPass(); // Pre-present transition memoryBarrier = new ImageMemoryBarrier { StructureType = StructureType.ImageMemoryBarrier, Image = backBuffers[currentBackBufferIndex], SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1), OldLayout = ImageLayout.ColorAttachmentOptimal, NewLayout = ImageLayout.PresentSource, SourceAccessMask = AccessFlags.ColorAttachmentWrite, DestinationAccessMask = AccessFlags.MemoryRead }; commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, PipelineStageFlags.BottomOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier); }
public void Run() { try { // Load renderer renderer = RenderSystem.Load("OpenGL", debugger); // Create render context var contextDesc = new RenderContextDescriptor(); { contextDesc.VideoMode.Resolution.Width = 800; contextDesc.VideoMode.Resolution.Height = 600; contextDesc.VideoMode.ColorBits = 32; contextDesc.VideoMode.DepthBits = 24; contextDesc.VideoMode.StencilBits = 8; } context = renderer.CreateRenderContext(contextDesc); // Get context window var window = context.Surface; window.Shown = true; window.Title = $"LLGL for C# - Texturing ( {renderer.Name} )"; // Print renderer information Console.WriteLine("Renderer Info:"); var info = renderer.Info; { Console.WriteLine($" Renderer: {info.RendererName}"); Console.WriteLine($" Device: {info.DeviceName}"); Console.WriteLine($" Vendor: {info.VendorName}"); Console.WriteLine($" Shading Language: {info.ShadingLanguageName}"); } // Create vertex buffer var vertexFormat = new VertexFormat(); vertexFormat.AppendAttribute(new VertexAttribute("coord", Format.RG32Float)); vertexFormat.AppendAttribute(new VertexAttribute("texCoord", Format.RG32Float)); const float uvScale = 10.0f; var vertices = new Vertex[] { new Vertex(-0.5f, -0.5f, 0.0f, uvScale), new Vertex(-0.5f, +0.5f, 0.0f, 0.0f), new Vertex(+0.5f, -0.5f, uvScale, uvScale), new Vertex(+0.5f, +0.5f, uvScale, 0.0f), }; var vertexBufferDesc = new BufferDescriptor(); { vertexBufferDesc.BindFlags = BindFlags.VertexBuffer; vertexBufferDesc.Size = vertexFormat.Stride * (ulong)vertices.Length; vertexBufferDesc.VertexBuffer.Format = vertexFormat; } var vertexBuffer = renderer.CreateBuffer(vertexBufferDesc, vertices); // Create shaders var vertShader = renderer.CreateShader( new ShaderDescriptor( type: ShaderType.Vertex, sourceType: ShaderSourceType.CodeString, source: @" #version 330 core in vec2 coord; in vec2 texCoord; out vec2 vTexCoord; void main() { gl_Position = vec4(coord, 0, 1); vTexCoord = texCoord; } " ) ); var fragShader = renderer.CreateShader( new ShaderDescriptor ( type: ShaderType.Fragment, sourceType: ShaderSourceType.CodeString, source: @" #version 330 core in vec2 vTexCoord; out vec4 fColor; uniform sampler2D tex; void main() { fColor = texture(tex, vTexCoord); } " ) ); var shaderProgramDesc = new ShaderProgramDescriptor(); { shaderProgramDesc.VertexFormats.Add(vertexFormat); shaderProgramDesc.VertexShader = vertShader; shaderProgramDesc.FragmentShader = fragShader; } var shaderProgram = renderer.CreateShaderProgram(shaderProgramDesc); if (shaderProgram.HasErrors) { throw new Exception(shaderProgram.Report); } // Create pipeline layout var pipelineLayoutDesc = new PipelineLayoutDescriptor(); { pipelineLayoutDesc.Bindings.Add( new BindingDescriptor(ResourceType.Texture, BindFlags.Sampled, StageFlags.FragmentStage, 0) ); pipelineLayoutDesc.Bindings.Add( new BindingDescriptor(ResourceType.Sampler, 0, StageFlags.FragmentStage, 0) ); } var pipelineLayout = renderer.CreatePipelineLayout(pipelineLayoutDesc); // Create graphics pipeline var pipelineDesc = new GraphicsPipelineDescriptor(); { pipelineDesc.ShaderProgram = shaderProgram; pipelineDesc.PipelineLayout = pipelineLayout; pipelineDesc.PrimitiveTopology = PrimitiveTopology.TriangleStrip; pipelineDesc.Blend.Targets[0].BlendEnabled = true; } pipeline = renderer.CreateGraphicsPipeline(pipelineDesc); // Create texture var imageDesc = new SrcImageDescriptor <RGBA>(); { imageDesc.Format = ImageFormat.RGBA; imageDesc.DataType = DataType.UInt8; imageDesc.Data = new RGBA[4]; imageDesc.Data[0] = new RGBA(255, 0, 0, 255); imageDesc.Data[1] = new RGBA(0, 255, 0, 255); imageDesc.Data[2] = new RGBA(0, 0, 0, 0); imageDesc.Data[3] = new RGBA(0, 0, 0, 0); } var textureDesc = new TextureDescriptor(); { textureDesc.Type = TextureType.Texture2D; textureDesc.Extent = new Extent3D(2, 2, 1); } var texture = renderer.CreateTexture(textureDesc, imageDesc); // Create sampler var samplerDesc = new SamplerDescriptor(); { samplerDesc.MagFilter = SamplerFilter.Nearest; } var sampler = renderer.CreateSampler(samplerDesc); // Create resource heap var resourceHeapDesc = new ResourceHeapDescriptor(); { resourceHeapDesc.PipelineLayout = pipelineLayout; resourceHeapDesc.ResourceViews.Add(new ResourceViewDescriptor(texture)); resourceHeapDesc.ResourceViews.Add(new ResourceViewDescriptor(sampler)); } var resourceHeap = renderer.CreateResourceHeap(resourceHeapDesc); // Get command queue cmdQueue = renderer.CommandQueue; cmdBuffer = renderer.CreateCommandBuffer(); cmdBuffer.SetClearColor(0.1f, 0.1f, 0.2f, 1.0f); // Render loop while (window.ProcessEvents()) { cmdBuffer.Begin(); { cmdBuffer.SetVertexBuffer(vertexBuffer); cmdBuffer.BeginRenderPass(context); { cmdBuffer.Clear(ClearFlags.Color); cmdBuffer.SetViewport(new Viewport(0, 0, context.Resolution.Width, context.Resolution.Height)); cmdBuffer.SetGraphicsPipeline(pipeline); cmdBuffer.SetGraphicsResourceHeap(resourceHeap); cmdBuffer.Draw(4, 0); } cmdBuffer.EndRenderPass(); } cmdBuffer.End(); cmdQueue.Submit(cmdBuffer); context.Present(); } } catch (Exception e) { Console.WriteLine(e.ToString()); Console.WriteLine("press any key to continue ..."); Console.ReadKey(); } finally { RenderSystem.Unload(renderer); } }
/// <summary> /// /// </summary> public override Task Update() => Task.Run(() => { var swapchainIndexes = new Dictionary <Window, Task <uint> >(); var cameras = MyScene.GetComponents <Camera>(); var lights = MyScene.GetComponents <Light>(); var transferCommands = new List <CommandBuffer>(); // fetch instanced and non-instanced meshes var meshRenderers = ( MyScene.GetComponents <MeshRenderer>() .Where(m => m.Material.Instanced == false) .ToArray() ); _instancedMeshes.Wait(); #region record command buffers _renderCommand.Begin(Vulkan.VkCommandBufferUsageFlags.OneTimeSubmit); _deferredCommand.Begin(Vulkan.VkCommandBufferUsageFlags.OneTimeSubmit); _presentCommand.Begin(Vulkan.VkCommandBufferUsageFlags.OneTimeSubmit); var cameraTasks = new List <Task>(); foreach (var camera in cameras) { var window = camera.RenderTarget as Window; if (window != null) { swapchainIndexes.Add( window, window.AcquireSwapchainImage() ); } // update camera descriptor sets camera.UpdateDescriptorSets(); // update lighting information camera.UpdateLights(lights); #region transfer images layout int attachmentCount = 0; foreach (var attachment in camera.MrtFramebuffer.RenderPass.Attachments) { if (attachment.Format != API.RenderPassAttachment.Default.Format) { continue; } // transfer image layout to color attachment optimial // used in render command _renderCommand.TransferImageLayout( camera.MrtFramebuffer.Images[attachmentCount], Vulkan.VkImageLayout.ColorAttachmentOptimal ); // transfer image layout to shader read only optimal // used in deffered command _deferredCommand.TransferImageLayout( camera.MrtFramebuffer.Images[attachmentCount], Vulkan.VkImageLayout.ShaderReadOnlyOptimal ); // transfer image layout to color attachment optimal // used in deffered command _presentCommand.TransferImageLayout( camera.MrtFramebuffer.Images[attachmentCount], Vulkan.VkImageLayout.ColorAttachmentOptimal ); attachmentCount++; } #endregion #region mesh draw commands _renderCommand.BeginRenderPass( camera.MrtFramebuffer, Vulkan.VkSubpassContents.SecondaryCommandBuffers ); var secondaryDrawCommands = new List <Task <API.CommandBuffer> >(); // non-instanced foreach (var meshRenderer in meshRenderers) { // setup mesh draw command secondaryDrawCommands.Add(Task.Run(() => { // transfer material textures to the correct image layout transferCommands.Add(meshRenderer.Material.TransferImages()); // update mesh render descriptor sets meshRenderer.UpdateDescriptorSet(); return(meshRenderer.DrawCommand( camera.MrtFramebuffer, 0, camera.ProjectionDescriptorSet, camera.ViewDescriptorSet, camera.Viewport, camera.Resolution )); })); } foreach (var mesh in _instancedMeshes.Result) { secondaryDrawCommands.Add(Task.Run(() => { // transfer material textures to the correct image layout transferCommands.Add(mesh.Key.Key.TransferImages()); // update instanced buffers transferCommands.Add(mesh.Key.Key.UpdateInstanceBuffers( mesh.Key.Value, mesh.Value )); return(mesh.Key.Key.DrawInstanced( mesh.Key.Value, mesh.Value, camera.MrtFramebuffer, 0, camera.ProjectionDescriptorSet, camera.ViewDescriptorSet, camera.Viewport, camera.Resolution )); })); } Task.WaitAll(secondaryDrawCommands.ToArray()); // execute all draw comands for meshes if (secondaryDrawCommands.Count > 0) { _renderCommand.ExecuteCommands(secondaryDrawCommands.Select(s => s.Result).ToList()); } _renderCommand.EndRenderPass(); #endregion #region deffered commands _deferredCommand.BeginRenderPass( camera.DefferedFramebuffer, Vulkan.VkSubpassContents.Inline ); _deferredCommand.BindPipeline(Camera.DefferedPipeline); _deferredCommand.BindDescriptorSets( Camera.DefferedPipeline, camera.MrtDescriptorSets ); _deferredCommand.SetScissor( 0, 0, camera.DefferedFramebuffer.Width, camera.DefferedFramebuffer.Height ); _deferredCommand.SetViewport( 0, 0, camera.DefferedFramebuffer.Width, camera.DefferedFramebuffer.Height ); _deferredCommand.Draw(6, 1); _deferredCommand.EndRenderPass(); #endregion #region update render targets if (camera.RenderTarget != null) { _presentCommand.TransferImageLayout( camera.DefferedFramebuffer.Images[0], Vulkan.VkImageLayout.TransferSrcOptimal ); _presentCommand.TransferImageLayout( camera.RenderTarget.RenderedImage, Vulkan.VkImageLayout.TransferDstOptimal ); // copy image from camera framebuffer to render target _presentCommand.BlitImage( camera.DefferedFramebuffer.Images[0].Handle, camera.DefferedFramebuffer.Images[0].Format, camera.DefferedFramebuffer.Images[0].Layout.First(), 0, 0, (int)camera.DefferedFramebuffer.Width, (int)camera.DefferedFramebuffer.Height, 0, camera.RenderTarget.RenderedImage.Handle, camera.RenderTarget.RenderedImage.Format, camera.RenderTarget.RenderedImage.Layout.First(), 0, 0, (int)camera.RenderTarget.RenderedImage.Width, (int)camera.RenderTarget.RenderedImage.Height, 0 ); } #endregion } _renderCommand.End(); _deferredCommand.End(); #endregion #region submit commands var transformCommandSemaphores = new List <Semaphore>(); transferCommands = transferCommands.Where(t => t != null).ToList(); if (transferCommands.Count > 0) { // submit transfer command _module.CommandBufferService.Submit( transferCommands, new List <Semaphore> { _transferCommandSemaphore } ); transformCommandSemaphores.Add(_transferCommandSemaphore); } // submit render commnad _module.CommandBufferService.Submit( _renderCommand, new List <Semaphore> { _renderCommandSemaphore }, transformCommandSemaphores ); // submit deffered command _module.CommandBufferService.Submit( _deferredCommand, new List <Semaphore> { _defferedCommandSemaphore }, new List <Semaphore> { _renderCommandSemaphore } ); #endregion #region update render targets foreach (var swapchain in swapchainIndexes) { swapchain.Value.Wait(); var swapchainIndex = (int)swapchain.Value.Result; var window = swapchain.Key; _presentCommand.TransferImageLayout( window.RenderedImage, Vulkan.VkImageLayout.TransferSrcOptimal ); _presentCommand.TransferImageLayout( window.Swapchain.Images[swapchainIndex], Vulkan.VkImageLayout.TransferDstOptimal ); _presentCommand.BlitImage( window.RenderedImage.Handle, window.RenderedImage.Format, window.RenderedImage.Layout.First(), 0, 0, (int)window.RenderedImage.Width, (int)window.RenderedImage.Height, 0, window.Swapchain.Images[swapchainIndex].Handle, window.Swapchain.Images[swapchainIndex].Format, window.Swapchain.Images[swapchainIndex].Layout.First(), 0, 0, (int)window.Swapchain.SurfaceExtent.width, (int)window.Swapchain.SurfaceExtent.height, 0 ); _presentCommand.TransferImageLayout( window.Swapchain.Images[swapchainIndex], Vulkan.VkImageLayout.PresentSrcKHR ); } _presentCommand.End(); _module.CommandBufferService.Submit( _presentCommand, new List <Semaphore> { _presentCommandSemaphore }, new List <Semaphore> { _defferedCommandSemaphore } ); #endregion #region update swapchain foreach (var swapchain in swapchainIndexes) { var window = swapchain.Key; _module.CommandBufferService.Present( window.Swapchain, swapchain.Value.Result, new List <Semaphore> { _presentCommandSemaphore } ); } #endregion });
public void Run() { try { // Load renderer renderer = RenderSystem.Load("OpenGL", debugger); // Create render context var contextDesc = new RenderContextDescriptor(); { contextDesc.VideoMode.Resolution.Width = 800; contextDesc.VideoMode.Resolution.Height = 600; contextDesc.VideoMode.ColorBits = 32; contextDesc.VideoMode.DepthBits = 24; contextDesc.VideoMode.StencilBits = 8; contextDesc.ProfileOpenGL.ContextProfile = OpenGLContextProfile.CoreProfile; } context = renderer.CreateRenderContext(contextDesc); // Get context window var window = context.Surface; window.Shown = true; window.Title = $"LLGL for C# - HelloTriangle ( {renderer.Name} )"; // Print renderer information Console.WriteLine("Renderer Info:"); var info = renderer.Info; { Console.WriteLine($" Renderer: {info.RendererName}"); Console.WriteLine($" Device: {info.DeviceName}"); Console.WriteLine($" Vendor: {info.VendorName}"); Console.WriteLine($" Shading Language: {info.ShadingLanguageName}"); } // Create vertex buffer var vertexFormat = new VertexFormat(); vertexFormat.AppendAttribute(new VertexAttribute("coord", Format.RGBA32Float)); vertexFormat.AppendAttribute(new VertexAttribute("color", Format.RGBA8UNorm)); var vertices = new Vertex[] { new Vertex { x = 0.0f, y = 0.5f, z = 0.0f, w = 1.0f, r = 255, g = 0, b = 0, a = 255 }, new Vertex { x = 0.5f, y = -0.5f, z = 0.0f, w = 1.0f, r = 0, g = 255, b = 0, a = 255 }, new Vertex { x = -0.5f, y = -0.5f, z = 0.0f, w = 1.0f, r = 0, g = 0, b = 255, a = 255 }, }; var vertexBufferDesc = new BufferDescriptor(); { vertexBufferDesc.Type = BufferType.Vertex; vertexBufferDesc.Size = vertexFormat.Stride * (ulong)vertices.Length; vertexBufferDesc.VertexBuffer.Format = vertexFormat; } var vertexBuffer = renderer.CreateBuffer(vertexBufferDesc, vertices); // Create shaders var vertShader = renderer.CreateShader( new ShaderDescriptor( type: ShaderType.Vertex, sourceType: ShaderSourceType.CodeString, source: @" #version 330 core in vec4 coord; in vec3 color; out vec4 vColor; void main() { gl_Position = coord; vColor = vec4(color, 1); } " ) ); var fragShader = renderer.CreateShader( new ShaderDescriptor ( type: ShaderType.Fragment, sourceType: ShaderSourceType.CodeString, source: @" #version 330 core in vec4 vColor; out vec4 fColor; void main() { fColor = vColor; } " ) ); var shaderProgramDesc = new ShaderProgramDescriptor(); { shaderProgramDesc.VertexFormats.Add(vertexFormat); shaderProgramDesc.VertexShader = vertShader; shaderProgramDesc.FragmentShader = fragShader; } var shaderProgram = renderer.CreateShaderProgram(shaderProgramDesc); if (shaderProgram.HasErrors) { throw new Exception(shaderProgram.QueryInfoLog()); } // Create graphics pipeline var pipelineDesc = new GraphicsPipelineDescriptor(); { pipelineDesc.ShaderProgram = shaderProgram; } pipeline = renderer.CreateGraphicsPipeline(pipelineDesc); // Get command queue cmdQueue = renderer.CommandQueue; cmdBuffer = renderer.CreateCommandBuffer(); cmdBuffer.SetClearColor(0.1f, 0.1f, 0.2f, 1.0f); // Render loop while (window.ProcessEvents()) { cmdBuffer.Begin(); { cmdBuffer.SetVertexBuffer(vertexBuffer); cmdBuffer.BeginRenderPass(context); { cmdBuffer.Clear(ClearFlags.Color); cmdBuffer.SetViewport(new Viewport(context.Resolution)); cmdBuffer.SetGraphicsPipeline(pipeline); cmdBuffer.Draw(3, 0); } cmdBuffer.EndRenderPass(); } cmdBuffer.End(); cmdQueue.Submit(cmdBuffer); context.Present(); } } catch (Exception e) { Console.WriteLine(e.ToString()); Console.WriteLine("press any key to continue ..."); Console.ReadKey(); } finally { RenderSystem.Unload(renderer); } }