Beispiel #1
0
        public static SceneGraph PickClosestObject(SceneGraph root, Camera Camera, Matrix ProjMatrix, Vector2 ClickPoint, Vector2 ScreenDims)
        {
            // Convert screen pixel to view space
            Vector2 viewSpacePixel = new Vector2((2.0f * ClickPoint.X / ScreenDims.X - 1.0f) / ProjMatrix.M11, (-2.0f * ClickPoint.Y / ScreenDims.Y + 1.0f) / ProjMatrix.M22);
            Ray viewRay = new Ray(new Vector3(), new Vector3(viewSpacePixel.X, viewSpacePixel.Y, 1.0f));

            // View Ray is now the thing we will use...
            Matrix toWorld = Matrix.Invert(Camera.GetViewMatrix());
            viewRay.Direction = Vector3.TransformNormal(viewRay.Direction, toWorld);
            viewRay.Position = Vector3.TransformCoordinate(viewRay.Position, toWorld);

            return pickClosestObject(root, Camera.GetViewMatrix(), viewRay);
        }
        /// <summary>
        /// Initialize the scene, that's pretty much it.
        /// </summary>
        public void CreateNewScene(out Camera o_Camera, out SceneGraph o_SceneGraph)
        {
            if (!IsExecuted)
            {
                // Create the scene graph
                SceneGraph = new SceneGraph(SlimDX.Matrix.Identity);
                IsExecuted = true;

                // Attach default terrain
                var TerrainThing = new SceneGraph(
                    SlimDX.Matrix.Transformation(SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, new SlimDX.Vector3(1.0f, 1.0f, 1.0f), SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, new SlimDX.Vector3(0.0f, 0.0f, 1.0f))
                );
                TerrainThing.Renderable = new TerrainRenderable(100.0f, 100.0f, 5, 5);

                SceneGraph.AttachChild("TerrainThing", TerrainThing);

                // Attach test object
                var CubeThing = new SceneGraph(
                    SlimDX.Matrix.Transformation(SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, new SlimDX.Vector3(1.0f, 1.0f, 1.0f), SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, new SlimDX.Vector3(38.0f, 1.0f, 1.0f))
                );
                CubeThing.Renderable = new TestRenderable();

                SceneGraph.AttachChild("CubeThing", CubeThing);

                // Create default camera
                var testCamera = new FlightCamera(new SlimDX.Vector3(10.0f, 8.0f, 0.0f));
                Camera = testCamera;
            }
            else
            {
                Debug.WriteLine("Already performed action CreateNewScene");
            }

            o_Camera = Camera;
            o_SceneGraph = SceneGraph;
        }
        public void Render(SceneGraph SceneGraph, Camera Camera, SlimDX.Matrix ProjMatrix)
        {
            // Set input assembler information...
            ImmediateContext.InputAssembler.InputLayout = InputLayout;

            // TODO KAM: Shouldn't the primitive topology be set by the objects being rendered themselves?
            ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

            // Build our vertex and index buffer...
            var verts = GetAllVertices(SceneGraph);
            var indices = GetAllIndices(SceneGraph);

            var vertBufferDesc = new BufferDescription(TestEffectVertex.Stride * verts.Length,
                ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            Util.ReleaseCom(ref VertexBuffer); // TODO KAM: Make this dirtyable instead
            VertexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(verts, true, false), vertBufferDesc);

            var indexBuferDesc = new BufferDescription(
                sizeof(uint) * indices.Length,
                ResourceUsage.Default,
                BindFlags.IndexBuffer,
                CpuAccessFlags.None,
                ResourceOptionFlags.None,
                0
            );
            Util.ReleaseCom(ref IndexBuffer);
            IndexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(indices, false, false), indexBuferDesc);

            // Set our vertex and index buffers
            ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, TestEffectVertex.Stride, 0));
            ImmediateContext.InputAssembler.SetIndexBuffer(IndexBuffer, SlimDX.DXGI.Format.R32_UInt, 0);

            // Go through, render all nodes
            var renderPass = EffectTechnique.GetPassByIndex(0);
            renderPass.Apply(ImmediateContext);
            int a, b;
            RenderNode(SceneGraph, Camera, ProjMatrix, 0, 0, out a, out b);
        }
        private void RenderNode(SceneGraph Node, Camera Camera, SlimDX.Matrix ProjMatrix, int indexOffset, int vertexOffset, out int indicesConsumed, out int verticesConsumed)
        {
            var ic = indexOffset;
            var vc = vertexOffset;

            if (Node.Renderable != null)
            {
                WorldViewProj = Node.WorldTransform * Camera.GetViewMatrix() * ProjMatrix;
                CPO_WorldViewProj.SetMatrix(WorldViewProj);

                int nIndices = Node.Renderable.GetIndexList(EffectName()).Length;
                int nVerts = Node.Renderable.GetVertexList(EffectName()).Length;

                // TODO KAM: This is horribly inefficient, change this!
                ImmediateContext.DrawIndexed(nIndices, indexOffset, vertexOffset);

                ic += nIndices;
                vc += nVerts;
            }

            foreach (var Child in Node.Children)
            {
                int cic, cvc;
                RenderNode(Child.Value, Camera, ProjMatrix, indexOffset + ic, vertexOffset + vc, out cic, out cvc);
                ic += cic;
                vc += cvc;
            }

            indicesConsumed = ic;
            verticesConsumed = vc;
        }
        public void Render(SceneGraph SceneGraph, Camera Camera, Matrix ProjMatrix)
        {
            // Set input assembler information...
            ImmediateContext.InputAssembler.InputLayout = InputLayout;
            ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

            // Since a menu node is a root node (according to the scene graph),
            //  just draw it without traversing or recursing or any of that mess.
            var vertsList = new List<object>();
            var indicesList = new List<uint>();
            var sets = new List<Tuple<int, int>>();
            vertsList.AddRange(SceneGraph.Renderable.GetVertexList(EffectName()));
            indicesList.AddRange(SceneGraph.Renderable.GetIndexList(EffectName()));
            sets.Add(new Tuple<int, int>(vertsList.Count, indicesList.Count));

            // TODO KAM: Remove this hack.
            if (vertsList.Count == 0)
            {
                return;
            }

            // Render buttons individually, both action and submenu buttons
            var menuButtons = (SceneGraph.Renderable as Menu).MenuButtons;
            for (var i = 0; i < menuButtons.Length; i++)
            {
                vertsList.AddRange(menuButtons[i].GetVertexList(EffectName()));
                indicesList.AddRange(menuButtons[i].GetIndexList(EffectName()));
                sets.Add(new Tuple<int, int>(vertsList.Count, indicesList.Count));
            }

            var vertexBufferDesc = new BufferDescription(MenuEffectVertex.Stride * vertsList.Count,
                ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            Util.ReleaseCom(ref VertexBuffer); // TODO KAM: Make this dirtyable instead
            VertexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(vertsList.Cast<MenuEffectVertex>().ToArray(), false, false), vertexBufferDesc);

            var indexBufferDesc = new BufferDescription(
                sizeof(uint) * indicesList.Count,
                ResourceUsage.Default,
                BindFlags.IndexBuffer,
                CpuAccessFlags.None,
                ResourceOptionFlags.None,
                0);
            Util.ReleaseCom(ref IndexBuffer);
            IndexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(indicesList.ToArray(), false, false), indexBufferDesc);

            // Set buffers
            ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, MenuEffectVertex.Stride, 0));
            ImmediateContext.InputAssembler.SetIndexBuffer(IndexBuffer, SlimDX.DXGI.Format.R32_UInt, 0);

            Pass = Technique.GetPassByIndex(0);
            CPO_BlendColor.Set(new Vector4(1.0f, 1.0f, 1.0f, 0.8f)); // 80% opacity

            //
            // Set depth stencil state
            //
            var existingState = ImmediateContext.OutputMerger.DepthStencilState;
            ImmediateContext.OutputMerger.DepthStencilState = DepthDisabledState;

            //
            // Render background...
            //
            SRV_DiffuseMap.SetResource(TextureManager.GetInstance().GetResource(Device, SceneGraph.Renderable.GetTexturePath()));
            Pass.Apply(ImmediateContext);
            ImmediateContext.DrawIndexed(sets[0].Item2, 0, 0);

            //
            // Render each button...
            //
            for (var i = 0; i < menuButtons.Length; i++)
            {
                CPO_BlendColor.Set(menuButtons[i].GetBlendColor());
                SRV_DiffuseMap.SetResource(TextureManager.GetInstance().GetResource(Device, menuButtons[i].GetTexturePath()));
                Pass.Apply(ImmediateContext);
                ImmediateContext.DrawIndexed(6, sets[i].Item2, sets[i].Item1);
            }

            //
            // Restore depth stencil state
            //
            ImmediateContext.OutputMerger.DepthStencilState = existingState;
        }