unsafe void Flush(bool rebatch) { if (batch.VertexCount == 0) { if (!rebatch) { batch.EndBatch(); } return; } // We flush the buffer, first end batch. batch.EndBatch(); // We update vertex constants. vertexConstants.Map(MapOptions.Write); try { DataTransform vtransform = positionTransforms.Peek(); if (!vtransform.ProcessCPU) { vertexConstants.SetConstant("PositionTransform", Matrix4x4f.CreateTranslate(new Vector3f(-unitSize.X, -unitSize.Y, 0)) * Matrix4x4f.CreateScale(new Vector3f(2.0f, 2.0f, 2.0f)) * vtransform.Transform.RuntimeForm); } else { vertexConstants.SetConstant("PositionTransform", Matrix4x4f.Identity); } DataTransform ttransform = textureTransforms.Peek(); if (!ttransform.ProcessCPU) { vertexConstants.SetConstant("TextureTransform", ttransform.Transform.RuntimeForm); } else { vertexConstants.SetConstant("TextureTransform", Matrix4x4f.Identity); } } finally { vertexConstants.UnMap(); } // Vertex Shader: FixedShaderParameters vparams = vertexShaderCode.FixedParameters; vparams.AddLayout(0, vertexConstants.Layout); VShader vshader = vertexShaderCode.Compile(device, vparams) as VShader; // Pixel Shaders: FixedShaderParameters pparams = pixelShaderCode.FixedParameters; // We set interfaces. pparams.SetInterfaceArray("Fills", fills); // We now set per parameter data. ConstantBufferLayoutBuilder builder = new ConstantBufferLayoutBuilder(); List <TextureView> textures = new List <TextureView>(); List <SamplerState> samplers = new List <SamplerState>(); // We add per-fill data. for (int i = 0; i < fills.Count; i++) { IFill fill = fills[i]; string prefix = string.Format("Fills[{0}]", i); InterfaceHelper.ApplyInterfaceConstants(prefix, fill, builder, pparams, textures, samplers, fill.ParameterValues); } // We create view and fill data. ConstantBufferLayout layout = builder.CreateLayout(); ConstantBufferView pixelConstantsView = pixelConstants.CreateConstantBuffer(layout); pparams.AddLayout(0, layout); // TODO: this may not be needed for optimized setting. pixelConstantsView.Map(MapOptions.Write); try { for (int i = 0; i < fills.Count; i++) { IFill fill = fills[i]; string prefix = string.Format("Fills[{0}]", i); InterfaceHelper.FillInterfaceConstants(prefix, fill, pixelConstantsView, fill.ParameterValues); } } finally { pixelConstantsView.UnMap(); } // Finally compile. PShader pshader = pixelShaderCode.Compile(device, pparams) as PShader; using (DeviceLock devLock = device.Lock()) { // We now draw using data, set all states. device.SetBlendState(blendState, Colour.Black, 0xFFFFFFFF); device.SetDepthStencilState(depthStencilState, 0); device.SetRasterizationState(rasterizationState); if (viewport.Width == viewport.Height && viewport.Height == 0) { device.Viewport = new Region2i(new Vector2i(0, 0), new Vector2i((int)renderTarget.Width, (int)renderTarget.Height)); } else { device.Viewport = viewport; } // We bind stages. device.SetVertexShader(vshader, batch, null, null, new ConstantBufferView[] { vertexConstants }); device.SetPixelShader(pshader, samplers.ToArray(), textures.ToArray(), new ConstantBufferView[] { pixelConstantsView }, new RenderTargetView[] { renderTarget }, null); device.SetGeometryShader(null, null, null, null, null); // We now draw. device.DrawIndexed(0, batch.IndexCount, 0); // We clear state. device.SetVertexShader(null, null, null, null, null); device.SetPixelShader(null, null, null, null, null, null); } pixelConstantsView.Dispose(); // Fills and data is irrelavant. fills.Clear(); // We rebatch if not completelly ended. if (rebatch) { batch.BeginBatch(); } }
/// <summary> /// Composites to source. /// </summary> /// <param name="compositeOperation"></param> public void CompositeToSource(ICompositingOperation compositeOperation, BlendState blendOverwrite, Colour blendColour, Region2i viewport, RenderTargetView target) { // 1) We first prepare the providers. List <ICompositingOperation> relavantOperations = new List <ICompositingOperation>(); ListOperations(compositeOperation, relavantOperations); // 2) We extract processors. List <ICompositeInterface> processors = new List <ICompositeInterface>(relavantOperations.Count); for (int i = 0; i < relavantOperations.Count; i++) { processors.Add(relavantOperations[i].Interface); } // 3) We prepare the shader. ShaderCode pshader = PixelShader; ShaderCode vshader = VertexShader; States.BlendState bstate = blendOverwrite != null ? blendOverwrite : DefaultBlendState; States.DepthStencilState dstate = DefaultDepthStencilState; States.RasterizationState rstate = DefaultRasterizationState; FixedShaderParameters pparams = pshader.FixedParameters; FixedShaderParameters vparams = vshader.FixedParameters; ConstantBufferLayoutBuilder builder = new ConstantBufferLayoutBuilder(); List <TextureView> textures = new List <TextureView>(); List <States.SamplerState> samplers = new List <States.SamplerState>(); // We set interface array. pparams.SetInterfaceArray("Composite", processors); builder.AppendElement("Offset", PinFormat.Floatx2); // 4) We fill parameters and builder. for (int i = 0; i < processors.Count; i++) { string name = string.Format("Composite[{0}]", i); InterfaceHelper.ApplyInterfaceConstants(name, processors[i], builder, pparams, textures, samplers, processors[i].ParameterValues); } // 5) We obtain layout big enough. ConstantBufferLayout layout = builder.CreateLayout(); pparams.AddLayout(0, layout); ConstantBufferView constantBuffer = pixelTypelessConstantBuffer.CreateConstantBuffer(layout); // 6) We fill buffer. constantBuffer.Map(MapOptions.Write); try { constantBuffer.SetConstant("Offset", new Vector2f((float)viewport.X, (float)viewport.Y)); for (int i = 0; i < processors.Count; i++) { InterfaceHelper.FillInterfaceConstants(string.Format("Composite[{0}]", i), processors[i], constantBuffer, processors[i].ParameterValues); } } finally { constantBuffer.UnMap(); } // 7) We prepare geometry. // We get quad geometry Geometry geometry = alignedQuad; // ) We render the composition. GraphicsDevice device = Device; using (DeviceLock l = device.Lock()) { // We set our state objects. device.SetBlendState(bstate, blendColour, 0xFFFFFFFF); device.SetDepthStencilState(dstate, 0); device.SetRasterizationState(rstate); device.Viewport = viewport; // We prepare to render. device.SetVertexShader(vshader.Compile(device, vparams) as VShader, geometry, null, null, null); device.SetGeometryShader(null, null, null, null, null); device.SetPixelShader(pshader.Compile(device, pparams) as PShader, samplers.ToArray(), textures.ToArray(), new ConstantBufferView[] { constantBuffer }, new RenderTargetView[] { target }, null); // We render it. if (geometry.IndexBuffer != null) { device.DrawIndexed(0, 6, 0); } else { device.Draw(0, 6); } device.SetPixelShader(null, null, null, null, null, null); } // We do not use constant buffer anymore. constantBuffer.Dispose(); }