/// <summary> /// Function to blit the texture to the specified render target. /// </summary> /// <param name="texture">The texture that will be blitted to the render target.</param> /// <param name="destRect">The layout area to blit the texture into.</param> /// <param name="sourceOffset">The offset within the source texture to start blitting from.</param> /// <param name="color">The color used to tint the diffuse value of the texture.</param> /// <param name="clip"><b>true</b> to clip the contents of the texture if the destination is larger/small than the size of the texture.</param> /// <param name="blendState">The blending state to apply.</param> /// <param name="samplerState">The sampler state to apply.</param> /// <param name="pixelShader">The pixel shader used to override the default pixel shader.</param> /// <param name="pixelShaderConstants">The pixel shader constant buffers to use.</param> public void Blit(GorgonTexture2DView texture, DX.Rectangle destRect, DX.Point sourceOffset, GorgonColor color, bool clip, GorgonBlendState blendState, GorgonSamplerState samplerState, GorgonPixelShader pixelShader, GorgonConstantBuffers pixelShaderConstants) { if ((_graphics.RenderTargets[0] == null) || (color.Alpha.EqualsEpsilon(0))) { return; } if (texture == null) { texture = _defaultTexture; } GorgonRenderTargetView currentView = _graphics.RenderTargets[0]; // We need to update the projection/view if the size of the target changes. if ((_targetBounds == null) || (currentView.Width != _targetBounds.Value.Width) || (currentView.Height != _targetBounds.Value.Height)) { _needsWvpUpdate = true; } UpdateProjection(); // Set to default states if not provided. if (blendState == null) { blendState = GorgonBlendState.NoBlending; } if (pixelShader == null) { pixelShader = _pixelShader; } if (samplerState == null) { samplerState = GorgonSamplerState.Default; } if (pixelShaderConstants == null) { pixelShaderConstants = _emptyPsConstants; } GetDrawCall(texture, blendState, samplerState, pixelShader, pixelShaderConstants); // Calculate position on the texture. DX.Vector2 topLeft = texture.Texture.ToTexel(sourceOffset); DX.Vector2 bottomRight = texture.Texture.ToTexel(clip ? new DX.Vector2(destRect.Width, destRect.Height) : new DX.Point(texture.Width, texture.Height)); if (clip) { DX.Vector2.Add(ref bottomRight, ref topLeft, out bottomRight); } // Update the vertices. _vertices[0] = new BltVertex { Position = new DX.Vector4(destRect.X, destRect.Y, 0, 1.0f), Uv = topLeft, Color = color }; _vertices[1] = new BltVertex { Position = new DX.Vector4(destRect.Right, destRect.Y, 0, 1.0f), Uv = new DX.Vector2(bottomRight.X, topLeft.Y), Color = color }; _vertices[2] = new BltVertex { Position = new DX.Vector4(destRect.X, destRect.Bottom, 0, 1.0f), Uv = new DX.Vector2(topLeft.X, bottomRight.Y), Color = color }; _vertices[3] = new BltVertex { Position = new DX.Vector4(destRect.Right, destRect.Bottom, 0, 1.0f), Uv = new DX.Vector2(bottomRight.X, bottomRight.Y), Color = color }; // Copy to the vertex buffer. _vertexBufferBindings[0].VertexBuffer.SetData(_vertices); _graphics.Submit(_drawCall); }
/// <summary> /// Function to return the appropriate draw call based on the states provided. /// </summary> /// <param name="texture">The texture to display.</param> /// <param name="blendState">The blending state for the texture.</param> /// <param name="samplerState">The sampler state for the texture.</param> /// <param name="shader">The pixel shader to use.</param> /// <param name="constantBuffers">Constant buffers for the pixel shader, if required.</param> private void GetDrawCall(GorgonTexture2DView texture, GorgonBlendState blendState, GorgonSamplerState samplerState, GorgonPixelShader shader, GorgonConstantBuffers constantBuffers) { if ((_drawCall != null) && (shader == _pixelShader) && (_drawCall.PixelShader.Samplers[0] == samplerState) && (_pipelineState.BlendStates[0] == blendState) && (_drawCall.PixelShader.ShaderResources[0] == texture) && (_drawCall.PixelShader.ConstantBuffers.DirtyEquals(constantBuffers))) { // This draw call hasn't changed, so return the previous one. return; } if (_pipelineState.BlendStates[0] != blendState) { _pipelineState = _pipeStateBuilder .BlendState(blendState) .Build(); _drawCallBuilder.PipelineState(_pipelineState); } _drawCall = _drawCallBuilder.ConstantBuffers(ShaderType.Pixel, constantBuffers) .SamplerState(ShaderType.Pixel, samplerState) .ShaderResource(ShaderType.Pixel, texture) .Build(_drawAllocator); }