Esempio n. 1
0
        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();
        }