/// <summary> /// Function to set up multiple rendertargets for MRT output from a shader. /// </summary> /// <param name="targets">An array of render targets to assign.</param> /// <param name="depthStencil">[Optional] A depth/stencil buffer to assign with the targets.</param> /// <remarks> /// Use this method to set up MRT (Multiple Render Targets) rendering for a shader. This allows for efficient multiple pass rendering from the shader /// by allowing the shader to output to each render target simultaneously instead of having to set up a new pass for each target output. /// <para> /// Ensure that all the render targets in the array are the same width/height, and format. The array count and mip count must also match. If they do /// not, an exception will be thrown. The width, height, array count, and mip count for the depth/stencil buffer must match the render targets being set. /// </para> /// <para> /// Setting only a single target in the <paramref name="targets"/> parameter is equivalent to setting the <see cref="Target"/> property. Also, note that /// setting the target property will unbind the rest of the targets if multiple render targets have been previously bound. /// </para> /// <para> /// The maximum number of render targets that can be bound simultaneously is defined by the <see cref="P:GorgonOutputMerger.MaxRenderTargetViewSlots"/> /// property. If the number of <paramref name="targets"/> passed to this method exceeds this value, then an exception will be thrown. /// </para> /// </remarks> /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="targets"/> parameter is set to NULL (Nothing in VB.Net).</exception> /// <exception cref="System.ArgumentException">Thrown when the <paramref name="targets"/> parameter is empty.</exception> public void SetMultipleRenderTargets(GorgonRenderTargetView[] targets, GorgonDepthStencilView depthStencil = null) { #if DEBUG if (targets == null) { throw new ArgumentNullException("targets"); } if (targets.Length == 0) { throw new ArgumentException(Resources.GOR2D_PARAMETER_MUST_NOT_BE_EMPTY, "targets"); } #endif // Bind the first target as our primary target so that clipping states and other // settings are updated. Target = targets[0]; if (targets.Length == 1) { return; } // Bind the rest of the targets. Graphics.Output.SetRenderTargets(targets, depthStencil); }
/// <summary> /// Function to handle a resize of the current render target. /// </summary> /// <param name="sender">Object that sent the event.</param> /// <param name="e">Event parameters.</param> private void target_Resized(object sender, GorgonAfterSwapChainResizedEventArgs e) { GorgonDepthStencilView depthStencil = _currentTarget.SwapChain.DepthStencilBuffer; if (DepthStencil != null) { depthStencil = DepthStencil; } var target = new Gorgon2DTarget(_currentTarget.SwapChain, depthStencil); UpdateTarget(ref target); }
/// <summary> /// Initializes a new instance of the <see cref="Gorgon2DTarget"/> struct. /// </summary> /// <param name="target">The target.</param> /// <param name="depthStencil">The depth/stencil view.</param> public Gorgon2DTarget(GorgonRenderTargetView target, GorgonDepthStencilView depthStencil) { Target = target; DepthStencil = null; SwapChain = null; Height = 1; switch (target.Resource.ResourceType) { case ResourceType.Buffer: var buffer = (GorgonBuffer)target.Resource; var info = GorgonBufferFormatInfo.GetInfo(buffer.Settings.DefaultShaderViewFormat); Width = buffer.SizeInBytes / info.SizeInBytes; Viewport = new GorgonViewport(0, 0, Width, Height, 0, 1.0f); break; case ResourceType.Texture1D: var target1D = (GorgonRenderTarget1D)target.Resource; Width = target1D.Settings.Width; Viewport = target1D.Viewport; DepthStencil = depthStencil ?? target1D.DepthStencilBuffer; break; case ResourceType.Texture2D: var target2D = (GorgonRenderTarget2D)target.Resource; Width = target2D.Settings.Width; Height = target2D.Settings.Height; Viewport = target2D.Viewport; if (target2D.IsSwapChain) { SwapChain = (GorgonSwapChain)target2D; } DepthStencil = depthStencil ?? target2D.DepthStencilBuffer; break; case ResourceType.Texture3D: var target3D = (GorgonRenderTarget3D)target.Resource; Width = target3D.Settings.Width; Height = target3D.Settings.Height; Viewport = target3D.Viewport; break; default: throw new GorgonException(GorgonResult.CannotBind, "Could not bind a render target. Resource type is unknown. Should not see this error."); } }
/// <summary> /// Function to save the state information to this object. /// </summary> private void Save() { _targets = _graphics.Output.GetRenderTargets(); _uavs = _graphics.Output.GetUnorderedAccessViews(); _indexBuffer = _graphics.Input.IndexBuffer; _vertexBuffer = _graphics.Input.VertexBuffers[0]; _inputLayout = _graphics.Input.Layout; _primitiveType = _graphics.Input.PrimitiveType; _pixelShader = _graphics.Shaders.PixelShader.Current; _vertexShader = _graphics.Shaders.VertexShader.Current; _blendStates = _graphics.Output.BlendingState.States; _blendFactor = _graphics.Output.BlendingState.BlendFactor; _blendSampleMask = _graphics.Output.BlendingState.BlendSampleMask; _rasterStates = _graphics.Rasterizer.States; _samplerState = _graphics.Shaders.PixelShader.TextureSamplers[0]; _resource = _graphics.Shaders.PixelShader.Resources[0]; _depthStencilState = _graphics.Output.DepthStencilState.States; _depthStencilReference = _graphics.Output.DepthStencilState.StencilReference; _rasterStates.IsScissorTestingEnabled = false; _depthStencil = _graphics.Output.DepthStencilView; _viewports = _graphics.Rasterizer.GetViewports(); _scissorTests = _graphics.Rasterizer.GetScissorRectangles(); _alphaTest = new Gorgon2DAlphaTest(Gorgon2D.IsAlphaTestEnabled, GorgonRangeF.Empty); _vsConstantBuffers = new Dictionary <int, GorgonConstantBuffer>(); _psConstantBuffers = new Dictionary <int, GorgonConstantBuffer>(); // Only store the constant buffers that we were using. // We need to store all the constant buffers because the effects // make use of multiple constant slots. Unlike the resource views, // where we know that we're only using the first item (all bets are // off if a user decides to use another resource view slot), there's no // guarantee that we'll be only using 1 or 2 constant buffer slots. for (int i = 0; i < _graphics.Shaders.VertexShader.ConstantBuffers.Count; i++) { if (_graphics.Shaders.VertexShader.ConstantBuffers[i] != null) { _vsConstantBuffers[i] = _graphics.Shaders.VertexShader.ConstantBuffers[i]; } } for (int i = 0; i < _graphics.Shaders.PixelShader.ConstantBuffers.Count; i++) { if (_graphics.Shaders.PixelShader.ConstantBuffers[i] != null) { _psConstantBuffers[i] = _graphics.Shaders.PixelShader.ConstantBuffers[i]; } } }