public void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc, ResourceScope scope) { if ((scope & ResourceScope.Map) == 0) { return; } var disposeFactory = new DisposeCollectorResourceFactory(gd.ResourceFactory, _disposeCollector); _sharedLayout = disposeFactory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("Projection", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("View", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("WorldAndInverse", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("LightingInfo", ResourceKind.UniformBuffer, ShaderStages.Fragment), new ResourceLayoutElementDescription("LightStyles", ResourceKind.UniformBuffer, ShaderStages.Fragment), new ResourceLayoutElementDescription("RenderColor", ResourceKind.UniformBuffer, ShaderStages.Fragment))); TextureLayout = disposeFactory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("Texture", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("Sampler", ResourceKind.Sampler, ShaderStages.Fragment))); LightmapLayout = disposeFactory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("Lightmaps", ResourceKind.TextureReadOnly, ShaderStages.Fragment))); var vertexLayouts = new VertexLayoutDescription[] { new VertexLayoutDescription( new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("TextureCoords", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2), new VertexElementDescription("LightmapCoords", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2), //Used for multiple light styles; this is the offset to apply to lightmap X coordinates new VertexElementDescription("LightmapXOffset", VertexElementSemantic.Position, VertexElementFormat.Float1), new VertexElementDescription("StyleIndices", VertexElementSemantic.Position, VertexElementFormat.Int4)) }; (var vs, var fs) = sc.MapResourceCache.GetShaders(gd, gd.ResourceFactory, "LightMappedGeneric"); //Create render mode pipelines var rasterizerState = new RasterizerStateDescription(FaceCullMode.Back, PolygonFillMode.Solid, FrontFace.Clockwise, true, true); const PrimitiveTopology primitiveTopology = PrimitiveTopology.TriangleList; var shaderSets = new ShaderSetDescription(vertexLayouts, new[] { vs, fs }); var resourceLayouts = new ResourceLayout[] { _sharedLayout, TextureLayout, LightmapLayout }; var outputDescription = sc.MainSceneFramebuffer.OutputDescription; var pipelines = new Pipeline[(int)RenderMode.Last + 1]; var pd = new GraphicsPipelineDescription( BlendStateDescription.SingleDisabled, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqual : DepthStencilStateDescription.DepthOnlyLessEqual, rasterizerState, primitiveTopology, shaderSets, resourceLayouts, outputDescription); pipelines[(int)RenderMode.Normal] = disposeFactory.CreateGraphicsPipeline(ref pd); pipelines[(int)RenderMode.TransColor] = disposeFactory.CreateGraphicsPipeline(ref pd); pd = new GraphicsPipelineDescription( BlendStateDescription.SingleAlphaBlend, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqualRead : DepthStencilStateDescription.DepthOnlyLessEqualRead, rasterizerState, primitiveTopology, shaderSets, resourceLayouts, outputDescription); pipelines[(int)RenderMode.TransTexture] = disposeFactory.CreateGraphicsPipeline(ref pd); //Glow uses the same pipeline as texture pipelines[(int)RenderMode.Glow] = pipelines[(int)RenderMode.TransTexture]; pd = new GraphicsPipelineDescription( BlendStateDescription.SingleDisabled, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqual : DepthStencilStateDescription.DepthOnlyLessEqual, rasterizerState, primitiveTopology, shaderSets, resourceLayouts, outputDescription); pipelines[(int)RenderMode.TransAlpha] = disposeFactory.CreateGraphicsPipeline(ref pd); pd = new GraphicsPipelineDescription( BlendStates.SingleAdditiveOneOneBlend, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqualRead : DepthStencilStateDescription.DepthOnlyLessEqualRead, rasterizerState, primitiveTopology, shaderSets, resourceLayouts, outputDescription); pipelines[(int)RenderMode.TransAdd] = disposeFactory.CreateGraphicsPipeline(ref pd); Pipelines = new RenderModePipelines(pipelines); RenderArgumentsBuffer = disposeFactory.CreateBuffer(new BufferDescription((uint)Marshal.SizeOf <BSPRenderArguments>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _sharedResourceSet = disposeFactory.CreateResourceSet(new ResourceSetDescription( _sharedLayout, sc.ProjectionMatrixBuffer, sc.ViewMatrixBuffer, sc.WorldAndInverseBuffer, sc.LightingInfoBuffer, sc.LightStylesBuffer, RenderArgumentsBuffer)); }
public void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc, ResourceScope scope) { if ((scope & ResourceScope.Map) == 0) { return; } var disposeFactory = new DisposeCollectorResourceFactory(gd.ResourceFactory, _disposeCollector); //Create the layout and pipelines used by sprites var vertexLayouts = new VertexLayoutDescription[] { new VertexLayoutDescription( new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("TextureCoords", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2) ) }; (var vs, var fs) = sc.MapResourceCache.GetShaders(gd, gd.ResourceFactory, "SpriteGeneric"); Layout = disposeFactory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("Projection", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("View", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("WorldAndInverse", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("Texture", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("Sampler", ResourceKind.Sampler, ShaderStages.Fragment), new ResourceLayoutElementDescription("LightingInfo", ResourceKind.UniformBuffer, ShaderStages.Fragment), new ResourceLayoutElementDescription("RenderColor", ResourceKind.UniformBuffer, ShaderStages.Fragment) )); //Vanilla GoldSource has a cvar gl_spriteblend that disables blending and makes normal sprites render differently //This is purely a performance setting and lowers the quality of sprites //We won't do that here var pd = new GraphicsPipelineDescription( BlendStateDescription.SingleAlphaBlend, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqual : DepthStencilStateDescription.DepthOnlyLessEqual, new RasterizerStateDescription(FaceCullMode.Back, PolygonFillMode.Solid, FrontFace.Clockwise, true, true), PrimitiveTopology.TriangleList, new ShaderSetDescription(vertexLayouts, new[] { vs, fs }), new ResourceLayout[] { Layout }, sc.MainSceneFramebuffer.OutputDescription); var pipelines = new Pipeline[(int)RenderMode.Last + 1]; pipelines[(int)RenderMode.Normal] = disposeFactory.CreateGraphicsPipeline(ref pd); //Same pipeline as normal when sprite blending is enabled in vanilla pipelines[(int)RenderMode.TransTexture] = pipelines[(int)RenderMode.Normal]; //Identical to Texture, vanilla GoldSource uses an invalid texture env mode that happens to use GL_MODULATE so for consistency this is required pipelines[(int)RenderMode.TransColor] = pipelines[(int)RenderMode.TransTexture]; pd = new GraphicsPipelineDescription( BlendStates.SingleAdditiveOneOneBlend, DepthStencilStateDescription.Disabled, new RasterizerStateDescription(FaceCullMode.Back, PolygonFillMode.Solid, FrontFace.Clockwise, true, true), PrimitiveTopology.TriangleList, new ShaderSetDescription(vertexLayouts, new[] { vs, fs }), new ResourceLayout[] { Layout }, sc.MainSceneFramebuffer.OutputDescription); pipelines[(int)RenderMode.Glow] = disposeFactory.CreateGraphicsPipeline(ref pd); //Identical to Texture, but does not write to the depth buffer pd = new GraphicsPipelineDescription( BlendStateDescription.SingleAlphaBlend, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqualRead : DepthStencilStateDescription.DepthOnlyLessEqualRead, new RasterizerStateDescription(FaceCullMode.Back, PolygonFillMode.Solid, FrontFace.Clockwise, true, true), PrimitiveTopology.TriangleList, new ShaderSetDescription(vertexLayouts, new[] { vs, fs }), new ResourceLayout[] { Layout }, sc.MainSceneFramebuffer.OutputDescription); pipelines[(int)RenderMode.TransAlpha] = disposeFactory.CreateGraphicsPipeline(ref pd); //Identical to Glow, but still uses depth testing pd = new GraphicsPipelineDescription( BlendStates.SingleAdditiveOneOneBlend, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqualRead : DepthStencilStateDescription.DepthOnlyLessEqualRead, new RasterizerStateDescription(FaceCullMode.Back, PolygonFillMode.Solid, FrontFace.Clockwise, true, true), PrimitiveTopology.TriangleList, new ShaderSetDescription(vertexLayouts, new[] { vs, fs }), new ResourceLayout[] { Layout }, sc.MainSceneFramebuffer.OutputDescription); pipelines[(int)RenderMode.TransAdd] = disposeFactory.CreateGraphicsPipeline(ref pd); Pipelines = new RenderModePipelines(pipelines); }