// TODO: Switch to lower quality pixel Format to reduce memory overhead // TODO: Find memory leak on move and resize public D3Drenderer(GraphView_StateManager manager, View.GraphView_CurveView View) { ((GameEditor_GraphView.ViewModel.CurveGraphViewModel)manager.ViewModel).Items.CollectionChanged += ViewModelChanged; Configuration.EnableObjectTracking = true; screenWidth = (float)SystemParameters.PrimaryScreenWidth; screenHeight = (float)SystemParameters.PrimaryScreenHeight; _RenderForm = new RenderForm(""); SetRenderDimensions(2048, 1280); //_RenderForm. _RenderForm.TopLevel = false; _RenderForm.FormBorderStyle = FormBorderStyle.None; CreateSwapChain(); manager.RefRenderer(this); mre = new ManualResetEvent(false); manager.SetupResetEvent(ref mre); // Create Device and set device context // D3D11 Device Device.CreateWithSwapChain( DriverType.Hardware, DeviceCreationFlags.BgraSupport, _SwapDesc, out _device, out _swapChain); _context = _device.ImmediateContext; }
/// <summary> /// Converts D3D coords to Canvas coords /// </summary> /// <param name="manager"></param> /// <param name="viewPort"></param> /// <param name="worldViewProj"></param> /// <returns></returns> private List <List <windows.Point> > PointToScreenSpace(GraphView_StateManager manager, Viewport viewPort, Matrix worldViewProj) { List <List <windows.Point> > finalList = new List <List <windows.Point> >(); var curveList = ((GameEditor_GraphView.ViewModel.CurveGraphViewModel)manager.ViewModel).ModelItems.Item.Curve; var camera = ((ViewModel.CurveGraphViewModel)manager.ViewModel).Camera; for (int j = 0; j < curveList.Count; j++) { var list = new List <windows.Point>(); var points = curveList[j].Points; for (int i = 0; i < points.Count; i++) { // Converts point in D3D space to screen space // var vector = new Vector3((float)(points[i].X - camera.GetTransform(0, 0)), (float)(points[i].Y - camera.GetTransform(0, 1)), 1); var vector = new Vector3((float)points[i].X, (float)points[i].Y, 1); var space = Vector3.Project(vector, 0, 1, viewPort.Width, viewPort.Height, 0.0f, 100.0f, worldViewProj); list.Add(new windows.Point(space.X, space.Y)); } finalList.Add(list); } return(finalList); }
/// <summary> /// Calculates Vertices from model curve /// </summary> /// <param name="manager"></param> private void CalculateQuads(GraphView_StateManager manager) { int index = 0; try { var item = ((GameEditor_GraphView.ViewModel.CurveGraphViewModel)manager.ViewModel).ModelItems.Item; var curveList = item.Curve; Console.WriteLine(_RenderForm.Width); var grid = GraphGridV2.Draw(((ViewModel.CurveGraphViewModel)manager.ViewModel).Camera, _RenderForm.Width, _RenderForm.Height); int gridSeperator = item.Curve.Count; vertices = null; Console.WriteLine(grid.Count + " is the grid count"); // Number of points times the numbers of points for 2 triangles(6), // times vector attributes in shader (3 for location, 1 for color) vertices = new Vector4[(item.GetCount + grid.Count) * 18]; var color = new Vector4(0.0f, 1.0f, 0.0f, 1.0f); var gridColor = new Vector4(0.1f, 0.1f, 0.0f, 1.0f); for (int i = 0; i < curveList.Count; i++) { CalculateVertices(curveList[i].Points, ref index, color); } CalculateVertices(grid, ref index, gridColor, true); } catch (Exception) { throw; } }
public MainWindow() { InitializeComponent(); ProjectStateManager = ProjectStateManager.Instance; GraphView_StateManager graphView_StateManager = new GraphView_StateManager(); ProjectStateManager.StateManagers.Add(graphView_StateManager); GraphViewMainGrid.Children.Add(graphView_StateManager.View); Closing += graphView_StateManager.Dispose; }
/// <summary> /// Sends bitmap to ViewModel through manager /// </summary> /// <param name="bitmapTarget"></param> /// <param name="data"></param> /// <param name="screenPoints"></param> /// <param name="manager"></param> private void DisplayBitmap(D2D1.BitmapRenderTarget bitmapTarget, byte[] data, List <List <windows.Point> > screenPoints, GraphView_StateManager manager) { if (bitmapTarget != null && data != null) { int height = 0; int width = 0; float dpiHeight = 0; float dpiWidth = 0; using (var bitmap = bitmapTarget.Bitmap) { height = bitmap.PixelSize.Height; width = bitmap.PixelSize.Width; dpiHeight = bitmap.DotsPerInch.Height; dpiWidth = bitmap.DotsPerInch.Width; } bitmapTarget.Dispose(); displayThread = new Thread(() => manager.SetupView(height, width, dpiHeight, dpiWidth, data, screenPoints)); displayThread.SetApartmentState(ApartmentState.STA); displayThread.Start(); } }
/// <summary> /// Starts render loop /// </summary> /// <param name="manager"></param> /// <param name="View"></param> public void Render(GraphView_StateManager manager, View.GraphView_CurveView View) { var signature = CreateShaders("Smooth.fx"); //var signature = CreateShaders(); var layout = new InputLayout(_device, signature, new[] { new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0), new InputElement("TEXCOORD", 0, Format.R32G32B32A32_Float, 32, 0) }); SetSamplerState(); // Instantiate buffers CreateVertexBuffer(); CreateConstantBuffer(); // Prepare Context SetUpContext(layout); // Prepare matrices var view = Matrix.OrthoLH(_RenderForm.ClientSize.Width, _RenderForm.ClientSize.Width, 0.00f, 10000.0f); Matrix proj = Matrix.Identity; // Declare texture for rendering bool userResized = true; Texture2D backBuffer = null; RenderTargetView renderView = null; Texture2D depthBuffer = null; DepthStencilView depthView = null; var camera = ((ViewModel.CurveGraphViewModel)manager.ViewModel).Camera; var rastDesc = new RasterizerStateDescription { FillMode = FillMode.Solid, CullMode = CullMode.None, IsAntialiasedLineEnabled = true, IsMultisampleEnabled = true }; var viewPort = new Viewport(0, 0, _RenderForm.ClientSize.Width, _RenderForm.ClientSize.Height); _RenderForm.UserResized += (sender, args) => userResized = true; // Main loop RenderLoop.Run(_RenderForm, () => { //TODO: Check for if collectionchanged event has been raised and trigger vertex recalculation if (IsViewModelChanged || !MessageQueue.IsEmpty || true) { CreateSwapChain(); IsViewModelChanged = false; if (true) { if (WindowResized()) { userResized = true; } SetSamplerState(); } // If Form resized if (userResized) { Console.WriteLine("resizing"); // Dispose all previous allocated resources Utilities.Dispose(ref backBuffer); Utilities.Dispose(ref renderView); Utilities.Dispose(ref depthBuffer); Utilities.Dispose(ref depthView); // Resizing buffers _swapChain.ResizeBuffers( _SwapDesc.BufferCount, //2048, //1280, _RenderForm.Width, _RenderForm.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None ); backBuffer = Texture2D.FromSwapChain <Texture2D>(_swapChain, 0); renderView = new RenderTargetView(_device, backBuffer); // Create the depth buffer depthBuffer = new Texture2D(_device, new Texture2DDescription() { Format = Format.D32_Float_S8X24_UInt, ArraySize = 1, MipLevels = 1, //Width = 2048, //Height = 1280, Width = _RenderForm.Width, Height = _RenderForm.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }); // Create the depth buffer view depthView = new DepthStencilView(_device, depthBuffer); viewPort.Width = _RenderForm.ClientSize.Width; viewPort.Height = _RenderForm.ClientSize.Height; // Setup targets and viewport for rendering _context.Rasterizer.SetViewport(viewPort); _context.OutputMerger.SetTargets(depthView, renderView); _context.Rasterizer.State = new RasterizerState(_device, rastDesc); userResized = false; } Thread vertexThread = new Thread(() => CalculateQuads(manager)); vertexThread.Start(); // World Matrix // The World Matrix translates the position of your vertices from model space to World space. // That means it applies its position in the world and its rotation var world = CalculateWorldTransform(camera); // A view matrix tells the GPU the position of the camera, the point the camera is facing, // and the up vector for the camera view = Matrix.LookAtLH(new Vector3(0, 0, -100), new Vector3(0, 0, 0), Vector3.Up); // A projection matrix tells the GPU the FOV, aspect ratio, and near and far clipping planes for the camera //proj = Matrix.OrthoLH(1280, 720, 0.00f, 1000.0f); proj = Matrix.OrthoLH(screenWidth, screenHeight, 0.00f, 1000.0f); var viewProj = Matrix.Multiply(view, proj); //var worldViewProj = Matrix.Multiply(world, proj); var worldViewProj = Matrix.Multiply(world, viewProj); // Clear views and set background as transparent _context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0); _context.ClearRenderTargetView(renderView, new SharpDX.Mathematics.Interop.RawColor4(0, 0, 0, 0.0f)); var screenPoints = PointToScreenSpace(manager, viewPort, worldViewProj); worldViewProj.Transpose(); _context.UpdateSubresource(ref worldViewProj, _ConstantBuffer); // Instantiate Vertex buffer from vertex data vertexThread.Join(); CreateVertexBuffer(); SetUpContext(layout); // Draw _context.Draw(vertices.Length, 0); // Convert backbuffer to texture, then to bitmap for display D2D1.BitmapRenderTarget target = RenderBitmap(); // Get byte array for bitmap byte[] data = CalculateBitmapBytes(backBuffer); DisplayBitmap(target, data, screenPoints, manager); // Dispose all previous allocated resources _context.Flush(); screenPoints = null; GC.Collect(); if (displayThread != null) { displayThread.Join(); } mre.Reset(); mre.WaitOne(); } // End of renderloop }); // Release all resources _context.ClearState(); _context.Flush(); DisposeResources(); signature.Dispose(); layout.Dispose(); depthBuffer.Dispose(); backBuffer.Dispose(); depthView.Dispose(); renderView.Dispose(); }