예제 #1
0
        void ListOperations(ICompositingOperation op, List <ICompositingOperation> list)
        {
            if (op.Source1 != null)
            {
                ListOperations(op.Source1, list);
            }
            if (op.Source2 != null)
            {
                ListOperations(op.Source2, list);
            }

            list.Add(op);
        }
예제 #2
0
        /// <summary>
        /// Applies effect to topmost image and writes result to the top.
        /// </summary>
        /// <param name="effect"></param>
        public void Call(ICompositingOperation operation)
        {
            switch (operation.OperationType)
            {
            case OperationType.NoSource:
                break;

            case OperationType.OneSource:
                operation.Source1 = results.Pop();
                break;

            case OperationType.TwoSources:
                operation.Source1 = results.Pop();
                operation.Source2 = results.Pop();
                break;
            }

            results.Push(operation);
        }
예제 #3
0
        /// <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();
        }