/// <summary> /// Sets targets. /// </summary> /// <param name="renderTargets"></param> public void SetTargets(DepthStencilSurface depthStencil, params RenderTargetSurface[] renderTargets) { int w = -1; int h = -1; if (renderTargets.Length > 8) { throw new ArgumentException("Could not bind more than 8 render targets"); } lock (deviceContext) { this.depthStencilSurface = depthStencil; renderTargets.CopyTo(renderTargetSurfaces, 0); if (depthStencil != null) { w = depthStencil.Width; h = depthStencil.Height; } if (renderTargets.Any()) { if (w == -1 || h == -1) { w = renderTargets.First().Width; h = renderTargets.First().Height; } if (!renderTargets.All(surf => surf.Width == w && surf.Height == h)) { throw new ArgumentException("All surfaces must be the same size", "renderTargets"); } } DepthStencilView dsv = depthStencil == null ? null : depthStencil.DSV; RenderTargetView[] rtvs = renderTargets.Select(rt => rt.RTV).ToArray(); if (!rtvs.Any()) { deviceContext.OutputMerger.SetTargets(dsv, (RenderTargetView)null); } else { deviceContext.OutputMerger.SetTargets(dsv, rtvs); } if (w > 0 && h > 0) { SetViewport(0, 0, w, h); } } }
/// <summary> /// Creates render target /// </summary> /// <param name="rs"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="format"></param> public DepthStencilCube(GraphicsDevice device, DepthFormat format, int size, int samples, string debugName = "") : base(device) { bool msaa = samples > 1; CheckSamplesCount(samples); SampleCount = samples; Format = format; SampleCount = samples; Width = size; Height = size; Depth = 1; var texDesc = new Texture2DDescription(); texDesc.Width = Width; texDesc.Height = Height; texDesc.ArraySize = 6; texDesc.BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.ConvertToTex(format); texDesc.MipLevels = 1; texDesc.OptionFlags = ResourceOptionFlags.TextureCube; texDesc.SampleDescription = new DXGI.SampleDescription(samples, 0); texDesc.Usage = ResourceUsage.Default; texCube = new D3D.Texture2D(device.Device, texDesc); var srvDesc = new ShaderResourceViewDescription(); srvDesc.Dimension = samples > 1 ? ShaderResourceViewDimension.Texture2DMultisampled : ShaderResourceViewDimension.Texture2D; srvDesc.Format = Converter.ConvertToSRV(format); srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; SRV = new ShaderResourceView(device.Device, texCube); // // Create surfaces : // surfaces = new DepthStencilSurface[6]; for (int face = 0; face < 6; face++) { var rtvDesc = new DepthStencilViewDescription(); rtvDesc.Texture2DArray.MipSlice = 0; rtvDesc.Texture2DArray.FirstArraySlice = face; rtvDesc.Texture2DArray.ArraySize = 1; rtvDesc.Dimension = msaa ? DepthStencilViewDimension.Texture2DMultisampledArray : DepthStencilViewDimension.Texture2DArray; rtvDesc.Format = Converter.ConvertToDSV(format); var dsv = new DepthStencilView(device.Device, texCube, rtvDesc); int subResId = Resource.CalculateSubResourceIndex(0, face, 1); surfaces[face] = new DepthStencilSurface(dsv, format, Width, Height, SampleCount); } }
/// <summary> /// Clear depth stencil surface /// </summary> /// <param name="surface"></param> /// <param name="depth"></param> /// <param name="stencil"></param> public void Clear(DepthStencilSurface surface, float depth = 1, byte stencil = 0) { lock (deviceContext) { deviceContext.ClearDepthStencilView(surface.DSV, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, depth, stencil); } }
/// <summary> /// /// </summary> /// <param name="depthStencil"></param> /// <param name="renderTargets"></param> public void GetTargets(out DepthStencilSurface depthStencil, out RenderTargetSurface[] renderTargets) { depthStencil = depthStencilSurface; renderTargets = renderTargetSurfaces.ToArray(); }
/// <summary> /// Creates depth stencil texture, view and shader resource with format D24S8 /// </summary> /// <param name="rs"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="format"></param> public DepthStencil2D( GraphicsDevice device, DepthFormat format, int width, int height, int samples = 1 ) : base(device) { CheckSamplesCount( samples ); Width = width; Height = height; Depth = 1; Format = format; SampleCount = samples; var bindFlags = BindFlags.DepthStencil; if (device.GraphicsProfile==GraphicsProfile.HiDef) { bindFlags |= BindFlags.ShaderResource; } else if (device.GraphicsProfile==GraphicsProfile.Reach) { if (samples==1) { bindFlags |= BindFlags.ShaderResource; } } var texDesc = new Texture2DDescription(); texDesc.Width = width; texDesc.Height = height; texDesc.ArraySize = 1; texDesc.BindFlags = bindFlags; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.ConvertToTex( format ); texDesc.MipLevels = 1; texDesc.OptionFlags = ResourceOptionFlags.None; texDesc.SampleDescription = new DXGI.SampleDescription(samples, 0); texDesc.Usage = ResourceUsage.Default; var dsvDesc = new DepthStencilViewDescription(); dsvDesc.Dimension = samples > 1 ? DepthStencilViewDimension.Texture2DMultisampled : DepthStencilViewDimension.Texture2D; dsvDesc.Format = Converter.ConvertToDSV( format ); dsvDesc.Flags = DepthStencilViewFlags.None; var srvDesc = new ShaderResourceViewDescription(); srvDesc.Dimension = samples > 1 ? ShaderResourceViewDimension.Texture2DMultisampled : ShaderResourceViewDimension.Texture2D; srvDesc.Format = Converter.ConvertToSRV( format ); srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; tex2D = new D3D.Texture2D ( device.Device, texDesc ); var dsv = new DepthStencilView ( device.Device, tex2D, dsvDesc ); if (bindFlags.HasFlag( BindFlags.ShaderResource)) { SRV = new ShaderResourceView ( device.Device, tex2D, srvDesc ); } surface = new DepthStencilSurface ( dsv, format, width, height, samples ); }
/// <summary> /// /// </summary> /// <param name="depthStencil"></param> /// <param name="renderTargets"></param> public void GetTargets( out DepthStencilSurface depthStencil, out RenderTargetSurface[] renderTargets ) { depthStencil = depthStencilSurface; renderTargets = renderTargetSurfaces.ToArray(); }
/// <summary> /// Sets targets. /// </summary> /// <param name="renderTargets"></param> public void SetTargets( DepthStencilSurface depthStencil, params RenderTargetSurface[] renderTargets ) { int w = -1; int h = -1; if (renderTargets.Length>8) { throw new ArgumentException("Could not bind more than 8 render targets"); } lock (deviceContext) { this.depthStencilSurface = depthStencil; renderTargets.CopyTo( renderTargetSurfaces, 0 ); if (depthStencil!=null) { w = depthStencil.Width; h = depthStencil.Height; } if (renderTargets.Any()) { if (w==-1 || h==-1) { w = renderTargets.First().Width; h = renderTargets.First().Height; } if ( !renderTargets.All( surf => surf.Width == w && surf.Height == h ) ) { throw new ArgumentException("All surfaces must be the same size", "renderTargets"); } } DepthStencilView dsv = depthStencil == null ? null : depthStencil.DSV; RenderTargetView[] rtvs = renderTargets.Select( rt => rt.RTV ).ToArray(); if (!rtvs.Any()) { deviceContext.OutputMerger.SetTargets( dsv, (RenderTargetView)null ); } else { deviceContext.OutputMerger.SetTargets( dsv, rtvs ); } if (w>0 && h>0) { SetViewport( 0, 0, w, h ); } } }
/// <summary> /// Clear depth stencil surface /// </summary> /// <param name="surface"></param> /// <param name="depth"></param> /// <param name="stencil"></param> public void Clear( DepthStencilSurface surface, float depth = 1, byte stencil = 0 ) { lock (deviceContext) { deviceContext.ClearDepthStencilView( surface.DSV, DepthStencilClearFlags.Depth|DepthStencilClearFlags.Stencil, depth, stencil ); } }
/// <summary> /// Renders sky with specified technique /// </summary> /// <param name="rendCtxt"></param> /// <param name="techName"></param> public void Render( GameTime gameTime, DepthStencilSurface depthBuffer, RenderTargetSurface hdrTarget, Matrix view, Matrix projection ) { var camera = Game.GetService<Camera>(); var scale = Matrix.Scaling( Params.SkySphereSize ); var rotation = Matrix.Identity; var sunPos = GetSunDirection(); var sunColor = GetSunGlowColor(); rs.ResetStates(); //rs.DepthStencilState = depthBuffer==null? DepthStencilState.None : DepthStencilState.Default ; rs.SetViewport( 0, 0, hdrTarget.Width, hdrTarget.Height ); rs.SetTargets( depthBuffer, hdrTarget ); var viewMatrix = view; var projMatrix = projection; skyConstsData.MatrixWVP = scale * rotation * MathUtil.Transformation( viewMatrix.Right, viewMatrix.Up, viewMatrix.Backward ) * projMatrix; skyConstsData.SunPosition = sunPos; skyConstsData.SunColor = sunColor; skyConstsData.Turbidity = Params.SkyTurbidity; skyConstsData.Temperature = Temperature.Get( Params.SunTemperature ); skyConstsData.SkyIntensity = Params.SkyIntensity; skyConstsCB.SetData( skyConstsData ); rs.VertexShaderConstants[0] = skyConstsCB; rs.PixelShaderConstants[0] = skyConstsCB; // // Sky : // SkyFlags flags = SkyFlags.PROCEDURAL_SKY; ApplyColorSpace( ref flags ); rs.PipelineState = factory[(int)flags]; for ( int j=0; j<skySphere.Meshes.Count; j++) { var mesh = skySphere.Meshes[j]; rs.SetupVertexInput( vertexBuffers[j], indexBuffers[j] ); rs.DrawIndexed( mesh.IndexCount, 0, 0 ); } // // Clouds : // scale = Matrix.Scaling( Params.SkySphereSize, Params.SkySphereSize, Params.SkySphereSize ); //scale = Matrix.Scaling( Params.SkySphereSize, Params.SkySphereSize * 0.1f, Params.SkySphereSize ); skyConstsData.MatrixWVP = scale * rotation * MathUtil.Transformation( viewMatrix.Right, viewMatrix.Up, viewMatrix.Backward ) * projMatrix; skyConstsData.SunPosition = sunPos; skyConstsData.SunColor = GetSunLightColor(); skyConstsData.Turbidity = Params.SkyTurbidity; skyConstsData.Temperature = Temperature.Get( Params.SunTemperature ); skyConstsData.SkyIntensity = Params.SkyIntensity; skyConstsData.Ambient = GetAmbientLevel().ToVector3(); skyConstsData.Time = (float)gameTime.Total.TotalSeconds; skyConstsCB.SetData( skyConstsData ); flags = SkyFlags.CLOUDS; for (int i=0; i<3; i++) { if (i==0) flags = SkyFlags.CLOUDS| SkyFlags.A; if (i==1) flags = SkyFlags.CLOUDS| SkyFlags.B; if (i==2) flags = SkyFlags.CLOUDS| SkyFlags.C; ApplyColorSpace( ref flags ); rs.PipelineState = factory[(int)flags]; rs.PixelShaderResources[0] = clouds; rs.PixelShaderResources[1] = cirrus; rs.PixelShaderResources[2] = noise; rs.PixelShaderResources[3] = arrows; rs.PixelShaderSamplers[0] = SamplerState.AnisotropicWrap; for ( int j=0; j<cloudSphere.Meshes.Count; j++) { var mesh = cloudSphere.Meshes[j]; rs.SetupVertexInput( cloudVertexBuffers[j], cloudIndexBuffers[j] ); rs.DrawIndexed( mesh.IndexCount, 0, 0 ); } } rs.ResetStates(); }
/// <summary> /// Creates render target /// </summary> /// <param name="rs"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="format"></param> public DepthStencilCube( GraphicsDevice device, DepthFormat format, int size, int samples, string debugName = "" ) : base(device) { bool msaa = samples > 1; CheckSamplesCount( samples ); SampleCount = samples; Format = format; SampleCount = samples; Width = size; Height = size; Depth = 1; var texDesc = new Texture2DDescription(); texDesc.Width = Width; texDesc.Height = Height; texDesc.ArraySize = 6; texDesc.BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.ConvertToTex( format ); texDesc.MipLevels = 1; texDesc.OptionFlags = ResourceOptionFlags.TextureCube; texDesc.SampleDescription = new DXGI.SampleDescription(samples, 0); texDesc.Usage = ResourceUsage.Default; texCube = new D3D.Texture2D( device.Device, texDesc ); var srvDesc = new ShaderResourceViewDescription(); srvDesc.Dimension = samples > 1 ? ShaderResourceViewDimension.Texture2DMultisampled : ShaderResourceViewDimension.Texture2D; srvDesc.Format = Converter.ConvertToSRV( format ); srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; SRV = new ShaderResourceView( device.Device, texCube ); // // Create surfaces : // surfaces = new DepthStencilSurface[ 6 ]; for ( int face=0; face<6; face++) { var rtvDesc = new DepthStencilViewDescription(); rtvDesc.Texture2DArray.MipSlice = 0; rtvDesc.Texture2DArray.FirstArraySlice = face; rtvDesc.Texture2DArray.ArraySize = 1; rtvDesc.Dimension = msaa ? DepthStencilViewDimension.Texture2DMultisampledArray : DepthStencilViewDimension.Texture2DArray; rtvDesc.Format = Converter.ConvertToDSV( format ); var dsv = new DepthStencilView( device.Device, texCube, rtvDesc ); int subResId = Resource.CalculateSubResourceIndex( 0, face, 1 ); surfaces[face] = new DepthStencilSurface( dsv, format, Width, Height, SampleCount ); } }
/// <summary> /// Creates depth stencil texture, view and shader resource with format D24S8 /// </summary> /// <param name="rs"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="format"></param> public DepthStencil2D(GraphicsDevice device, DepthFormat format, int width, int height, int samples = 1) : base(device) { CheckSamplesCount(samples); Width = width; Height = height; Depth = 1; Format = format; SampleCount = samples; var bindFlags = BindFlags.DepthStencil; if (device.GraphicsProfile == GraphicsProfile.HiDef) { bindFlags |= BindFlags.ShaderResource; } else if (device.GraphicsProfile == GraphicsProfile.Reach) { if (samples == 1) { bindFlags |= BindFlags.ShaderResource; } } var texDesc = new Texture2DDescription(); texDesc.Width = width; texDesc.Height = height; texDesc.ArraySize = 1; texDesc.BindFlags = bindFlags; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Format = Converter.ConvertToTex(format); texDesc.MipLevels = 1; texDesc.OptionFlags = ResourceOptionFlags.None; texDesc.SampleDescription = new DXGI.SampleDescription(samples, 0); texDesc.Usage = ResourceUsage.Default; var dsvDesc = new DepthStencilViewDescription(); dsvDesc.Dimension = samples > 1 ? DepthStencilViewDimension.Texture2DMultisampled : DepthStencilViewDimension.Texture2D; dsvDesc.Format = Converter.ConvertToDSV(format); dsvDesc.Flags = DepthStencilViewFlags.None; var srvDesc = new ShaderResourceViewDescription(); srvDesc.Dimension = samples > 1 ? ShaderResourceViewDimension.Texture2DMultisampled : ShaderResourceViewDimension.Texture2D; srvDesc.Format = Converter.ConvertToSRV(format); srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; tex2D = new D3D.Texture2D(device.Device, texDesc); var dsv = new DepthStencilView(device.Device, tex2D, dsvDesc); if (bindFlags.HasFlag(BindFlags.ShaderResource)) { SRV = new ShaderResourceView(device.Device, tex2D, srvDesc); } surface = new DepthStencilSurface(dsv, format, width, height, samples); }
/// <summary> /// Renders sky with specified technique /// </summary> /// <param name="rendCtxt"></param> /// <param name="techName"></param> public void Render( GameTime gameTime, DepthStencilSurface depthBuffer, RenderTargetSurface hdrTarget, Matrix view, Matrix projection, RenderTarget2D cloudTarget, RenderTarget2D smallerCloudTarget) { var camera = Game.GetService<Camera>(); var scale = Matrix.Scaling( Params.SkySphereSize ); var rotation = Matrix.Identity; var sunPos = GetSunDirection(); var sunColor = GetSunGlowColor(); rs.ResetStates(); //rs.DepthStencilState = depthBuffer==null? DepthStencilState.None : DepthStencilState.Default ; rs.SetViewport( 0, 0, hdrTarget.Width, hdrTarget.Height ); rs.SetTargets( depthBuffer, hdrTarget ); var viewMatrix = view; var projMatrix = projection; skyConstsData.MatrixWVP = scale * rotation * MathUtil.Transformation( viewMatrix.Right, viewMatrix.Up, viewMatrix.Backward ) * projMatrix; skyConstsData.SunPosition = sunPos; skyConstsData.SunColor = sunColor; skyConstsData.Turbidity = Params.SkyTurbidity; skyConstsData.Temperature = Temperature.Get( Params.SunTemperature ); skyConstsData.SkyIntensity = Params.SkyIntensity; skyConstsCB.SetData( skyConstsData ); rs.VertexShaderConstants[0] = skyConstsCB; rs.PixelShaderConstants[0] = skyConstsCB; // // Sky : // SkyFlags flags = SkyFlags.PROCEDURAL_SKY; ApplyColorSpace( ref flags ); rs.PipelineState = factory[(int)flags]; for ( int j=0; j<skySphere.Meshes.Count; j++) { var mesh = skySphere.Meshes[j]; rs.SetupVertexInput( vertexBuffers[j], indexBuffers[j] ); rs.DrawIndexed( mesh.IndexCount, 0, 0 ); } // // Clouds : // scale = Matrix.Scaling( Params.SkySphereSize, Params.SkySphereSize, Params.SkySphereSize ); //scale = Matrix.Scaling( Params.SkySphereSize, Params.SkySphereSize * 0.1f, Params.SkySphereSize ); skyConstsData.MatrixWVP = scale * rotation * MathUtil.Transformation( viewMatrix.Right, viewMatrix.Up, viewMatrix.Backward ) * projMatrix; skyConstsData.SunPosition = sunPos; skyConstsData.SunColor = GetSunLightColor(); skyConstsData.Turbidity = Params.SkyTurbidity; skyConstsData.Temperature = Temperature.Get( Params.SunTemperature ); skyConstsData.SkyIntensity = Params.SkyIntensity; skyConstsData.Ambient = GetAmbientLevel().ToVector3(); skyConstsData.Time = (float)gameTime.Total.TotalSeconds; skyConstsCB.SetData( skyConstsData ); rs.SetTargets( depthBuffer, hdrTarget); // rs.SetTargets( null, cloudTarget.Surface ); flags = SkyFlags.CLOUDS; //int i = 0; for (int i=0; i<3; i++) { if (i==0) flags = SkyFlags.CLOUDS| SkyFlags.A | SkyFlags.RED; if (i==1) flags = SkyFlags.CLOUDS| SkyFlags.B | SkyFlags.GREEN; if (i==2) flags = SkyFlags.CLOUDS| SkyFlags.C | SkyFlags.BLUE; ApplyColorSpace( ref flags ); rs.PipelineState = factory[(int)flags]; rs.PixelShaderResources[0] = clouds; rs.PixelShaderResources[1] = cirrus; rs.PixelShaderResources[2] = noise; rs.PixelShaderResources[3] = arrows; rs.PixelShaderSamplers[0] = SamplerState.AnisotropicWrap; for ( int j=0; j<cloudSphere.Meshes.Count; j++) { var mesh = cloudSphere.Meshes[j]; rs.SetupVertexInput( cloudVertexBuffers[j], cloudIndexBuffers[j] ); rs.DrawIndexed( mesh.IndexCount, 0, 0 ); } } #if false //Blur var filter = Game.GetService<Filter>(); //filter.RadialBlur(smallerCloudTarget.Surface, cloudTarget, new Vector2(0.5f, 0.5f), 1.0f, -0.2f); //if(Game.InputDevice.IsKeyDown(Keys.LeftButton)) //{ Vector4 sunProj = Vector4.Transform(new Vector4(sunPos, 0), viewMatrix); sunProj = Vector4.Transform(sunProj, projMatrix); sunProj = new Vector4(sunProj.X / sunProj.W, sunProj.Y / sunProj.W, sunProj.Z / sunProj.W, 1); Vector2 relSunPosition = new Vector2(0.5f, 0.5f); //if ( Math.Abs(sunProj.X ) < 1 && Math.Abs (sunProj.Y) < 1){ relSunPosition = new Vector2( (sunProj.X + 1) / 2, - (sunProj.Y - 1) / 2); //} //Log.Message(relSunPosition + ""); filter.RadialBlur(smallerCloudTarget.Surface, cloudTarget, relSunPosition, 1.0f, -0.2f); //} flags = SkyFlags.BLUR_CLOUD; skyConstsData.MatrixWVP = Matrix.Identity; skyConstsCB.SetData( skyConstsData ); rs.SetTargets(null, hdrTarget); ApplyColorSpace( ref flags ); rs.VertexShaderConstants[0] = skyConstsCB; rs.PixelShaderConstants[0] = skyConstsCB; rs.PipelineState = factory[(int)flags]; rs.PixelShaderResources[4] = cloudTarget; rs.PixelShaderSamplers[1] = SamplerState.LinearWrap; var v0 = new VertexColorTextureTBN { Position = new Vector3( -1.0f, -1.0f, 0 ), TexCoord = new Vector2( 0, 1 ), }; var v1 = new VertexColorTextureTBN { Position = new Vector3( 1.0f, 1.0f, 0 ), TexCoord = new Vector2( 1, 0 ), }; var v2 = new VertexColorTextureTBN { Position = new Vector3( -1.0f, 1.0f, 0 ), TexCoord = new Vector2( 0, 0 ), }; var v3 = new VertexColorTextureTBN { Position = new Vector3( -1.0f, -1.0f, 0 ), TexCoord = new Vector2( 0, 1 ), }; var v4 = new VertexColorTextureTBN { Position = new Vector3( 1.0f, -1.0f, 0 ), TexCoord = new Vector2( 1, 1 ), }; var v5 = new VertexColorTextureTBN { Position = new Vector3( 1.0f, 1.0f, 0 ), TexCoord = new Vector2( 1, 0 ), };//*/ var data = new VertexColorTextureTBN[] { v0, v1, v2, v3, v4, v5 }; //Log.Message(""+v0.TexCoord); vertexBufferBlur.SetData( data, 0, 6 ); //for ( int j=0; j<cloudSphere.Meshes.Count; j++) { // var mesh = cloudSphere.Meshes[j]; // rs.SetupVertexInput( cloudVertexBuffers[j], cloudIndexBuffers[j] ); // rs.DrawIndexed( mesh.IndexCount, 0, 0 ); // } rs.SetupVertexInput( vertexBufferBlur, null ); rs.Draw( 6, 0 ); #endif rs.ResetStates(); }