unsafe public override void Render(Renderer.IndirectDrawEncoder encoder, SceneRenderPipeline sp) { if (!IsVisible) { return; } if (NvmResource == null || !NvmResource.IsLoaded || NvmResource.Get() == null) { return; } if (NvmResource.TryLock()) { var resource = NvmResource.Get(); var geombuffer = resource.GeomBuffer; if (geombuffer.AllocStatus != VertexIndexBufferAllocator.VertexIndexBufferHandle.Status.Resident) { NvmResource.Unlock(); return; } uint indexStart = geombuffer.IAllocationStart / 4u; var args = new Renderer.IndirectDrawIndexedArgumentsPacked(); args.FirstInstance = WorldBuffer.AllocationStart / (uint)sizeof(InstanceData); args.VertexOffset = (int)(geombuffer.VAllocationStart / Resource.CollisionLayout.SizeInBytes); args.InstanceCount = 1; args.FirstIndex = indexStart; args.IndexCount = geombuffer.IAllocationSize / 4u; encoder.AddDraw(ref args, geombuffer.BufferIndex, RenderPipeline, PerObjRS, IndexFormat.UInt32); NvmResource.Unlock(); } }
public override void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneRenderPipeline sp) { var factory = gd.ResourceFactory; WorldBuffer = Renderer.UniformBufferAllocator.Allocate(128, 128); WorldBuffer.FillBuffer(cl, ref _World); VertexLayoutDescription[] mainVertexLayouts = new VertexLayoutDescription[] { new VertexLayoutDescription( new VertexElementDescription("position", VertexElementSemantic.TextureCoordinate, Veldrid.VertexElementFormat.Float3), new VertexElementDescription("normal", VertexElementSemantic.TextureCoordinate, Veldrid.VertexElementFormat.SByte4), new VertexElementDescription("color", VertexElementSemantic.TextureCoordinate, Veldrid.VertexElementFormat.Byte4)) }; var res = StaticResourceCache.GetShaders(gd, gd.ResourceFactory, "Collision").ToTuple(); Shaders = new Shader[] { res.Item1, res.Item2 }; ResourceLayout projViewLayout = StaticResourceCache.GetResourceLayout( gd.ResourceFactory, StaticResourceCache.SceneParamLayoutDescription); ResourceLayout mainPerObjectLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription( new ResourceLayoutElementDescription("WorldBuffer", ResourceKind.StructuredBufferReadWrite, ShaderStages.Vertex | ShaderStages.Fragment, ResourceLayoutElementOptions.None))); PerObjRS = StaticResourceCache.GetResourceSet(factory, new ResourceSetDescription(mainPerObjectLayout, Renderer.UniformBufferAllocator._backingBuffer)); bool isTriStrip = false; var fres = ColResource.Get(); if (fres != null) { var mesh = fres.GPUMeshes[ColMeshIndex]; } GraphicsPipelineDescription pipelineDescription = new GraphicsPipelineDescription(); pipelineDescription.BlendState = BlendStateDescription.SingleOverrideBlend; pipelineDescription.DepthStencilState = DepthStencilStateDescription.DepthOnlyGreaterEqual; pipelineDescription.RasterizerState = new RasterizerStateDescription( cullMode: FaceCullMode.Back, fillMode: PolygonFillMode.Solid, frontFace: WindClockwise ? FrontFace.Clockwise : FrontFace.CounterClockwise, depthClipEnabled: true, scissorTestEnabled: false); pipelineDescription.PrimitiveTopology = isTriStrip ? PrimitiveTopology.TriangleStrip : PrimitiveTopology.TriangleList; pipelineDescription.ShaderSet = new ShaderSetDescription( vertexLayouts: mainVertexLayouts, shaders: Shaders); pipelineDescription.ResourceLayouts = new ResourceLayout[] { projViewLayout, mainPerObjectLayout, Renderer.GlobalTexturePool.GetLayout(), Renderer.GlobalCubeTexturePool.GetLayout(), Renderer.MaterialBufferAllocator.GetLayout(), SamplerSet.SamplersLayout }; pipelineDescription.Outputs = gd.SwapchainFramebuffer.OutputDescription; RenderPipeline = StaticResourceCache.GetPipeline(factory, ref pipelineDescription); }
/// <summary> /// Submit the encoded batches as indirect draw calls /// </summary> /// <param name="cl"></param> public unsafe void SubmitBatches(CommandList cl, SceneRenderPipeline pipeline) { // If renderset is -1, no work has actually been uploaded to the gpu yet if (_renderSet == -1) { return; } // Dispatch indirect calls for each batch uint c = _batchCount[_renderSet] > 0 ? _batchCount[_renderSet] - 1 : 0; for (int i = 0; i < _batchCount[_renderSet]; i++) { cl.SetPipeline(_batches[MAX_BATCH * _renderSet + i]._pipeline); pipeline.BindResources(cl); cl.SetGraphicsResourceSet(1, _batches[MAX_BATCH * _renderSet + i]._objectRS); GlobalTexturePool.BindTexturePool(cl, 2); GlobalCubeTexturePool.BindTexturePool(cl, 3); MaterialBufferAllocator.BindAsResourceSet(cl, 4); cl.SetGraphicsResourceSet(5, SamplerSet.SamplersSet); if (!GeometryBufferAllocator.BindAsVertexBuffer(cl, _batches[MAX_BATCH * _renderSet + i]._bufferIndex)) { continue; } if (!GeometryBufferAllocator.BindAsIndexBuffer(cl, _batches[MAX_BATCH * _renderSet + i]._bufferIndex, _batches[MAX_BATCH * _renderSet + i]._indexFormat)) { continue; } uint count = _indirectDrawCount[_renderSet] - _batches[MAX_BATCH * _renderSet + i]._batchStart; if (i < _batchCount[_renderSet] - 1) { count = _batches[MAX_BATCH * _renderSet + i + 1]._batchStart - _batches[MAX_BATCH * _renderSet + i]._batchStart; } if (UseDirect) { uint start = _batches[MAX_BATCH * _renderSet + i]._batchStart; for (uint d = start; d < start + count; d++) { cl.DrawIndexed(_directBuffer[d].IndexCount, _directBuffer[d].InstanceCount, _directBuffer[d].FirstIndex, _directBuffer[d].VertexOffset, _directBuffer[d].FirstInstance); } } else { cl.DrawIndexedIndirect(_indirectBuffer, _batches[MAX_BATCH * _renderSet + i]._batchStart * 20, count, 20); } } }
public abstract void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneRenderPipeline sp);
//public abstract void Render(GraphicsDevice gd, CommandList cl, SceneRenderPipeline sp); public abstract void Render(Renderer.IndirectDrawEncoder encoder, SceneRenderPipeline sp);
public abstract void UpdatePerFrameResources(GraphicsDevice gd, CommandList cl, SceneRenderPipeline sp);
public override void UpdatePerFrameResources(GraphicsDevice gd, CommandList cl, SceneRenderPipeline sp) { if (WorldDirty) { WorldBuffer.FillBuffer(cl, ref _World); WorldDirty = false; } }
public void Render(Renderer.RenderQueue queue, Renderer.RenderQueue overlayQueue, BoundingFrustum frustum, SceneRenderPipeline pipeline) { /*CulledObjects.Clear(); * lock (SceneUpdateLock) * { * var watch = Stopwatch.StartNew(); * Octree.ApplyPendingMoves(); * Octree.GetContainedObjects(frustum, CulledObjects); * watch.Stop(); * OctreeCullTime = (float)(((double)watch.ElapsedTicks / (double)Stopwatch.Frequency) * 1000.0); * } * RenderObjectCount = CulledObjects.Count(); * var watch2 = Stopwatch.StartNew(); * foreach (var obj in CulledObjects) * { * if (((obj.DrawFilter & DrawFilter) > 0 && obj.DrawGroups.IsInDisplayGroup(DisplayGroup) && obj.IsVisible) || obj.Highlighted) || { || obj.SubmitRenderObjects(queue); || } ||} ||watch2.Stop(); ||CPUDrawTime = (float)(((double)watch2.ElapsedTicks / (double)Stopwatch.Frequency) * 1000.0);*/ var watch = Stopwatch.StartNew(); OpaqueRenderables.CullRenderables(frustum); OpaqueRenderables.ProcessSceneVisibility(DrawFilter, DisplayGroup); watch.Stop(); OctreeCullTime = (float)(((double)watch.ElapsedTicks / (double)Stopwatch.Frequency) * 1000.0); var watch2 = Stopwatch.StartNew(); OpaqueRenderables.SubmitRenderables(queue); watch2.Stop(); CPUDrawTime = (float)(((double)watch2.ElapsedTicks / (double)Stopwatch.Frequency) * 1000.0); queue.SetDrawParameters(OpaqueRenderables.cDrawParameters, _pickingEnabled ? OpaqueRenderables.cSelectionPipelines : OpaqueRenderables.cPipelines); OverlayRenderables.CullRenderables(frustum); OverlayRenderables.ProcessSceneVisibility(DrawFilter, DisplayGroup); OverlayRenderables.SubmitRenderables(overlayQueue); overlayQueue.SetDrawParameters(OverlayRenderables.cDrawParameters, _pickingEnabled ? OverlayRenderables.cSelectionPipelines : OverlayRenderables.cPipelines); _pickingEnabled = false; }
public abstract void UpdateRenderables(GraphicsDevice gd, CommandList cl, SceneRenderPipeline sp);