/// <summary>
 /// Clears a render target.
 /// </summary>
 /// <param name="renderTarget">The render target.</param>
 /// <param name="color">Set this color value for the RenderTarget buffer.</param>
 public void Clear(RenderTarget renderTarget, Mathematics.Color color)
 {
     throw new NotImplementedException();
 }
Example #2
0
        public override void Load()
        {
            base.Load();

            if (OfflineCompilation)
                return;

            var renderTargets = new RenderTarget[2];
            DepthStencilBuffer depthStencilBuffer = null;
            Texture2D depthStencilTexture = null;

            Parameters.AddSources(MainPlugin.ViewParameters);

            Parameters.RegisterParameter(EffectPlugin.BlendStateKey);

            var filteredPasses = new FastList<RenderPass>();

            RenderPass.UpdatePasses += updatePassesAction = (RenderPass currentRenderPass, ref FastList<RenderPass> currentPasses) =>
                {
                    var originalPasses = currentPasses;
                    filteredPasses.Clear();
                    currentPasses = filteredPasses;

                    Parameters.Set(PickingFrameIndex, ++currentPickingFrameIndex);
                    Request[] requests;

                    lock (pendingRequests)
                    {
                        // No picking request or no mesh to pick?
                        if (pendingRequests.Count == 0)
                            return;

                        requests = pendingRequests.ToArray();
                        pendingRequests.Clear();
                    }

                    foreach (var request in requests)
                    {
                        requestResults.Add(request);
                    }

                    if (originalPasses == null)
                        return;

                    // Count mesh passes
                    int meshIndex = 0;
                    foreach (var pass in originalPasses)
                    {
                        meshIndex += pass.Passes.Count;
                    }

                    // No mesh to pick?
                    if (meshIndex == 0)
                        return;

                    // Copy mesh passes and assign indices
                    var meshPasses = new EffectMesh[meshIndex];
                    meshIndex = 0;
                    foreach (var pass in RenderPass.Passes)
                    {
                        throw new NotImplementedException();
                        //foreach (var effectMeshPass in pass.Meshes)
                        //{
                        //    meshPasses[meshIndex] = (EffectMesh)effectMeshPass;
                        //    // Prefix increment so that 0 means no rendering.
                        //    effectMeshPass.Parameters.Set(PickingMeshIndex, ++meshIndex);
                        //}
                    }

                    // For now, it generates one rendering per picking.
                    // It would be quite easy to optimize it by make Picking shader works on multiple picking points at a time.
                    foreach (var request in requests)
                    {
                        var pickingRenderPass = new RenderPass("Picking");

                        pickingRenderPass.StartPass.AddFirst = (threadContext) =>
                            {
                                threadContext.GraphicsDevice.Clear(renderTargets[0], Color.Black);
                                threadContext.GraphicsDevice.Clear(renderTargets[1], Color.Black);
                                threadContext.Parameters.Set(PickingScreenPosition, request.Location);
                                threadContext.GraphicsDevice.SetViewport(new Viewport(0, 0, renderTargets[0].Description.Width, renderTargets[0].Description.Height));

                                threadContext.GraphicsDevice.Clear(depthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
                                threadContext.GraphicsDevice.SetRenderTargets(depthStencilBuffer, renderTargets);
                            };
                        pickingRenderPass.EndPass.AddLast = (threadContext) =>
                            {
                                threadContext.Parameters.Reset(PickingScreenPosition);
                                threadContext.GraphicsDevice.Copy(renderTargets[0].Texture, request.ResultTextures[0]);
                                threadContext.GraphicsDevice.Copy(renderTargets[1].Texture, request.ResultTextures[1]);
                            };
                        //pickingRenderPass.PassesInternal = originalPasses;
                        throw new NotImplementedException();

                        request.MeshPasses = meshPasses;

                        currentPasses.Add(pickingRenderPass);

                        request.HasResults = true;

                        // Wait 2 frames before pulling the results.
                        request.FrameCounter = 2;
                    }
                };

            RenderSystem.GlobalPass.EndPass.AddLast = CheckPickingResults;

            var backBuffer = GraphicsDevice.BackBuffer; 

            int pickingArea = 1 + PickingDistance * 2;
            renderTargets[0] = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.R32_UInt, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget().KeepAliveBy(ActiveObjects);
            renderTargets[1] = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.R32G32B32A32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget().KeepAliveBy(ActiveObjects);

            depthStencilTexture = Texture.New2D(GraphicsDevice, pickingArea, pickingArea, PixelFormat.D32_Float, TextureFlags.ShaderResource | TextureFlags.DepthStencil).KeepAliveBy(ActiveObjects);
            depthStencilBuffer = depthStencilTexture.ToDepthStencilBuffer(false);

            Parameters.AddDynamic(PickingMatrix, ParameterDynamicValue.New(PickingScreenPosition, (ref Vector2 pickingPosition, ref Matrix picking) =>
                {
                    // Move center to picked position, and zoom (it is supposed to stay per-pixel according to render target size)
                    picking = Matrix.Translation(1.0f - (pickingPosition.X) / backBuffer.Width * 2.0f, -1.0f + (pickingPosition.Y) / backBuffer.Height * 2.0f, 0.0f)
                        * Matrix.Scaling((float)backBuffer.Width / (float)pickingArea, (float)backBuffer.Height / (float)pickingArea, 1.0f);
                }));
        }