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; }