protected override async Task LoadContent() { await base.LoadContent(); wireframeState = new RasterizerStateDescription(CullMode.Back) { FillMode = FillMode.Wireframe }; simpleEffect = new EffectInstance(new Effect(GraphicsDevice, SpriteEffect.Bytecode)); // TODO GRAPHICS REFACTOR simpleEffect.Parameters.Set(TexturingKeys.Texture0, UVTexture); simpleEffect.UpdateEffect(GraphicsDevice); primitives = new List<GeometricPrimitive>(); // Creates all primitives primitives = new List<GeometricPrimitive> { GeometricPrimitive.Plane.New(GraphicsDevice), GeometricPrimitive.Cube.New(GraphicsDevice), GeometricPrimitive.Sphere.New(GraphicsDevice), GeometricPrimitive.GeoSphere.New(GraphicsDevice), GeometricPrimitive.Cylinder.New(GraphicsDevice), GeometricPrimitive.Torus.New(GraphicsDevice), GeometricPrimitive.Teapot.New(GraphicsDevice), GeometricPrimitive.Capsule.New(GraphicsDevice, 0.5f, 0.3f), GeometricPrimitive.Cone.New(GraphicsDevice) }; view = Matrix.LookAtRH(new Vector3(0, 0, 5), new Vector3(0, 0, 0), Vector3.UnitY); Window.AllowUserResizing = true; }
/// <summary> /// /// </summary> /// <param name="depthBias"></param> protected override void OnRasterStateChanged(int depthBias) { if (this.IsAttached) { Disposer.RemoveAndDispose(ref this.rasterState); /// --- set up rasterizer states var rasterStateDesc = new RasterizerStateDescription() { FillMode = FillMode.Solid, CullMode = CullMode.Back, DepthBias = depthBias, DepthBiasClamp = -1000, SlopeScaledDepthBias = +0, IsDepthClipEnabled = true, IsFrontCounterClockwise = true, //IsMultisampleEnabled = true, //IsAntialiasedLineEnabled = true, //IsScissorEnabled = true, }; try { this.rasterState = new RasterizerState(this.Device, rasterStateDesc); } catch (System.Exception) { } } }
public RasterizerStateChangeCommand(RasterizerStateDescription rStateDesc) : base(CommandType.RasterizerStateChange) { CommandAttributes |= CommandAttributes.MonoRendering; Description = rStateDesc; rasterizerState = RasterizerState.FromDescription(Game.Context.Device, Description); }
public static PrimitiveRasterizer CreateRasterizer( PrimitiveTopology primitiveTopology, RasterizerStateDescription rasterizerState, int multiSampleCount, ShaderOutputInputBindings outputInputBindings, ref Viewport viewport, Func<int, int, bool> fragmentQuadFilter) { switch (primitiveTopology) { case PrimitiveTopology.PointList: throw new NotImplementedException(); case PrimitiveTopology.LineList: case PrimitiveTopology.LineStrip: throw new NotImplementedException(); case PrimitiveTopology.TriangleList: case PrimitiveTopology.TriangleStrip: return new TriangleRasterizer( rasterizerState, multiSampleCount, outputInputBindings, ref viewport, fragmentQuadFilter); default: throw new ArgumentOutOfRangeException("primitiveTopology"); } }
protected override async Task LoadContent() { await base.LoadContent(); batch = new Sprite3DBatch(GraphicsDevice); sphere = Content.Load<Texture>("Sphere"); rotatedImages = Content.Load<SpriteSheet>("RotatedImages"); rasterizerState = new RasterizerStateDescription(CullMode.None); }
public TriangleRasterizer( RasterizerStateDescription rasterizerState, int multiSampleCount, ShaderOutputInputBindings outputInputBindings, ref Viewport viewport, Func<int, int, bool> fragmentFilter) : base(rasterizerState, multiSampleCount, outputInputBindings, ref viewport, fragmentFilter) { }
protected PrimitiveRasterizer( RasterizerStateDescription rasterizerState, int multiSampleCount, ShaderOutputInputBindings outputInputBindings, ref Viewport viewport, Func<int, int, bool> fragmentFilter) { RasterizerState = rasterizerState; MultiSampleCount = multiSampleCount; OutputInputBindings = outputInputBindings; ScreenBounds = new Box2D( viewport.TopLeftX, viewport.TopLeftY, viewport.TopLeftX + viewport.Width, viewport.TopLeftY + viewport.Height); FragmentFilter = fragmentFilter; }
public void MakeBothSidesRendered() { var rsDesc = new RasterizerStateDescription(); rsDesc.IsAntialiasedLineEnabled = false; rsDesc.CullMode = CullMode.None; rsDesc.DepthBias = 0; rsDesc.DepthBiasClamp = 0; rsDesc.IsDepthClipEnabled = true; rsDesc.FillMode = FillMode.Solid; rsDesc.IsFrontCounterclockwise = false; rsDesc.IsMultisampleEnabled = false; rsDesc.IsScissorEnabled = false; rsDesc.SlopeScaledDepthBias = 0; Device.Rasterizer.State = RasterizerState.FromDescription(Device, rsDesc); }
public void SetDefaultRasterizer() { this.Rasterizer = new RasterizerStateDescription() { CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = 0.0f, FillMode = FillMode.Solid, IsAntialiasedLineEnabled = false, IsDepthClipEnabled = true, IsFrontCounterclockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = 0.0f }; }
// ReSharper restore NotAccessedField.Local public void CreateDeviceObjects(IRendererContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var c = (VeldridRendererContext)context; var cl = c.CommandList; var gd = c.GraphicsDevice; var sc = c.SceneContext; ResourceFactory factory = gd.ResourceFactory; _vb = factory.CreateBuffer(new BufferDescription(Vertices.SizeInBytes(), BufferUsage.VertexBuffer)); _ib = factory.CreateBuffer(new BufferDescription(Indices.SizeInBytes(), BufferUsage.IndexBuffer)); _miscUniformBuffer = factory.CreateBuffer(new BufferDescription(MiscUniformData.SizeInBytes, BufferUsage.UniformBuffer)); _vb.Name = "TileMapVertexBuffer"; _ib.Name = "TileMapIndexBuffer"; _miscUniformBuffer.Name = "TileMapMiscBuffer"; cl.UpdateBuffer(_vb, 0, Vertices); cl.UpdateBuffer(_ib, 0, Indices); var shaderCache = Resolve <IShaderCache>(); _shaders = shaderCache.GetShaderPair(gd.ResourceFactory, VertexShaderName, FragmentShaderName, shaderCache.GetGlsl(VertexShaderName), shaderCache.GetGlsl(FragmentShaderName)); var shaderSet = new ShaderSetDescription(new[] { VertexLayout, InstanceLayout }, _shaders); _layout = factory.CreateResourceLayout(PerSpriteLayoutDescription); _textureSampler = gd.ResourceFactory.CreateSampler(new SamplerDescription( SamplerAddressMode.Clamp, SamplerAddressMode.Clamp, SamplerAddressMode.Clamp, SamplerFilter.MinPoint_MagPoint_MipPoint, null, 1, 0, 0, 0, SamplerBorderColor.TransparentBlack )); var depthStencilMode = gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyLessEqual : DepthStencilStateDescription.DepthOnlyGreaterEqual; var rasterizerMode = new RasterizerStateDescription( FaceCullMode.Front, PolygonFillMode.Solid, FrontFace.Clockwise, true, true); var pd = new GraphicsPipelineDescription( BlendStateDescription.SingleAlphaBlend, depthStencilMode, rasterizerMode, PrimitiveTopology.TriangleList, new ShaderSetDescription(new[] { VertexLayout, InstanceLayout }, shaderSet.Shaders, ShaderHelper.GetSpecializations(gd)), new[] { _layout, sc.CommonResourceLayout }, gd.SwapchainFramebuffer.OutputDescription); _pipeline = factory.CreateGraphicsPipeline(ref pd); _pipeline.Name = "P_TileMapRenderer"; _disposeCollector.Add(_vb, _ib, _layout, _textureSampler, _pipeline); }
/// <summary> /// Dessine cette cellule. /// </summary> public void Draw() { // Dessine la cellule. var device = Scene.GetGraphicsDevice().ImmediateContext; device.InputAssembler.SetIndexBuffer(Generation.ModelGenerator.GetIndexBuffer(GridResolution), Format.R32_UInt, 0); device.InputAssembler.PrimitiveTopology = (PrimitiveTopology.TriangleList); device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(m_vBuffer, Graphics.VertexPositionTextureNormal.Vertex.Stride, 0)); RasterizerStateDescription rsd = new RasterizerStateDescription() { CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = 0.0f, FillMode = FillMode.Solid, IsAntialiasedLineEnabled = true, IsDepthClipEnabled = true, IsFrontCounterclockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = 0.0f }; // Alpha blending var transDesc = new BlendStateDescription { AlphaToCoverageEnable = false, IndependentBlendEnable = false }; transDesc.RenderTargets[0].BlendEnable = true; transDesc.RenderTargets[0].SourceBlend = BlendOption.SourceAlpha; transDesc.RenderTargets[0].DestinationBlend = BlendOption.InverseSourceAlpha; transDesc.RenderTargets[0].BlendOperation = BlendOperation.Add; transDesc.RenderTargets[0].SourceBlendAlpha = BlendOption.One; transDesc.RenderTargets[0].DestinationBlendAlpha = BlendOption.Zero; transDesc.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add; transDesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; var bs = BlendState.FromDescription(device.Device, transDesc); device.OutputMerger.BlendState = bs; RasterizerState rs = RasterizerState.FromDescription(Scene.GetGraphicsDevice(), rsd); device.Rasterizer.State = rs; // Variables Graphics.WaterEffect effect = Scene.GetGraphicsEngine().WaterEffect; effect.Apply(Matrix.Identity, Scene.Instance.Camera.View, Scene.Instance.Camera.Projection, m_material); device.DrawIndexed(Generation.ModelGenerator.GetIndexBuffer(GridResolution).Description.SizeInBytes / sizeof(int), 0, 0); device.OutputMerger.BlendState = null; }
private SharpDX.Direct3D12.RasterizerStateDescription CreateRasterizerState(RasterizerStateDescription description) { SharpDX.Direct3D12.RasterizerStateDescription nativeDescription; nativeDescription.CullMode = (SharpDX.Direct3D12.CullMode)description.CullMode; nativeDescription.FillMode = (SharpDX.Direct3D12.FillMode)description.FillMode; nativeDescription.IsFrontCounterClockwise = description.FrontFaceCounterClockwise; nativeDescription.DepthBias = description.DepthBias; nativeDescription.SlopeScaledDepthBias = description.SlopeScaleDepthBias; nativeDescription.DepthBiasClamp = description.DepthBiasClamp; nativeDescription.IsDepthClipEnabled = description.DepthClipEnable; //nativeDescription.IsScissorEnabled = description.ScissorTestEnable; nativeDescription.IsMultisampleEnabled = description.MultiSampleLevel >= MSAALevel.None; nativeDescription.IsAntialiasedLineEnabled = description.MultiSampleAntiAliasLine; nativeDescription.ConservativeRaster = ConservativeRasterizationMode.Off; nativeDescription.ForcedSampleCount = 0; return nativeDescription; }
public static void Initialize(Device device) { { var blendStateDescription = new BlendStateDescription(); blendStateDescription.RenderTargets[0].BlendEnable = false; blendStateDescription.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; blendStateDescription.RenderTargets[1].BlendEnable = false; blendStateDescription.RenderTargets[1].RenderTargetWriteMask = ColorWriteMaskFlags.None; blendStateDescription.RenderTargets[2].BlendEnable = false; blendStateDescription.RenderTargets[2].RenderTargetWriteMask = ColorWriteMaskFlags.None; blendStateDescription.RenderTargets[3].BlendEnable = false; blendStateDescription.RenderTargets[3].RenderTargetWriteMask = ColorWriteMaskFlags.None; m_BlendStates[(int)BlendType.None] = BlendState.FromDescription(device, blendStateDescription); blendStateDescription.RenderTargets[0].BlendEnable = true; blendStateDescription.RenderTargets[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add; blendStateDescription.RenderTargets[0].DestinationBlend = BlendOption.One; blendStateDescription.RenderTargets[0].DestinationBlendAlpha = BlendOption.One; blendStateDescription.RenderTargets[0].SourceBlend = BlendOption.One; blendStateDescription.RenderTargets[0].SourceBlendAlpha = BlendOption.One; blendStateDescription.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; m_BlendStates[(int)BlendType.Additive] = BlendState.FromDescription(device, blendStateDescription); } { var depthStencilStateDescription = new DepthStencilStateDescription(); depthStencilStateDescription.DepthComparison = Comparison.Always; depthStencilStateDescription.DepthWriteMask = DepthWriteMask.Zero; depthStencilStateDescription.IsDepthEnabled = false; depthStencilStateDescription.IsStencilEnabled = false; depthStencilStateDescription.DepthWriteMask = DepthWriteMask.Zero; m_DepthStencilStates[(int)DepthConfigurationType.NoDepth] = DepthStencilState.FromDescription(device, depthStencilStateDescription); depthStencilStateDescription.DepthComparison = Comparison.LessEqual; depthStencilStateDescription.DepthWriteMask = DepthWriteMask.All; depthStencilStateDescription.IsDepthEnabled = true; m_DepthStencilStates[(int)DepthConfigurationType.DepthWriteCompare] = DepthStencilState.FromDescription(device, depthStencilStateDescription); depthStencilStateDescription.DepthWriteMask = DepthWriteMask.Zero; m_DepthStencilStates[(int)DepthConfigurationType.DepthCompare] = DepthStencilState.FromDescription(device, depthStencilStateDescription); } { var rasterizerStateDescription = new RasterizerStateDescription(); rasterizerStateDescription.DepthBias = 0; rasterizerStateDescription.DepthBiasClamp = 0; rasterizerStateDescription.FillMode = FillMode.Solid; rasterizerStateDescription.IsAntialiasedLineEnabled = false; rasterizerStateDescription.IsDepthClipEnabled = true; rasterizerStateDescription.IsMultisampleEnabled = false; rasterizerStateDescription.IsScissorEnabled = false; rasterizerStateDescription.SlopeScaledDepthBias = 0; rasterizerStateDescription.CullMode = CullMode.None; m_RasterizerStates[(int)RasterizerStateType.CullNone] = RasterizerState.FromDescription(device, rasterizerStateDescription); rasterizerStateDescription.CullMode = CullMode.Front; m_RasterizerStates[(int)RasterizerStateType.CullFront] = RasterizerState.FromDescription(device, rasterizerStateDescription); rasterizerStateDescription.CullMode = CullMode.Back; m_RasterizerStates[(int)RasterizerStateType.CullBack] = RasterizerState.FromDescription(device, rasterizerStateDescription); } }
/// <summary> /// Dessine cette cellule. /// </summary> public override void Draw() { if (!m_genTask.IsRessourceReady) throw new Exception("Unable to draw this ressource when it is not ready !"); // Dessine la cellule. var device = Scene.GetGraphicsDevice().ImmediateContext; device.InputAssembler.SetIndexBuffer(Generation.ModelGenerator.GetIndexBuffer(GridResolution), Format.R32_UInt, 0); device.InputAssembler.PrimitiveTopology = (PrimitiveTopology.TriangleList); device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(m_genTask.Ressource.VertexBuffer, Graphics.VertexPositionTextureNormal.Vertex.Stride, 0)); RasterizerStateDescription rsd = new RasterizerStateDescription() { CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = 0.0f, FillMode = RasterizerFillMode, IsAntialiasedLineEnabled = true, IsDepthClipEnabled = true, IsFrontCounterclockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = 0.0f }; RasterizerState rs = RasterizerState.FromDescription(Scene.GetGraphicsDevice(), rsd); device.Rasterizer.State = rs; // Variables Graphics.BasicEffect effect = Scene.GetGraphicsEngine().BasicEffect; effect.Apply(Matrix.Identity, Scene.Instance.Camera.View, Scene.Instance.Camera.Projection, m_material); device.DrawIndexed(Generation.ModelGenerator.GetIndexBuffer(GridResolution).Description.SizeInBytes / sizeof(int), 0, 0); }
protected override void OnRasterStateChanged() { if (this.IsAttached) { Disposer.RemoveAndDispose(ref this.rasterState); /// --- set up rasterizer states var rasterStateDesc = new RasterizerStateDescription() { FillMode = FillMode.Solid, CullMode = CullMode.None, DepthBias = DepthBias, DepthBiasClamp = -1000, SlopeScaledDepthBias = -2, IsDepthClipEnabled = true, IsFrontCounterClockwise = false, IsMultisampleEnabled = true, //IsAntialiasedLineEnabled = true, // Intel HD 3000 doesn't like this (#10051) and it's not needed //IsScissorEnabled = true, }; try { this.rasterState = new RasterizerState(this.Device, rasterStateDesc); } catch (System.Exception) { } } }
public override void Run() { #region Create renderers // Note: the renderers take care of creating their own // device resources and listen for DeviceManager.OnInitialize #region Initialize MeshRenderer instances // Create and initialize the mesh renderer var loadedMesh = Common.Mesh.LoadFromFile("Scene.cmo"); List <MeshRenderer> meshes = new List <MeshRenderer>(); meshes.AddRange((from mesh in loadedMesh select ToDispose(new MeshRenderer(mesh)))); // We will support a envmap for each mesh that contains "reflector" in its name List <DualParaboloidMap> envMaps = new List <DualParaboloidMap>(); // We will rotate any meshes that contains "rotate" in its name List <MeshRenderer> rotateMeshes = new List <MeshRenderer>(); // We will generate meshRows * meshColumns of any mesh that contains "replicate" in its name int meshRows = 10; int meshColumns = 10; // Define an action to initialize our meshes so that we can // dynamically change the number of reflective surfaces and // replicated meshes Action createMeshes = () => { // Clear context states, ensures we don't have // any of the resources we are going to release // assigned to the pipeline. DeviceManager.Direct3DContext.ClearState(); if (contextList != null) { foreach (var context in contextList) { context.ClearState(); } } // Remove meshes foreach (var mesh in meshes) { mesh.Dispose(); } meshes.Clear(); // Remove environment maps foreach (var envMap in envMaps) { envMap.Dispose(); } envMaps.Clear(); // Create non-replicated MeshRenderer instances meshes.AddRange(from mesh in loadedMesh where !((mesh.Name ?? "").ToLower().Contains("replicate")) select ToDispose(new MeshRenderer(mesh))); #region Create replicated meshes // Add the same mesh multiple times, separate by the combined extent var replicatedMeshes = (from mesh in loadedMesh where (mesh.Name ?? "").ToLower().Contains("replicate") select mesh).ToArray(); if (replicatedMeshes.Length > 0) { var minExtent = (from mesh in replicatedMeshes orderby new { mesh.Extent.Min.X, mesh.Extent.Min.Z } select mesh.Extent).First(); var maxExtent = (from mesh in replicatedMeshes orderby new { mesh.Extent.Max.X, mesh.Extent.Max.Z } descending select mesh.Extent).First(); var extentDiff = (maxExtent.Max - minExtent.Min); for (int x = -(meshColumns / 2); x < (meshColumns / 2); x++) { for (int z = -(meshRows / 2); z < (meshRows / 2); z++) { var meshGroup = (from mesh in replicatedMeshes where (mesh.Name ?? "").ToLower().Contains("replicate") select ToDispose(new MeshRenderer(mesh))).ToList(); // Reposition based on width/depth of combined extent foreach (var m in meshGroup) { m.World.TranslationVector = new Vector3(m.Mesh.Extent.Center.X + extentDiff.X * x, m.Mesh.Extent.Min.Y, m.Mesh.Extent.Center.Z + extentDiff.Z * z); } meshes.AddRange(meshGroup); } } } #endregion #region Create reflective meshes // Create reflections where necessary and add rotation meshes int reflectorCount = 0; meshes.ForEach(m => { var name = (m.Mesh.Name ?? "").ToLower(); if (name.Contains("reflector") && reflectorCount < maxReflectors) { reflectorCount++; var envMap = ToDispose(new DualParaboloidMap(512)); envMap.Reflector = m; envMap.Initialize(this); m.EnvironmentMap = envMap; envMaps.Add(envMap); } if (name.Contains("rotate")) { rotateMeshes.Add(m); } m.Initialize(this); }); #endregion // Initialize each mesh meshes.ForEach(m => m.Initialize(this)); }; createMeshes(); // Set the first animation as the current animation and start clock meshes.ForEach(m => { if (m.Mesh.Animations != null && m.Mesh.Animations.Any()) { m.CurrentAnimation = m.Mesh.Animations.First().Value; } m.Clock.Start(); }); // Create the overall mesh World matrix var meshWorld = Matrix.Identity; #endregion // Create and initialize a Direct2D FPS text renderer var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16)); fps.Initialize(this); // Create and initialize a general purpose Direct2D text renderer // This will display some instructions and the current view and rotation offsets var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12)); textRenderer.Initialize(this); #endregion // Initialize the world matrix var worldMatrix = Matrix.Identity; // Set the camera position slightly behind (z) var cameraPosition = new Vector3(0, 1, 2); var cameraTarget = Vector3.Zero; // Looking at the origin 0,0,0 var cameraUp = Vector3.UnitY; // Y+ is Up // Prepare matrices // Create the view matrix from our camera position, look target and up direction var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp); viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0); // Create the projection matrix /* FoV 60degrees = Pi/3 radians */ // Aspect ratio (based on window size), Near clip, Far clip var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); // Maintain the correct aspect ratio on resize Window.Resize += (s, e) => { projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); }; #region Rotation and window event handlers // Create a rotation vector to keep track of the rotation // around each of the axes var rotation = new Vector3(0.0f, 0.0f, 0.0f); // We will call this action to update text // for the text renderer Action updateText = () => { textRenderer.Text = String.Format( "\nPause rotation: P" + "\nThreads: {0} (+/-)" + "\nReflectors: {1} (Shift-Up/Down)" + "\nCPU load: {2} matrix ops (Shift +/-)" + "\nRotating meshes: {3} (Up/Down, Left/Right)" , threadCount, maxReflectors, additionalCPULoad, meshRows * meshColumns); }; Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>(); keyToggles[Keys.Z] = false; keyToggles[Keys.F] = false; // Support keyboard/mouse input to rotate or move camera view var moveFactor = 0.02f; // how much to change on each keypress var shiftKey = false; var ctrlKey = false; var background = Color.White; Window.KeyDown += (s, e) => { var context = DeviceManager.Direct3DContext; shiftKey = e.Shift; ctrlKey = e.Control; switch (e.KeyCode) { // WASD -> pans view case Keys.A: viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.D: viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.S: if (shiftKey) { viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2; } break; case Keys.W: if (shiftKey) { viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2; } break; // Up/Down and Left/Right - rotates around X / Y respectively // (Mouse wheel rotates around Z) //case Keys.Down: // worldMatrix *= Matrix.RotationX(moveFactor); // rotation += new Vector3(moveFactor, 0f, 0f); // break; //case Keys.Up: // worldMatrix *= Matrix.RotationX(-moveFactor); // rotation -= new Vector3(moveFactor, 0f, 0f); // break; //case Keys.Left: // worldMatrix *= Matrix.RotationY(moveFactor); // rotation += new Vector3(0f, moveFactor, 0f); // break; //case Keys.Right: // worldMatrix *= Matrix.RotationY(-moveFactor); // rotation -= new Vector3(0f, moveFactor, 0f); // break; case Keys.T: fps.Show = !fps.Show; textRenderer.Show = !textRenderer.Show; break; case Keys.B: if (background == Color.White) { background = new Color(30, 30, 34); } else { background = Color.White; } break; case Keys.P: // Pause or resume mesh animation meshes.ForEach(m => { if (m.Clock.IsRunning) { m.Clock.Stop(); } else { m.Clock.Start(); } }); break; case Keys.X: // To test for correct resource recreation // Simulate device reset or lost. System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); DeviceManager.Initialize(DeviceManager.Dpi); System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); break; //case Keys.Z: // keyToggles[Keys.Z] = !keyToggles[Keys.Z]; // if (keyToggles[Keys.Z]) // { // context.PixelShader.Set(depthPixelShader); // } // else // { // context.PixelShader.Set(pixelShader); // } // break; case Keys.F: keyToggles[Keys.F] = !keyToggles[Keys.F]; RasterizerStateDescription rasterDesc; if (context.Rasterizer.State != null) { rasterDesc = context.Rasterizer.State.Description; } else { rasterDesc = new RasterizerStateDescription() { CullMode = CullMode.Back, FillMode = FillMode.Solid } }; if (keyToggles[Keys.F]) { rasterDesc.FillMode = FillMode.Wireframe; rasterizerState = ToDispose(new RasterizerState(context.Device, rasterDesc)); } else { rasterDesc.FillMode = FillMode.Solid; rasterizerState = ToDispose(new RasterizerState(context.Device, rasterDesc)); } break; //case Keys.D1: // context.PixelShader.Set(pixelShader); // break; //case Keys.D2: // context.PixelShader.Set(lambertShader); // break; //case Keys.D3: // context.PixelShader.Set(phongShader); // break; //case Keys.D4: // context.PixelShader.Set(blinnPhongShader); // break; //case Keys.D5: // context.PixelShader.Set(simpleUVShader); // break; //case Keys.D6: // context.PixelShader.Set(lambertUVShader); // break; //case Keys.D7: // context.PixelShader.Set(phongUVShader); // break; //case Keys.D8: // context.PixelShader.Set(blinnPhongUVShader); // break; } updateText(); }; Window.KeyUp += (s, e) => { // Clear the shift/ctrl keys so they aren't sticky if (e.KeyCode == Keys.ShiftKey) { shiftKey = false; } if (e.KeyCode == Keys.ControlKey) { ctrlKey = false; } }; Window.MouseWheel += (s, e) => { if (shiftKey) { // Zoom in/out viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2); } else { // rotate around Z-axis viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor); rotation += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor); } updateText(); }; var lastX = 0; var lastY = 0; Window.MouseDown += (s, e) => { if (e.Button == MouseButtons.Left) { lastX = e.X; lastY = e.Y; } }; Window.MouseMove += (s, e) => { if (e.Button == MouseButtons.Left) { var yRotate = lastX - e.X; var xRotate = lastY - e.Y; lastY = e.Y; lastX = e.X; // Mouse move changes viewMatrix *= Matrix.RotationX(-xRotate * moveFactor); viewMatrix *= Matrix.RotationY(-yRotate * moveFactor); updateText(); } }; // Display instructions with initial values updateText(); #endregion var clock = new System.Diagnostics.Stopwatch(); clock.Start(); // Setup the deferred contexts SetupContextList(); #region Render loop // Whether or not to reinitialize meshes bool initializeMesh = false; // Define additional key handlers for controlling the // number of threads, reflectors, and replicated meshes #region Dynamic Cube map and threading KeyDown handlers Window.KeyDown += (s, e) => { switch (e.KeyCode) { case Keys.Up: if (shiftKey) { maxReflectors++; } else { meshRows += 2; } initializeMesh = true; break; case Keys.Down: if (shiftKey) { maxReflectors = Math.Max(0, maxReflectors - 1); } else { meshRows = Math.Max(2, meshRows - 2); } initializeMesh = true; break; case Keys.Right: meshColumns += 2; initializeMesh = true; break; case Keys.Left: meshColumns = Math.Max(2, meshColumns - 2); initializeMesh = true; break; case Keys.Add: if (shiftKey) { additionalCPULoad += 100; } else { threadCount++; } break; case Keys.Subtract: if (shiftKey) { additionalCPULoad = Math.Max(0, additionalCPULoad - 100); } else { threadCount = Math.Max(1, threadCount - 1); } break; case Keys.Enter: if (keyToggles.ContainsKey(Keys.Enter)) { keyToggles[Keys.Enter] = !keyToggles[Keys.Enter]; } else { keyToggles[Keys.Enter] = true; } break; default: break; } updateText(); }; #endregion #region Render mesh group // Action for rendering a group of meshes for a // context (based on number of available contexts) Action <int, DeviceContext, Matrix, Matrix> renderMeshGroup = (contextIndex, renderContext, view, projection) => { var viewProjection = view * projection; // Determine the meshes to render for this context int batchSize = (int)Math.Floor((double)meshes.Count / contextList.Length); int startIndex = batchSize * contextIndex; int endIndex = Math.Min(startIndex + batchSize, meshes.Count - 1); // If this is the last context include whatever remains to be // rendered due to the rounding above. if (contextIndex == contextList.Length - 1) { endIndex = meshes.Count - 1; } // Loop over the meshes for this context and render them var perObject = new ConstantBuffers.PerObject(); for (var i = startIndex; i <= endIndex; i++) { // Simulate additional CPU load for (var j = 0; j < additionalCPULoad; j++) { viewProjection = Matrix.Multiply(view, projection); } // Retrieve current mesh var m = meshes[i]; // Check if this is a rotating mesh if (rotateMeshes.Contains(m)) { var rotate = Matrix.RotationAxis(Vector3.UnitY, m.Clock.ElapsedMilliseconds / 1000.0f); perObject.World = m.World * rotate * worldMatrix; } else { perObject.World = m.World * worldMatrix; } // Update perObject constant buffer perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.Transpose(); renderContext.UpdateSubresource(ref perObject, perObjectBuffer); // Provide the material and armature constant buffer to the mesh renderer m.PerArmatureBuffer = perArmatureBuffer; m.PerMaterialBuffer = perMaterialBuffer; // Render the mesh using the provided DeviceContext m.Render(renderContext); } }; #endregion #region Render scene // Action for rendering the entire scene Action <DeviceContext, Matrix, Matrix, RenderTargetView, DepthStencilView, DualParaboloidMap> renderScene = (context, view, projection, rtv, dsv, envMap) => { // We must initialize the context every time we render // the scene as we are changing the state depending on // whether we are rendering the envmaps or final scene InitializeContext(context, false); // We always need the immediate context // Note: the passed in context will normally be the immediate context // however it is possible to run this method threaded also. var immediateContext = this.DeviceManager.Direct3DDevice.ImmediateContext; // Clear depth stencil view context.ClearDepthStencilView(dsv, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); // Clear render target view context.ClearRenderTargetView(rtv, background); // Create viewProjection matrix var viewProjection = Matrix.Multiply(view, projection); // Extract camera position from view var camPosition = Matrix.Transpose(Matrix.Invert(view)).Column4; cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z); // Setup the per frame constant buffer var perFrame = new ConstantBuffers.PerFrame(); perFrame.Light.Color = new Color(0.9f, 0.9f, 0.9f, 1.0f); var lightDir = Vector3.Transform(new Vector3(-1f, -1f, -1f), worldMatrix); perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z); perFrame.CameraPosition = cameraPosition; context.UpdateSubresource(ref perFrame, perFrameBuffer); // Render each object // Prepare the default per material constant buffer var perMaterial = new ConstantBuffers.PerMaterial(); perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); // ----------Render meshes------------ if (contextList.Length == 1) { // If there is only one context available there is no need to // generate command lists and execute them so just render the // mesh directly on the current context (which may or may // not be an immediate context depending on the caller). renderMeshGroup(0, context, view, projection); } else { // There are multiple contexts therefore // we are using deferred contexts. Prepare a // separate thread for each available context // and render a group of meshes on each. Task[] renderTasks = new Task[contextList.Length]; CommandList[] commands = new CommandList[contextList.Length]; var viewports = context.Rasterizer.GetViewports(); for (var i = 0; i < contextList.Length; i++) { // Must store the iteration value in another variable // or each task action will use the last iteration value. var contextIndex = i; // Create task to run on new thread from ThreadPool renderTasks[i] = Task.Run(() => { // Retrieve context for this thread var renderContext = contextList[contextIndex]; // Initialize the context state InitializeContext(renderContext, false); // Set the render targets and viewport renderContext.OutputMerger.SetRenderTargets(dsv, rtv); renderContext.Rasterizer.SetViewports(viewports); // If we are rendering for an env map we must set the // per environment map buffer. if (envMap != null) { renderContext.VertexShader.SetConstantBuffer(4, envMap.PerEnvMapBuffer); renderContext.PixelShader.SetConstantBuffer(4, envMap.PerEnvMapBuffer); } // Render logic renderMeshGroup(contextIndex, renderContext, view, projection); // Create the command list if (renderContext.TypeInfo == DeviceContextType.Deferred) { commands[contextIndex] = renderContext.FinishCommandList(false); } }); } // Wait for all the tasks to complete Task.WaitAll(renderTasks); // Replay the command lists on the immediate context for (var i = 0; i < contextList.Length; i++) { if (contextList[i].TypeInfo == DeviceContextType.Deferred && commands[i] != null) { immediateContext.ExecuteCommandList(commands[i], false); // Clean up command list commands[i].Dispose(); commands[i] = null; } } } }; #endregion long frameCount = 0; int lastThreadCount = threadCount; keyToggles[Keys.Enter] = false; // Create and run the render loop RenderLoop.Run(Window, () => { // Allow dynamic changes to number of reflectors and replications if (initializeMesh) { initializeMesh = false; createMeshes(); } if (keyToggles[Keys.Enter]) { // Export the paraboloid maps var i = 0; foreach (var item in envMaps) { using (var tex = item.EnvMapSRV.ResourceAs <Texture2D>()) { for (var j = 0; j < tex.Description.ArraySize; j++) { CopyTexture.SaveToFile(DeviceManager, tex, String.Format("DualMap{0}_{1}.png", i, j), null, tex.Description.MipLevels * j); } i++; } } keyToggles[Keys.Enter] = false; } // Allow dynamic chnages to the number of threads to use if (lastThreadCount != threadCount) { SetupContextList(); lastThreadCount = threadCount; } // Start of frame: frameCount++; // Retrieve immediate context var context = DeviceManager.Direct3DContext; //if (frameCount % 3 == 1) // to update envmap once every third frame //{ #region Update environment maps // Update each of the environment maps activeVertexShader = envMapVSShader; activeGeometryShader = envMapGSShader; activePixelShader = envMapPSShader; // Render the scene from the perspective of each of the environment maps foreach (var envMap in envMaps) { var mesh = envMap.Reflector as MeshRenderer; if (mesh != null) { // Calculate view point for reflector var meshCenter = Vector3.Transform(mesh.Mesh.Extent.Center, mesh.World * worldMatrix); envMap.SetViewPoint(new Vector3(meshCenter.X, meshCenter.Y, meshCenter.Z)); // Render envmap in single full render pass using // geometry shader instancing. envMap.UpdateSinglePass(context, renderScene); } } #endregion //} #region Render final scene // Reset the vertex, geometry and pixel shader activeVertexShader = vertexShader; activeGeometryShader = null; activePixelShader = blinnPhongShader; // Initialize context (also resetting the render targets) InitializeContext(context, true); // Render the final scene renderScene(context, viewMatrix, projectionMatrix, RenderTargetView, DepthStencilView, null); #endregion // Render FPS fps.Render(); // Render instructions + position changes textRenderer.Render(); // Present the frame Present(); }); #endregion } }
private void LoadAssets() { // Create the root signature description. var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, // Root Parameters new[] { new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 }) }, // Samplers new[] { new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0) { Filter = Filter.MinimumMinMagMipPoint, AddressUVW = TextureAddressMode.Border, } }); rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. var inputElementDescs = new [] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0) }; // Describe and create the graphics pipeline state object (PSO). var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a triangle. var triangleVertices = new [] { new Vertex() { Position = new Vector3(0.0f, 0.25f * aspectRatio, 0.0f), TexCoord = new Vector2(0.5f, 0.0f) }, new Vertex() { Position = new Vector3(0.25f, -0.25f * aspectRatio, 0.0f), TexCoord = new Vector2(1.0f, 1.0f) }, new Vertex() { Position = new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f), TexCoord = new Vector2(0.0f, 1.0f) }, }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. var pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf <Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; // Create the texture. // Describe and create a Texture2D. var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight); texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination); long uploadBufferSize = GetRequiredIntermediateSize(this.texture, 0, 1); // Create the GPU upload buffer. var textureUploadHeap = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight), ResourceStates.GenericRead); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. byte[] textureData = GenerateTextureData(); var handle = GCHandle.Alloc(textureData, GCHandleType.Pinned); var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0); textureUploadHeap.WriteToSubresource(0, null, ptr, TexturePixelSize * TextureWidth, textureData.Length); handle.Free(); commandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null); commandList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource); // Describe and create a SRV for the texture. var srvDesc = new ShaderResourceViewDescription { Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(), Format = textureDesc.Format, Dimension = ShaderResourceViewDimension.Texture2D, Texture2D = { MipLevels = 1 }, }; device.CreateShaderResourceView(this.texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); commandQueue.ExecuteCommandList(commandList); // Create synchronization objects. fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); WaitForPreviousFrame(); //release temp texture textureUploadHeap.Dispose(); }
public override void Run() { #region Create renderers // Note: the renderers take care of creating their own // device resources and listen for DeviceManager.OnInitialize // Create a axis-grid renderer var axisGrid = ToDispose(new AxisGridRenderer()); axisGrid.Initialize(this); // Create and initialize the mesh renderer var loadedMesh = Common.Mesh.LoadFromFile("PhysicsScene1.cmo"); List <MeshRenderer> meshes = new List <MeshRenderer>(); meshes.AddRange(from mesh in loadedMesh select ToDispose(new MeshRenderer(mesh))); foreach (var m in meshes) { m.Initialize(this); m.World = Matrix.Identity; } // Set the first animation as the current animation and start clock foreach (var m in meshes) { if (m.Mesh.Animations != null && m.Mesh.Animations.Any()) { m.CurrentAnimation = m.Mesh.Animations.First().Value; } m.Clock.Start(); } loadedMesh = Common.Mesh.LoadFromFile("SubdividedPlane.cmo"); var waterMesh = ToDispose(new MeshRenderer(loadedMesh.First())); waterMesh.Initialize(this); loadedMesh = Common.Mesh.LoadFromFile("Bataux.cmo"); List <MeshRenderer> shipMeshes = new List <MeshRenderer>(); shipMeshes.AddRange((from mesh in loadedMesh select ToDispose(new MeshRenderer(mesh)))); foreach (var m in shipMeshes) { m.Initialize(this); m.World = Matrix.Scaling(3) * Matrix.RotationAxis(Vector3.UnitY, -1.57079f); } //var anchor = new SphereRenderer(0.05f); //anchor.Initialize(this); //var anchorWorld = Matrix.Identity; //var sphere = new SphereRenderer(); //sphere.Initialize(this); //var sphereWorld = Matrix.Identity; // Create and initialize a Direct2D FPS text renderer var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16)); fps.Initialize(this); // Create and initialize a general purpose Direct2D text renderer // This will display some instructions and the current view and rotation offsets var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12)); textRenderer.Initialize(this); #endregion #region Initialize physics engine CollisionConfiguration defaultConfig = new DefaultCollisionConfiguration(); ConstraintSolver solver = new SequentialImpulseConstraintSolver(); BulletSharp.Dispatcher dispatcher = new CollisionDispatcher(defaultConfig); BroadphaseInterface broadphase = new DbvtBroadphase(); DynamicsWorld world = null; Action initializePhysics = () => { RemoveAndDispose(ref world); world = ToDispose(new BulletSharp.DiscreteDynamicsWorld(dispatcher, broadphase, solver, defaultConfig)); world.Gravity = new BulletSharp.Math.Vector3(0, -10, 0); // For each mesh, create a RigidBody and add to "world" for simulation meshes.ForEach(m => { // We use the name of the mesh to determine the correct body if (String.IsNullOrEmpty(m.Mesh.Name)) { return; } var name = m.Mesh.Name.ToLower(); var extent = m.Mesh.Extent; BulletSharp.CollisionShape shape; #region Create collision shape if (name.Contains("box") || name.Contains("cube")) { // Assumes the box/cube has an axis-aligned neutral orientation shape = new BulletSharp.BoxShape( Math.Abs(extent.Max.Z - extent.Min.Z) / 2.0f, Math.Abs(extent.Max.Y - extent.Min.Y) / 2.0f, Math.Abs(extent.Max.X - extent.Min.X) / 2.0f); } else if (name.Contains("sphere")) { shape = new BulletSharp.SphereShape(extent.Radius); } else // use mesh vertices directly { // for each SubMesh, retrieve the vertex and index buffers // to create a TriangleMeshShape for collision detection. List <Vector3> vertices = new List <Vector3>(); List <int> indices = new List <int>(); int vertexOffset = 0; foreach (var sm in m.Mesh.SubMeshes) { vertexOffset += vertices.Count; indices.AddRange( (from indx in m.Mesh.IndexBuffers[(int)sm.IndexBufferIndex] select vertexOffset + (int)indx)); vertices.AddRange( (from v in m.Mesh .VertexBuffers[(int)sm.VertexBufferIndex] select v.Position - extent.Center)); } // Create the collision shape var iva = new BulletSharp.TriangleIndexVertexArray(indices.ToArray(), vertices.ToArray().ToBulletVector3Array()); shape = new BulletSharp.BvhTriangleMeshShape(iva, true); } #endregion m.World = Matrix.Identity; // Reset mesh location float mass; Vector3 vec; BulletSharp.Math.Vector3 bsVec; shape.GetBoundingSphere(out bsVec, out mass); vec = bsVec.ToSharpDXVector3(); var body = new BulletSharp.RigidBody( new BulletSharp.RigidBodyConstructionInfo(name.Contains("static") ? 0 : mass, new MeshMotionState(m), shape, shape.CalculateLocalInertia(mass))); if (body.IsStaticObject) { body.Restitution = 1f; body.Friction = 0.4f; } // Add to the simulation world.AddRigidBody(body); }); #if DEBUG world.DebugDrawer = ToDispose(new PhysicsDebugDraw(this.DeviceManager)); world.DebugDrawer.DebugMode = DebugDrawModes.DrawAabb | DebugDrawModes.DrawWireframe; #endif }; initializePhysics(); // Newton's Cradle //var box = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.BoxShape(7, 1, 2)); //box.Position = new Jitter.LinearMath.JVector(0, 8, 0); //world.AddBody(box); //box.IsStatic = true; //var anchorBody = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.SphereShape(0.05f)); //anchorBody.Position = new Jitter.LinearMath.JVector(0, 4, 0); //world.AddBody(anchorBody); //anchorBody.IsStatic = true; //for (var bodyCount = -3; bodyCount < 4; bodyCount++) //{ // var testBody = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.SphereShape(0.501f)); // testBody.Position = new Jitter.LinearMath.JVector(bodyCount, 0, 0); // world.AddBody(testBody); // world.AddConstraint(new Jitter.Dynamics.Constraints.PointPointDistance(box, testBody, // testBody.Position + Jitter.LinearMath.JVector.Up * 8f + Jitter.LinearMath.JVector.Forward * 3f + Jitter.LinearMath.JVector.Down * 0.5f, // testBody.Position) { Softness = 1.0f, BiasFactor = 0.8f }); // world.AddConstraint(new Jitter.Dynamics.Constraints.PointPointDistance(box, testBody, // testBody.Position + Jitter.LinearMath.JVector.Up * 8f + Jitter.LinearMath.JVector.Backward * 3f + Jitter.LinearMath.JVector.Down * 0.5f, // testBody.Position) { Softness = 1.0f, BiasFactor = 0.8f }); // testBody.Material.Restitution = 1.0f; // testBody.Material.StaticFriction = 1.0f; //} #endregion // Initialize the world matrix var worldMatrix = Matrix.Identity; // Set the camera position slightly behind (z) var cameraPosition = new Vector3(0, 1, 10); var cameraTarget = Vector3.Zero; // Looking at the origin 0,0,0 var cameraUp = Vector3.UnitY; // Y+ is Up // Prepare matrices // Create the view matrix from our camera position, look target and up direction var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp); viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0); // Create the projection matrix /* FoV 60degrees = Pi/3 radians */ // Aspect ratio (based on window size), Near clip, Far clip var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); // Maintain the correct aspect ratio on resize Window.Resize += (s, e) => { projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); }; bool debugDraw = false; bool paused = false; var simTime = new System.Diagnostics.Stopwatch(); simTime.Start(); float time = 0.0f; float timeStep = 0.0f; #region Rotation and window event handlers // Create a rotation vector to keep track of the rotation // around each of the axes var rotation = new Vector3(0.0f, 0.0f, 0.0f); // We will call this action to update text // for the text renderer Action updateText = () => { textRenderer.Text = String.Format("Rotation ({0}) (Up/Down Left/Right Wheel+-)\nView ({1}) (A/D, W/S, Shift+Wheel+-)" //+ "\nPress 1,2,3,4,5,6,7,8 to switch shaders" + "\nTime: {2:0.00} (P to toggle, R to reset scene)" + "\nPhysics debug draw: {3} (E to toggle)" + "\nBackspace: toggle between Physics and Waves", rotation, viewMatrix.TranslationVector, simTime.Elapsed.TotalSeconds, debugDraw); }; Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>(); keyToggles[Keys.Z] = false; keyToggles[Keys.F] = false; keyToggles[Keys.Back] = false; // Support keyboard/mouse input to rotate or move camera view var moveFactor = 0.02f; // how much to change on each keypress var shiftKey = false; var ctrlKey = false; var background = Color.White; var showNormals = false; var enableNormalMap = true; Window.KeyDown += (s, e) => { var context = DeviceManager.Direct3DContext; shiftKey = e.Shift; ctrlKey = e.Control; switch (e.KeyCode) { // WASD -> pans view case Keys.A: viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.D: viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.S: if (shiftKey) { viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2; } break; case Keys.W: if (shiftKey) { viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2; } break; // Up/Down and Left/Right - rotates around X / Y respectively // (Mouse wheel rotates around Z) case Keys.Down: worldMatrix *= Matrix.RotationX(moveFactor); rotation += new Vector3(moveFactor, 0f, 0f); break; case Keys.Up: worldMatrix *= Matrix.RotationX(-moveFactor); rotation -= new Vector3(moveFactor, 0f, 0f); break; case Keys.Left: worldMatrix *= Matrix.RotationY(moveFactor); rotation += new Vector3(0f, moveFactor, 0f); break; case Keys.Right: worldMatrix *= Matrix.RotationY(-moveFactor); rotation -= new Vector3(0f, moveFactor, 0f); break; case Keys.T: fps.Show = !fps.Show; textRenderer.Show = !textRenderer.Show; break; case Keys.B: if (background == Color.White) { background = new Color(30, 30, 34); } else { background = Color.White; } break; case Keys.G: axisGrid.Show = !axisGrid.Show; break; case Keys.P: paused = !paused; if (paused) { simTime.Stop(); } else { simTime.Start(); } // Pause or resume mesh animation meshes.ForEach(m => { if (m.Clock.IsRunning) { m.Clock.Stop(); } else { m.Clock.Start(); } }); updateText(); break; case Keys.X: // To test for correct resource recreation // Simulate device reset or lost. System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); DeviceManager.Initialize(DeviceManager.Dpi); System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); break; case Keys.Z: keyToggles[Keys.Z] = !keyToggles[Keys.Z]; if (keyToggles[Keys.Z]) { context.PixelShader.Set(depthPixelShader); } else { context.PixelShader.Set(pixelShader); } break; case Keys.F: keyToggles[Keys.F] = !keyToggles[Keys.F]; RasterizerStateDescription rasterDesc; if (context.Rasterizer.State != null) { rasterDesc = context.Rasterizer.State.Description; } else { rasterDesc = new RasterizerStateDescription() { CullMode = CullMode.None, FillMode = FillMode.Solid } }; if (keyToggles[Keys.F]) { rasterDesc.FillMode = FillMode.Wireframe; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } else { rasterDesc.FillMode = FillMode.Solid; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } break; case Keys.N: if (!shiftKey) { showNormals = !showNormals; } else { enableNormalMap = !enableNormalMap; } break; case Keys.E: debugDraw = !debugDraw; break; case Keys.R: //world = new Jitter.World(new Jitter.Collision.CollisionSystemSAP()); initializePhysics(); if (simTime.IsRunning) { simTime.Restart(); } else { simTime.Reset(); } break; case Keys.D1: context.PixelShader.Set(pixelShader); break; case Keys.D2: context.PixelShader.Set(lambertShader); break; case Keys.D3: context.PixelShader.Set(phongShader); break; case Keys.D4: context.PixelShader.Set(blinnPhongShader); break; case Keys.Back: keyToggles[Keys.Back] = !keyToggles[Keys.Back]; break; } updateText(); }; Window.KeyUp += (s, e) => { // Clear the shift/ctrl keys so they aren't sticky if (e.KeyCode == Keys.ShiftKey) { shiftKey = false; } if (e.KeyCode == Keys.ControlKey) { ctrlKey = false; } }; Window.MouseWheel += (s, e) => { if (shiftKey) { // Zoom in/out viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2); } else { // rotate around Z-axis viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor); rotation += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor); } updateText(); }; var lastX = 0; var lastY = 0; Window.MouseDown += (s, e) => { if (e.Button == MouseButtons.Left) { lastX = e.X; lastY = e.Y; } }; Window.MouseMove += (s, e) => { if (e.Button == MouseButtons.Left) { var yRotate = lastX - e.X; var xRotate = lastY - e.Y; lastY = e.Y; lastX = e.X; // Mouse move changes viewMatrix *= Matrix.RotationX(-xRotate * moveFactor); viewMatrix *= Matrix.RotationY(-yRotate * moveFactor); updateText(); } }; // Display instructions with initial values updateText(); #endregion var clock = new System.Diagnostics.Stopwatch(); clock.Start(); #region Render loop // Create and run the render loop RenderLoop.Run(Window, () => { // Update simulation, at 60fps if (!paused) { if ((float)simTime.Elapsed.TotalSeconds < time) { time = 0; timeStep = 0; } timeStep = ((float)simTime.Elapsed.TotalSeconds - time); time = (float)simTime.Elapsed.TotalSeconds; world.StepSimulation(timeStep, 7); // For how to choose the maxSubSteps see: // http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World } updateText(); // Start of frame: // Retrieve immediate context var context = DeviceManager.Direct3DContext; // Clear depth stencil view context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); // Clear render target view context.ClearRenderTargetView(RenderTargetView, background); // Create viewProjection matrix var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix); // Extract camera position from view var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4; cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z); var perFrame = new ConstantBuffers.PerFrame(); perFrame.Light.Color = new Color(0.8f, 0.8f, 0.8f, 1.0f); var lightDir = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix); perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z); perFrame.CameraPosition = cameraPosition; perFrame.Time = (float)simTime.Elapsed.TotalSeconds; // Provide simulation time to shader context.UpdateSubresource(ref perFrame, perFrameBuffer); // Render each object var perMaterial = new ConstantBuffers.PerMaterial(); perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); var perObject = new ConstantBuffers.PerObject(); // MESH if (!keyToggles[Keys.Back]) { meshes.ForEach((m) => { perObject.World = m.World * worldMatrix; // Provide the material constant buffer to the mesh renderer perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); m.PerMaterialBuffer = perMaterialBuffer; m.PerArmatureBuffer = perArmatureBuffer; m.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); m.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } }); if (debugDraw) { perObject.World = Matrix.Identity; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); (world.DebugDrawer as PhysicsDebugDraw).DrawDebugWorld(world); context.VertexShader.Set(vertexShader); context.PixelShader.Set(pixelShader); context.InputAssembler.InputLayout = vertexLayout; } } else { perObject.World = waterMesh.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); waterMesh.EnableNormalMap = enableNormalMap; waterMesh.PerMaterialBuffer = perMaterialBuffer; waterMesh.PerArmatureBuffer = perArmatureBuffer; context.VertexShader.Set(waterVertexShader); waterMesh.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); waterMesh.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } context.VertexShader.Set(vertexShader); foreach (var m in shipMeshes) { perObject.World = m.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); // Provide the material constant buffer to the mesh renderer perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); m.PerMaterialBuffer = perMaterialBuffer; m.PerArmatureBuffer = perArmatureBuffer; m.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); m.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } } } perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); // AXIS GRID context.HullShader.Set(null); context.DomainShader.Set(null); context.GeometryShader.Set(null); using (var prevPixelShader = context.PixelShader.Get()) using (var prevVertexShader = context.VertexShader.Get()) { context.VertexShader.Set(vertexShader); context.PixelShader.Set(pixelShader); perObject.World = worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); axisGrid.Render(); context.PixelShader.Set(prevPixelShader); context.VertexShader.Set(prevVertexShader); } // Render FPS fps.Render(); // Render instructions + position changes textRenderer.Render(); // Present the frame Present(); }); #endregion }
public bool Initialize(int screenWidth, int screenHeight, bool vSync, IntPtr hwnd, bool fullScreen, float screenDepth, float screenNear) { try { vSyncEnabled = vSync; Rational refreshRate = new Rational(0, 0); var factory = new Factory1(); var adapter = factory.Adapters[0]; var adapterOutput = adapter.Outputs[0]; var modes = adapterOutput.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced); for (int i = 0; i < modes.Length; i++) { if (modes[i].Width == screenWidth) { if (modes[i].Height == screenHeight) { refreshRate = modes[i].RefreshRate; } } } VideoCardMemory = adapter.Description.DedicatedVideoMemory / 1024 / 1024; VideoCardDescription = adapter.Description.Description; adapterOutput.Dispose(); adapter.Dispose(); factory.Dispose(); var swapChainDescription = new SwapChainDescription { BufferCount = 1, ModeDescription = { Width = screenWidth, Height = screenHeight, Format = Format.R8G8B8A8_UNorm, RefreshRate = vSyncEnabled ? refreshRate : new Rational(0, 0), ScanlineOrdering = DisplayModeScanlineOrder.Unspecified, Scaling = DisplayModeScaling.Unspecified }, Usage = Usage.RenderTargetOutput, OutputHandle = hwnd, SampleDescription = { Count = 1, Quality = 0 }, IsWindowed = !fullScreen, SwapEffect = SwapEffect.Discard, Flags = SwapChainFlags.None }; var featureLevel = FeatureLevel.Level_11_0; Device device; Device.CreateWithSwapChain( DriverType.Hardware, DeviceCreationFlags.Debug, new[] { featureLevel }, swapChainDescription, out device, out swapChain ); Device = device; DeviceContext = device.ImmediateContext; using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) { renderTargetView = new RenderTargetView(device, backBuffer); } var depthBufferDescription = new Texture2DDescription { Width = screenWidth, Height = screenHeight, MipLevels = 1, ArraySize = 1, Format = Format.D24_UNorm_S8_UInt, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; depthStencilBuffer = new Texture2D(device, depthBufferDescription); var depthStencilStateDescription = new DepthStencilStateDescription { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, FrontFace = { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, BackFace = { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; depthStencilState = new DepthStencilState(device, depthStencilStateDescription); var depthStencilViewDescription = new DepthStencilViewDescription { Format = Format.D24_UNorm_S8_UInt, Dimension = DepthStencilViewDimension.Texture2D, Texture2D = { MipSlice = 0 } }; depthStencilView = new DepthStencilView(device, depthStencilBuffer, depthStencilViewDescription); DeviceContext.OutputMerger.SetRenderTargets(depthStencilView, renderTargetView); var rasterizerStateDescription = new RasterizerStateDescription { IsAntialiasedLineEnabled = false, CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = 0.0f, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsFrontCounterClockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = 0.0f }; rasterizerState = new RasterizerState(device, rasterizerStateDescription); DeviceContext.Rasterizer.State = rasterizerState; var viewport = new Viewport { Width = screenWidth, Height = screenHeight, MinDepth = 0.0f, MaxDepth = 1.0f, X = 0, Y = 0 }; DeviceContext.Rasterizer.SetViewport(viewport); var fieldOfView = MathUtil.Pi / 4.0f; var screenAspect = (float)screenWidth / screenHeight; Projection = Matrix.PerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth); World = Matrix.Identity; Orthogonal = Matrix.OrthoLH(screenWidth, screenHeight, screenNear, screenDepth); } catch { return(false); } return(true); }
private void Update(EvaluationContext context) { var updateLive = UpdateLive.GetValue(context); if (_updatedOnce && !updateLive) { FilteredCubeMap.Value = _prefilteredCubeMap; return; } //ConstantBuffers.GetValues(ref _constantBuffers, context); ShaderResources.GetValues(ref _shaderResourceViews, context); SamplerStates.GetValues(ref _samplerStates, context); var vs = VertexShader.GetValue(context); var gs = GeometryShader.GetValue(context); if (CubeMap.IsConnected && CubeMap.DirtyFlag.IsDirty) { //Log.Debug("Dirty"); } var cubeMapSrc = CubeMap.GetValue(context); // Needs to be checked for null! if (cubeMapSrc == null) { FilteredCubeMap.Value = null; return; } var device = ResourceManager.Instance().Device; var deviceContext = device.ImmediateContext; // Vertex shader stage var vsStage = deviceContext.VertexShader; _prevVsConstantBuffers = vsStage.GetConstantBuffers(0, 1); _prevVsShaderResourceViews = vsStage.GetShaderResources(0, _shaderResourceViews.Length); _prevVertexShader = vsStage.Get(); if (vs == null) { Log.Warning($"{nameof(_SpecularPrefilter)} requires valid vertex shader", SymbolChildId); return; } vsStage.Set(vs); vsStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews); // Geometry shader stage var gsStage = deviceContext.GeometryShader; _prevGsConstantBuffers = gsStage.GetConstantBuffers(0, 1); _prevGsShaderResourceViews = gsStage.GetShaderResources(0, _shaderResourceViews.Length); _prevGeometryShader = gsStage.Get(); if (gs == null) { Log.Warning($"{nameof(_SpecularPrefilter)} requires valid geometry shader", SymbolChildId); return; } gsStage.Set(gs); gsStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews); // Pixel shader stage var psStage = deviceContext.PixelShader; _prevPixelShader = psStage.Get(); _prevPsConstantBuffers = psStage.GetConstantBuffers(0, 1); _prevPsShaderResourceViews = psStage.GetShaderResources(0, _shaderResourceViews.Length); _prevPsSamplerStates = psStage.GetSamplers(0, _samplerStates.Length); var ps = PixelShader.GetValue(context); if (ps == null) { Log.Warning($"{nameof(_SpecularPrefilter)} requires valid pixel shader", SymbolChildId); return; } psStage.Set(ps); psStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews); psStage.SetSamplers(0, _samplerStates); // if (_prefilteredCubeMap != null && !Changed) // { // context.Image = _prefilteredCubeMap; // return context; // } Vector2 cubeMapSize = new Vector2(cubeMapSrc.Description.Width, cubeMapSrc.Description.Height); // Log.Debug($"source size: {cubeMapSrc.Description.Width} num mips in src: {cubeMapSrc.Description.MipLevels}"); // if ( _prefilteredCubeMap == null ) // { var cubeMapDesc = new Texture2DDescription { BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget, Format = cubeMapSrc.Description.Format, Width = (int)cubeMapSize.X, Height = (int)cubeMapSize.Y, MipLevels = cubeMapSrc.Description.MipLevels, SampleDescription = cubeMapSrc.Description.SampleDescription, Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.TextureCube | ResourceOptionFlags.GenerateMipMaps, CpuAccessFlags = CpuAccessFlags.None, ArraySize = 6 }; Utilities.Dispose(ref _prefilteredCubeMap); try { _prefilteredCubeMap = new Texture2D(device, cubeMapDesc); } catch (SharpDXException e) { Log.Debug($"can't create CubeMap target {e.Message}"); return; } var rastDesc = new RasterizerStateDescription { FillMode = FillMode.Solid, CullMode = CullMode.None, IsDepthClipEnabled = false }; _rasterizerState = new RasterizerState(device, rastDesc); // Input Assembler var previousTopology = device.ImmediateContext.InputAssembler.PrimitiveTopology; device.ImmediateContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; _prevBlendState = device.ImmediateContext.OutputMerger.GetBlendState(out _prevBlendFactor, out _prevSampleMask); device.ImmediateContext.OutputMerger.BlendState = DefaultRenderingStates.DisabledBlendState; device.ImmediateContext.OutputMerger.DepthStencilState = DefaultRenderingStates.DisabledDepthStencilState; _prevRenderTargetViews = device.ImmediateContext.OutputMerger.GetRenderTargets(1); device.ImmediateContext.OutputMerger.GetRenderTargets(out _prevDepthStencilView); var rtvDesc = new RenderTargetViewDescription() { Dimension = RenderTargetViewDimension.Texture2DArray, Format = cubeMapSrc.Description.Format, Texture2DArray = new RenderTargetViewDescription.Texture2DArrayResource() { ArraySize = 6, FirstArraySlice = 0, MipSlice = 0 } }; int size = _prefilteredCubeMap.Description.Width; _prevViewports = device.ImmediateContext.Rasterizer.GetViewports <RawViewportF>(); device.ImmediateContext.Rasterizer.State = _rasterizerState; int numMipLevels = _prefilteredCubeMap.Description.MipLevels; int mipSlice = 0; while (mipSlice < numMipLevels) { // Log.Debug($"Update mipmap level {mipSlice} size: {size}"); var viewport = new RawViewportF { X = 0, Y = 0, Width = size, Height = size, MinDepth = 0, MaxDepth = 1 }; device.ImmediateContext.Rasterizer.SetViewports(new[] { viewport }); Utilities.Dispose(ref _cubeMapRtv); rtvDesc.Texture2DArray.MipSlice = mipSlice; _cubeMapRtv = new RenderTargetView(device, _prefilteredCubeMap, rtvDesc); device.ImmediateContext.OutputMerger.SetTargets(_cubeMapRtv, null); var roughness = (float)mipSlice / (_prefilteredCubeMap.Description.MipLevels - 1); // Is this required? if (_settingsBuffer != null) { Utilities.Dispose(ref _settingsBuffer); } for (int i = 0; i < _samplingParameters.Length; ++i) { int indexToUse = -1; if (Math.Abs(roughness - _samplingParameters[i].roughness) < 0.001f) { indexToUse = i; } if (indexToUse == -1 && roughness < _samplingParameters[i].roughness) { indexToUse = i - 1; } if (indexToUse != -1) { var param = _samplingParameters[indexToUse]; param.roughness = roughness; ResourceManager.Instance().SetupConstBuffer(param, ref _settingsBuffer); break; } } var constantBuffers = new[] { _settingsBuffer }; psStage.SetConstantBuffers(0, 1, constantBuffers); vsStage.SetConstantBuffers(0, 1, constantBuffers); gsStage.SetConstantBuffers(0, 1, constantBuffers); device.ImmediateContext.Draw(3, 0); size /= 2; ++mipSlice; } FilteredCubeMap.Value = _prefilteredCubeMap; Utilities.Dispose(ref _cubeMapRtv); //device.ImmediateContext.InputAssembler.PrimitiveTopology = previousTopology; Restore(context); _updatedOnce = true; }
void Initialize() { // shader.fx ShaderFlags shaderFlags = ShaderFlags.None; //ShaderFlags shaderFlags = ShaderFlags.Debug | ShaderFlags.SkipOptimization; ShaderBytecode shaderByteCode = ShaderBytecode.CompileFromFile(Application.StartupPath + "\\shader.fx", "fx_4_0", shaderFlags, EffectFlags.None); effect = new Effect(_device, shaderByteCode); EffectTechnique technique = effect.GetTechniqueByIndex(0); shadowGenPass = technique.GetPassByIndex(0); gBufferGenPass = technique.GetPassByIndex(1); BufferDescription sceneConstantsDesc = new BufferDescription() { SizeInBytes = Marshal.SizeOf(typeof(ShaderSceneConstants)), Usage = ResourceUsage.Dynamic, BindFlags = BindFlags.ConstantBuffer, CpuAccessFlags = CpuAccessFlags.Write, OptionFlags = ResourceOptionFlags.None }; sceneConstantsBuffer = new Buffer(_device, sceneConstantsDesc); EffectConstantBuffer effectConstantBuffer = effect.GetConstantBufferByName("scene"); effectConstantBuffer.SetConstantBuffer(sceneConstantsBuffer); RasterizerStateDescription desc = new RasterizerStateDescription() { CullMode = CullMode.None, FillMode = FillMode.Solid, IsFrontCounterClockwise = true, DepthBias = 0, DepthBiasClamp = 0, SlopeScaledDepthBias = 0, IsDepthClipEnabled = true, }; _device.Rasterizer.State = new RasterizerState(_device, desc); DepthStencilStateDescription depthDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, IsStencilEnabled = false, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less }; depthStencilState = new DepthStencilState(_device, depthDesc); DepthStencilStateDescription lightDepthStateDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, IsStencilEnabled = false, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less }; lightDepthStencilState = new DepthStencilState(_device, lightDepthStateDesc); // grender.fx shaderByteCode = ShaderBytecode.CompileFromFile(Application.StartupPath + "\\grender.fx", "fx_4_0", shaderFlags, EffectFlags.None); effect2 = new Effect(_device, shaderByteCode); technique = effect2.GetTechniqueByIndex(0); gBufferRenderPass = technique.GetPassByIndex(0); Buffer quad = MeshFactory.CreateScreenQuad(_device); quadBinding = new VertexBufferBinding(quad, 20, 0); Matrix quadProjection = Matrix.OrthoLH(1, 1, 0.1f, 1.0f); effect2.GetVariableByName("ViewProjection").AsMatrix().SetMatrix(quadProjection); InputElement[] elements = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0, InputClassification.PerVertexData, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0, InputClassification.PerVertexData, 0), }; quadBufferLayout = new InputLayout(_device, gBufferRenderPass.Description.Signature, elements); Info = new InfoText(_device); meshFactory = new MeshFactory(this); OnInitialize(); CreateBuffers(); SetSceneConstants(); }
private void createRasterizerState() { RasterizerStateDescription rsd = new RasterizerStateDescription() { //CullMode = CullMode.None, CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = 0.0f, //FillMode = FillMode.Wireframe, FillMode = FillMode.Solid, IsAntialiasedLineEnabled = false, IsDepthClipEnabled = false, IsFrontCounterclockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = 0.0f }; rasterState = RasterizerState.FromDescription(D3DDevice, rsd); D3DDevice.ImmediateContext.Rasterizer.State = rasterState; }
private void LoadAssets() { DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = int.MinValue, DescriptorCount = 1 } }; RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges); // Create an empty root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter }); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 12, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { new Vertex() { position = new Vector3(0.0f, 0.25f * aspectRatio, 0.0f), color = new Vector4(1.0f, 0.0f, 0.0f, 1.0f) }, new Vertex() { position = new Vector3(0.25f, -0.25f * aspectRatio, 0.0f), color = new Vector4(0.0f, 1.0f, 0.0f, 1.0f) }, new Vertex() { position = new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f), color = new Vector4(0.0f, 0.0f, 1.0f, 1.0f) }, }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf <Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <ConstantBuffer>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc, constantBufferViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. constantBufferPointer = constantBuffer.Map(0); Utilities.Write(constantBufferPointer, ref constantBufferData); // Create synchronization objects. fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); }
internal static void Modify(RasterizerId id, RasterizerStateDescription desc) { RasterizerStates.Data[id.Index] = desc; RasterizerObjects[id.Index].Dispose(); RasterizerObjects[id.Index] = null; InitRasterizerState(id); }
public VkPipeline(VkGraphicsDevice gd, ref GraphicsPipelineDescription description) : base(ref description) { _gd = gd; IsComputePipeline = false; VkGraphicsPipelineCreateInfo pipelineCI = VkGraphicsPipelineCreateInfo.New(); // Blend State VkPipelineColorBlendStateCreateInfo blendStateCI = VkPipelineColorBlendStateCreateInfo.New(); int attachmentsCount = description.BlendState.AttachmentStates.Length; VkPipelineColorBlendAttachmentState *attachmentsPtr = stackalloc VkPipelineColorBlendAttachmentState[attachmentsCount]; for (int i = 0; i < attachmentsCount; i++) { BlendAttachmentDescription vdDesc = description.BlendState.AttachmentStates[i]; VkPipelineColorBlendAttachmentState attachmentState = new VkPipelineColorBlendAttachmentState(); attachmentState.srcColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceColorFactor); attachmentState.dstColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationColorFactor); attachmentState.colorBlendOp = VkFormats.VdToVkBlendOp(vdDesc.ColorFunction); attachmentState.srcAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceAlphaFactor); attachmentState.dstAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationAlphaFactor); attachmentState.alphaBlendOp = VkFormats.VdToVkBlendOp(vdDesc.AlphaFunction); attachmentState.blendEnable = vdDesc.BlendEnabled; attachmentState.colorWriteMask = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A; attachmentsPtr[i] = attachmentState; } blendStateCI.attachmentCount = (uint)attachmentsCount; blendStateCI.pAttachments = attachmentsPtr; RgbaFloat blendFactor = description.BlendState.BlendFactor; blendStateCI.blendConstants_0 = blendFactor.R; blendStateCI.blendConstants_1 = blendFactor.G; blendStateCI.blendConstants_2 = blendFactor.B; blendStateCI.blendConstants_3 = blendFactor.A; pipelineCI.pColorBlendState = &blendStateCI; // Rasterizer State RasterizerStateDescription rsDesc = description.RasterizerState; VkPipelineRasterizationStateCreateInfo rsCI = VkPipelineRasterizationStateCreateInfo.New(); rsCI.cullMode = VkFormats.VdToVkCullMode(rsDesc.CullMode); rsCI.polygonMode = VkFormats.VdToVkPolygonMode(rsDesc.FillMode); rsCI.depthClampEnable = !rsDesc.DepthClipEnabled; rsCI.frontFace = rsDesc.FrontFace == FrontFace.Clockwise ? VkFrontFace.Clockwise : VkFrontFace.CounterClockwise; rsCI.lineWidth = 1f; pipelineCI.pRasterizationState = &rsCI; ScissorTestEnabled = rsDesc.ScissorTestEnabled; // Dynamic State VkPipelineDynamicStateCreateInfo dynamicStateCI = VkPipelineDynamicStateCreateInfo.New(); VkDynamicState *dynamicStates = stackalloc VkDynamicState[2]; dynamicStates[0] = VkDynamicState.Viewport; dynamicStates[1] = VkDynamicState.Scissor; dynamicStateCI.dynamicStateCount = 2; dynamicStateCI.pDynamicStates = dynamicStates; pipelineCI.pDynamicState = &dynamicStateCI; // Depth Stencil State DepthStencilStateDescription vdDssDesc = description.DepthStencilState; VkPipelineDepthStencilStateCreateInfo dssCI = VkPipelineDepthStencilStateCreateInfo.New(); dssCI.depthWriteEnable = vdDssDesc.DepthWriteEnabled; dssCI.depthTestEnable = vdDssDesc.DepthTestEnabled; dssCI.depthCompareOp = VkFormats.VdToVkCompareOp(vdDssDesc.DepthComparison); dssCI.stencilTestEnable = vdDssDesc.StencilTestEnabled; dssCI.front.failOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Fail); dssCI.front.passOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Pass); dssCI.front.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.DepthFail); dssCI.front.compareMask = vdDssDesc.StencilReadMask; dssCI.front.writeMask = vdDssDesc.StencilWriteMask; dssCI.front.reference = vdDssDesc.StencilReference; dssCI.back.failOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Fail); dssCI.back.passOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Pass); dssCI.back.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.DepthFail); dssCI.back.compareMask = vdDssDesc.StencilReadMask; dssCI.back.writeMask = vdDssDesc.StencilWriteMask; dssCI.back.reference = vdDssDesc.StencilReference; pipelineCI.pDepthStencilState = &dssCI; // Multisample VkPipelineMultisampleStateCreateInfo multisampleCI = VkPipelineMultisampleStateCreateInfo.New(); VkSampleCountFlags vkSampleCount = VkFormats.VdToVkSampleCount(description.Outputs.SampleCount); multisampleCI.rasterizationSamples = vkSampleCount; pipelineCI.pMultisampleState = &multisampleCI; // Input Assembly VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New(); inputAssemblyCI.topology = VkFormats.VdToVkPrimitiveTopology(description.PrimitiveTopology); pipelineCI.pInputAssemblyState = &inputAssemblyCI; // Vertex Input State VkPipelineVertexInputStateCreateInfo vertexInputCI = VkPipelineVertexInputStateCreateInfo.New(); VertexLayoutDescription[] inputDescriptions = description.ShaderSet.VertexLayouts; uint bindingCount = (uint)inputDescriptions.Length; uint attributeCount = 0; for (int i = 0; i < inputDescriptions.Length; i++) { attributeCount += (uint)inputDescriptions[i].Elements.Length; } VkVertexInputBindingDescription * bindingDescs = stackalloc VkVertexInputBindingDescription[(int)bindingCount]; VkVertexInputAttributeDescription *attributeDescs = stackalloc VkVertexInputAttributeDescription[(int)attributeCount]; int targetIndex = 0; int targetLocation = 0; for (int binding = 0; binding < inputDescriptions.Length; binding++) { VertexLayoutDescription inputDesc = inputDescriptions[binding]; bindingDescs[binding] = new VkVertexInputBindingDescription() { binding = (uint)binding, inputRate = (inputDesc.InstanceStepRate != 0) ? VkVertexInputRate.Instance : VkVertexInputRate.Vertex, stride = inputDesc.Stride }; uint currentOffset = 0; for (int location = 0; location < inputDesc.Elements.Length; location++) { VertexElementDescription inputElement = inputDesc.Elements[location]; attributeDescs[targetIndex] = new VkVertexInputAttributeDescription() { format = VkFormats.VdToVkVertexElementFormat(inputElement.Format), binding = (uint)binding, location = (uint)(targetLocation + location), offset = inputElement.Offset != 0 ? inputElement.Offset : currentOffset }; targetIndex += 1; currentOffset += FormatHelpers.GetSizeInBytes(inputElement.Format); } targetLocation += inputDesc.Elements.Length; } vertexInputCI.vertexBindingDescriptionCount = bindingCount; vertexInputCI.pVertexBindingDescriptions = bindingDescs; vertexInputCI.vertexAttributeDescriptionCount = attributeCount; vertexInputCI.pVertexAttributeDescriptions = attributeDescs; pipelineCI.pVertexInputState = &vertexInputCI; // Shader Stage VkSpecializationInfo specializationInfo; SpecializationConstant[] specDescs = description.ShaderSet.Specializations; if (specDescs != null) { uint specDataSize = 0; foreach (SpecializationConstant spec in specDescs) { specDataSize += VkFormats.GetSpecializationConstantSize(spec.Type); } byte *fullSpecData = stackalloc byte[(int)specDataSize]; int specializationCount = specDescs.Length; VkSpecializationMapEntry *mapEntries = stackalloc VkSpecializationMapEntry[specializationCount]; uint specOffset = 0; for (int i = 0; i < specializationCount; i++) { ulong data = specDescs[i].Data; byte *srcData = (byte *)&data; uint dataSize = VkFormats.GetSpecializationConstantSize(specDescs[i].Type); Unsafe.CopyBlock(fullSpecData + specOffset, srcData, dataSize); mapEntries[i].constantID = specDescs[i].ID; mapEntries[i].offset = specOffset; mapEntries[i].size = (UIntPtr)dataSize; specOffset += dataSize; } specializationInfo.dataSize = (UIntPtr)specDataSize; specializationInfo.pData = fullSpecData; specializationInfo.mapEntryCount = (uint)specializationCount; specializationInfo.pMapEntries = mapEntries; } Shader[] shaders = description.ShaderSet.Shaders; StackList <VkPipelineShaderStageCreateInfo> stages = new StackList <VkPipelineShaderStageCreateInfo>(); foreach (Shader shader in shaders) { VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader); VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New(); stageCI.module = vkShader.ShaderModule; stageCI.stage = VkFormats.VdToVkShaderStages(shader.Stage); stageCI.pName = CommonStrings.main; // Meh stageCI.pSpecializationInfo = &specializationInfo; stages.Add(stageCI); } pipelineCI.stageCount = stages.Count; pipelineCI.pStages = (VkPipelineShaderStageCreateInfo *)stages.Data; // ViewportState VkPipelineViewportStateCreateInfo viewportStateCI = VkPipelineViewportStateCreateInfo.New(); viewportStateCI.viewportCount = 1; viewportStateCI.scissorCount = 1; pipelineCI.pViewportState = &viewportStateCI; // Pipeline Layout ResourceLayout[] resourceLayouts = description.ResourceLayouts; VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New(); pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length; VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length]; for (int i = 0; i < resourceLayouts.Length; i++) { dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout; } pipelineLayoutCI.pSetLayouts = dsls; vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout); pipelineCI.layout = _pipelineLayout; // Create fake RenderPass for compatibility. VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New(); OutputDescription outputDesc = description.Outputs; StackList <VkAttachmentDescription, Size512Bytes> attachments = new StackList <VkAttachmentDescription, Size512Bytes>(); // TODO: A huge portion of this next part is duplicated in VkFramebuffer.cs. StackList <VkAttachmentDescription> colorAttachmentDescs = new StackList <VkAttachmentDescription>(); StackList <VkAttachmentReference> colorAttachmentRefs = new StackList <VkAttachmentReference>(); for (uint i = 0; i < outputDesc.ColorAttachments.Length; i++) { colorAttachmentDescs[i].format = VkFormats.VdToVkPixelFormat(outputDesc.ColorAttachments[i].Format); colorAttachmentDescs[i].samples = vkSampleCount; colorAttachmentDescs[i].loadOp = VkAttachmentLoadOp.DontCare; colorAttachmentDescs[i].storeOp = VkAttachmentStoreOp.Store; colorAttachmentDescs[i].stencilLoadOp = VkAttachmentLoadOp.DontCare; colorAttachmentDescs[i].stencilStoreOp = VkAttachmentStoreOp.DontCare; colorAttachmentDescs[i].initialLayout = VkImageLayout.Undefined; colorAttachmentDescs[i].finalLayout = VkImageLayout.ShaderReadOnlyOptimal; attachments.Add(colorAttachmentDescs[i]); colorAttachmentRefs[i].attachment = i; colorAttachmentRefs[i].layout = VkImageLayout.ColorAttachmentOptimal; } VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription(); VkAttachmentReference depthAttachmentRef = new VkAttachmentReference(); if (outputDesc.DepthAttachment != null) { PixelFormat depthFormat = outputDesc.DepthAttachment.Value.Format; bool hasStencil = FormatHelpers.IsStencilFormat(depthFormat); depthAttachmentDesc.format = VkFormats.VdToVkPixelFormat(outputDesc.DepthAttachment.Value.Format, toDepthFormat: true); depthAttachmentDesc.samples = vkSampleCount; depthAttachmentDesc.loadOp = VkAttachmentLoadOp.DontCare; depthAttachmentDesc.storeOp = VkAttachmentStoreOp.Store; depthAttachmentDesc.stencilLoadOp = VkAttachmentLoadOp.DontCare; depthAttachmentDesc.stencilStoreOp = hasStencil ? VkAttachmentStoreOp.Store : VkAttachmentStoreOp.DontCare; depthAttachmentDesc.initialLayout = VkImageLayout.Undefined; depthAttachmentDesc.finalLayout = VkImageLayout.DepthStencilAttachmentOptimal; depthAttachmentRef.attachment = (uint)outputDesc.ColorAttachments.Length; depthAttachmentRef.layout = VkImageLayout.DepthStencilAttachmentOptimal; } VkSubpassDescription subpass = new VkSubpassDescription(); subpass.pipelineBindPoint = VkPipelineBindPoint.Graphics; subpass.colorAttachmentCount = (uint)outputDesc.ColorAttachments.Length; subpass.pColorAttachments = (VkAttachmentReference *)colorAttachmentRefs.Data; for (int i = 0; i < colorAttachmentDescs.Count; i++) { attachments.Add(colorAttachmentDescs[i]); } if (outputDesc.DepthAttachment != null) { subpass.pDepthStencilAttachment = &depthAttachmentRef; attachments.Add(depthAttachmentDesc); } VkSubpassDependency subpassDependency = new VkSubpassDependency(); subpassDependency.srcSubpass = SubpassExternal; subpassDependency.srcStageMask = VkPipelineStageFlags.ColorAttachmentOutput; subpassDependency.dstStageMask = VkPipelineStageFlags.ColorAttachmentOutput; subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite; renderPassCI.attachmentCount = attachments.Count; renderPassCI.pAttachments = (VkAttachmentDescription *)attachments.Data; renderPassCI.subpassCount = 1; renderPassCI.pSubpasses = &subpass; renderPassCI.dependencyCount = 1; renderPassCI.pDependencies = &subpassDependency; VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass); CheckResult(creationResult); pipelineCI.renderPass = _renderPass; VkResult result = vkCreateGraphicsPipelines(_gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline); CheckResult(result); ResourceSetCount = (uint)description.ResourceLayouts.Length; DynamicOffsetsCount = 0; foreach (VkResourceLayout layout in ResourceLayouts) { DynamicOffsetsCount += layout.DynamicBufferCount; } }
private void InitializeGraphics() { // Creating device (we accept dx10 cards or greater) FeatureLevel[] levels = { FeatureLevel.Level_11_0, FeatureLevel.Level_10_1, FeatureLevel.Level_10_0 }; // Defining our swap chain SwapChainDescription desc = new SwapChainDescription(); desc.BufferCount = 1; desc.Usage = Usage.RenderTargetOutput; desc.ModeDescription = new ModeDescription(0, 0, new Rational(0, 0), Format.R8G8B8A8_UNorm); desc.SampleDescription = new SampleDescription(1, 0); desc.OutputHandle = form.Handle; desc.IsWindowed = true; desc.SwapEffect = SwapEffect.Discard; Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, levels, desc, out device11, out swapChain); Format depthFormat = Format.D24_UNorm_S8_UInt; Texture2DDescription depthBufferDesc = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, Format = depthFormat, Height = form.Height, Width = form.Width, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; depthBuffer = new Texture2D(device11, depthBufferDesc); DepthStencilViewDescription dsViewDesc = new DepthStencilViewDescription { Format = depthFormat, Dimension = DepthStencilViewDimension.Texture2D, MipSlice = 0, }; depthView = new DepthStencilView(device11, depthBuffer, dsViewDesc); DepthStencilStateDescription dsStateDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, }; depthState = DepthStencilState.FromDescription(device11, dsStateDesc); // Getting back buffer backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0); // Defining render view renderTargetView = new RenderTargetView(device11, backBuffer); device11.ImmediateContext.OutputMerger.DepthStencilState = depthState; device11.ImmediateContext.OutputMerger.SetTargets(depthView, renderTargetView); // Setup the raster description which will determine how and what polygons will be drawn. RasterizerStateDescription rasterDesc = new RasterizerStateDescription(){ IsAntialiasedLineEnabled = false, CullMode = CullMode.None, DepthBias = 0, DepthBiasClamp = 0.0f, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsFrontCounterclockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = 0.0f, }; // Create the rasterizer state from the description we just filled out. rasterState = RasterizerState.FromDescription(device11, rasterDesc); // Now set the rasterizer state. device11.ImmediateContext.Rasterizer.State = rasterState; device11.ImmediateContext.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f)); }
public override void Run() { #region Create renderers // Note: the renderers take care of creating their own // device resources and listen for DeviceManager.OnInitialize // Create a axis-grid renderer var axisGrid = ToDispose(new AxisGridRenderer()); axisGrid.Initialize(this); // Determine if the hardware driver supports CommandLists // If not, the Direct3D framework will emulate support. bool createResourcesConcurrently; bool nativeCommandListSupport; DeviceManager.Direct3DDevice.CheckThreadingSupport(out createResourcesConcurrently, out nativeCommandListSupport); // Create and initialize the mesh renderer var loadedMesh = Common.Mesh.LoadFromFile("Character.cmo"); List <MeshRenderer> meshes = new List <MeshRenderer>(); int meshRows = 10; int meshColumns = 10; Action createMeshes = () => { // Remove meshes foreach (var mesh in meshes) { mesh.Dispose(); } meshes.Clear(); // Add the same mesh multiple times, separate by the combined extent var minExtent = (from mesh in loadedMesh orderby new { mesh.Extent.Min.X, mesh.Extent.Min.Z } select mesh.Extent).First(); var maxExtent = (from mesh in loadedMesh orderby new { mesh.Extent.Max.X, mesh.Extent.Max.Z } descending select mesh.Extent).First(); var extentDiff = (maxExtent.Max - minExtent.Min); for (int x = -(meshColumns / 2); x < (meshColumns / 2); x++) { for (int z = -(meshRows / 2); z < (meshRows / 2); z++) { var meshGroup = (from mesh in loadedMesh select ToDispose(new MeshRenderer(mesh))).ToList(); // Reposition based on width/depth of combined extent foreach (var m in meshGroup) { m.World.TranslationVector = new Vector3(m.Mesh.Extent.Center.X + extentDiff.X * x, m.Mesh.Extent.Min.Y, m.Mesh.Extent.Center.Z + extentDiff.Z * z); } meshes.AddRange(meshGroup); } } // Initialize each mesh meshes.ForEach(m => m.Initialize(this)); }; createMeshes(); bool animationEnabled = false; bool changeAnimation = false; Action toggleAnimation = () => { // Set the first animation as the current animation and start clock meshes.ForEach(m => { if (!animationEnabled && m.Mesh.Animations.Any()) { m.CurrentAnimation = m.Mesh.Animations.First().Value; m.Clock.Start(); } else { m.CurrentAnimation = null; } }); animationEnabled = !animationEnabled; }; var meshWorld = Matrix.Identity; // Create and initialize a Direct2D FPS text renderer var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16)); fps.Initialize(this); // Create and initialize a general purpose Direct2D text renderer // This will display some instructions and the current view and rotation offsets var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12)); textRenderer.Initialize(this); #endregion // Initialize the world matrix var worldMatrix = Matrix.Identity; // Set the camera position var cameraPosition = new Vector3(0, 1, 10); var cameraTarget = Vector3.Zero; // Looking at the origin 0,0,0 var cameraUp = Vector3.UnitY; // Y+ is Up // Prepare matrices // Create the view matrix from our camera position, look target and up direction var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp); viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0); // Create the projection matrix /* FoV 60degrees = Pi/3 radians */ // Aspect ratio (based on window size), Near clip, Far clip var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.5f, 100f); // Maintain the correct aspect ratio on resize Window.Resize += (s, e) => { projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.5f, 100f); }; #region Rotation and window event handlers // Create a rotation vector to keep track of the rotation // around each of the axes var rotation = new Vector3(0.0f, 0.0f, 0.0f); // We will call this action to update text // for the text renderer Action updateText = () => { textRenderer.Text = String.Format( "\nToggle animation: Backspace, Pause animation: P" + "\nThreads: {0} (+/-)" + " Add CPU load: {1} matrix multiplications (Shift +/-)" + "\nMeshes: {2} (Up/Down, Left/Right)", threadCount, additionalCPULoad, meshRows * meshColumns); }; Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>(); keyToggles[Keys.Z] = false; keyToggles[Keys.F] = false; // Support keyboard/mouse input to rotate or move camera view var moveFactor = 0.02f; // how much to change on each keypress var shiftKey = false; var ctrlKey = false; var background = Color.White; Window.KeyDown += (s, e) => { var context = DeviceManager.Direct3DContext; shiftKey = e.Shift; ctrlKey = e.Control; switch (e.KeyCode) { // WASD -> pans view case Keys.A: viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.D: viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.S: if (shiftKey) { viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2; } break; case Keys.W: if (shiftKey) { viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2; } break; // Up/Down and Left/Right - rotates around X / Y respectively // (Mouse wheel rotates around Z) case Keys.Down: worldMatrix *= Matrix.RotationX(moveFactor); rotation += new Vector3(moveFactor, 0f, 0f); break; case Keys.Up: worldMatrix *= Matrix.RotationX(-moveFactor); rotation -= new Vector3(moveFactor, 0f, 0f); break; case Keys.Left: worldMatrix *= Matrix.RotationY(moveFactor); rotation += new Vector3(0f, moveFactor, 0f); break; case Keys.Right: worldMatrix *= Matrix.RotationY(-moveFactor); rotation -= new Vector3(0f, moveFactor, 0f); break; case Keys.T: fps.Show = !fps.Show; textRenderer.Show = !textRenderer.Show; break; case Keys.B: if (background == Color.White) { background = new Color(30, 30, 34); } else { background = Color.White; } break; case Keys.G: axisGrid.Show = !axisGrid.Show; break; case Keys.P: // Pause or resume mesh animation meshes.ForEach(m => { if (m.Clock.IsRunning) { m.Clock.Stop(); } else { m.Clock.Start(); } }); break; case Keys.X: // To test for correct resource recreation // Simulate device reset or lost. System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); DeviceManager.Initialize(DeviceManager.Dpi); System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); break; case Keys.Z: keyToggles[Keys.Z] = !keyToggles[Keys.Z]; if (keyToggles[Keys.Z]) { context.PixelShader.Set(depthPixelShader); } else { context.PixelShader.Set(pixelShader); } break; case Keys.F: keyToggles[Keys.F] = !keyToggles[Keys.F]; RasterizerStateDescription rasterDesc; if (context.Rasterizer.State != null) { rasterDesc = context.Rasterizer.State.Description; } else { rasterDesc = new RasterizerStateDescription() { CullMode = CullMode.Back, FillMode = FillMode.Solid } }; if (keyToggles[Keys.F]) { rasterDesc.FillMode = FillMode.Wireframe; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } else { rasterDesc.FillMode = FillMode.Solid; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } break; case Keys.D1: context.PixelShader.Set(pixelShader); break; case Keys.D2: context.PixelShader.Set(lambertShader); break; case Keys.D3: context.PixelShader.Set(phongShader); break; case Keys.D4: context.PixelShader.Set(blinnPhongShader); break; } updateText(); }; Window.KeyUp += (s, e) => { // Clear the shift/ctrl keys so they aren't sticky if (e.KeyCode == Keys.ShiftKey) { shiftKey = false; } if (e.KeyCode == Keys.ControlKey) { ctrlKey = false; } }; Window.MouseWheel += (s, e) => { if (shiftKey) { // Zoom in/out viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2); } else { // rotate around Z-axis viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor); rotation += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor); } updateText(); }; var lastX = 0; var lastY = 0; Window.MouseDown += (s, e) => { if (e.Button == MouseButtons.Left) { lastX = e.X; lastY = e.Y; } }; Window.MouseMove += (s, e) => { if (e.Button == MouseButtons.Left) { var yRotate = lastX - e.X; var xRotate = lastY - e.Y; lastY = e.Y; lastX = e.X; // Mouse move changes viewMatrix *= Matrix.RotationX(-xRotate * moveFactor); viewMatrix *= Matrix.RotationY(-yRotate * moveFactor); updateText(); } }; // Display instructions with initial values updateText(); #endregion var clock = new System.Diagnostics.Stopwatch(); clock.Start(); SetupContextList(); bool initializeMesh = false; Window.KeyDown += (s, e) => { switch (e.KeyCode) { case Keys.Back: changeAnimation = true; break; case Keys.Up: meshRows += 2; initializeMesh = true; break; case Keys.Down: meshRows = Math.Max(2, meshRows - 2); initializeMesh = true; break; case Keys.Right: meshColumns += 2; initializeMesh = true; break; case Keys.Left: meshColumns = Math.Max(2, meshColumns - 2); initializeMesh = true; break; case Keys.Add: if (shiftKey) { additionalCPULoad += 100; } else { threadCount++; } break; case Keys.Subtract: if (shiftKey) { additionalCPULoad = Math.Max(0, additionalCPULoad - 100); } else { threadCount = Math.Max(1, threadCount - 1); } break; default: break; } updateText(); }; // Action for rendering a mesh using the context // from the specified index wtihin contextList Action <int> renderMeshGroup = (int contextIndex) => { // Retrieve appropriate context var renderContext = contextList[contextIndex]; // Create viewProjection matrix var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix); // Determine the meshes to render for this context int batchSize = (int)Math.Floor((double)meshes.Count / contextList.Length); int startIndex = batchSize * contextIndex; int endIndex = Math.Min(startIndex + batchSize, meshes.Count - 1); // If this is the last context include whatever remains to be // rendered due to the rounding above. if (contextIndex == contextList.Length - 1) { endIndex = meshes.Count - 1; } // Loop over the meshes for this context and render them var perObject = new ConstantBuffers.PerObject(); for (var i = startIndex; i <= endIndex; i++) { // Simulate additional CPU load for (var j = 0; j < additionalCPULoad; j++) { viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix); } var m = meshes[i]; // Update perObject constant buffer perObject.World = m.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.Transpose(); renderContext.UpdateSubresource(ref perObject, perObjectBuffer); // Provide the material and armature constant buffer to the mesh renderer m.PerArmatureBuffer = perArmatureBuffer; m.PerMaterialBuffer = perMaterialBuffer; // Specify the context to render with m.Render(renderContext); } }; #region Render loop var lastThreadCount = threadCount; // Create and run the render loop RenderLoop.Run(Window, () => { if (initializeMesh) { initializeMesh = false; createMeshes(); } if (changeAnimation) { toggleAnimation(); changeAnimation = false; } if (lastThreadCount != threadCount) { SetupContextList(); lastThreadCount = threadCount; } // Start of frame: // Retrieve immediate context var immediateContext = DeviceManager.Direct3DDevice.ImmediateContext; // The context at index 0 is always executed first var context = contextList[0]; // Clear depth stencil view context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); // Clear render target view context.ClearRenderTargetView(RenderTargetView, background); // Create viewProjection matrix var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix); // Extract camera position from view var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4; cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z); // If Keys.CtrlKey is down, auto rotate viewProjection based on time var time = clock.ElapsedMilliseconds / 1000.0f; if (ctrlKey) { viewProjection = Matrix.RotationY(time * 1.8f) * Matrix.RotationX(time * 1f) * Matrix.RotationZ(time * 0.6f) * viewProjection; } var worldRotation = Matrix.RotationAxis(Vector3.UnitY, time); var perFrame = new ConstantBuffers.PerFrame(); perFrame.Light.Color = new Color(0.8f, 0.8f, 0.8f, 1.0f); var lightDir = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix); perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z);// new Vector3(Vector3.Transform(new Vector3(1f, -1f, 1f), worldMatrix * worldRotation).ToArray().Take(3).ToArray()); perFrame.CameraPosition = cameraPosition; context.UpdateSubresource(ref perFrame, perFrameBuffer); // Render each object var perMaterial = new ConstantBuffers.PerMaterial(); perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); var perObject = new ConstantBuffers.PerObject(); // AXIS GRID using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); perObject.World = worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); axisGrid.RenderContext = context; axisGrid.Render(); context.PixelShader.Set(prevPixelShader); } Task[] renderTasks = new Task[contextList.Length]; CommandList[] commands = new CommandList[contextList.Length]; for (var i = 0; i < contextList.Length; i++) { // var contextIndex = i; renderTasks[i] = Task.Run(() => { // Render logic renderMeshGroup(contextIndex); // Create the command list if (contextList[contextIndex].TypeInfo == DeviceContextType.Deferred) { commands[contextIndex] = contextList[contextIndex].FinishCommandList(true); } }); } // Wait for all the tasks to complete Task.WaitAll(renderTasks); // Replay the command lists on the immediate context for (var i = 0; i < contextList.Length; i++) { if (contextList[i].TypeInfo == DeviceContextType.Deferred && commands[i] != null) { immediateContext.ExecuteCommandList(commands[i], false); commands[i].Dispose(); commands[i] = null; } } // Render FPS fps.Render(); // Render instructions + position changes textRenderer.Render(); // Present the frame Present(); }); #endregion }
void InitD3D() { var swapDesc = new Dxgi.SwapChainDescription { BufferCount = 1, ModeDescription = new Dxgi.ModeDescription { Width = Container.ClientSize.Width, Height = Container.ClientSize.Height, RefreshRate = new Rational(60, 1), Format = Dxgi.Format.R8G8B8A8_UNorm }, IsWindowed = true, OutputHandle = Container.Handle, SampleDescription = new Dxgi.SampleDescription(1, 0), SwapEffect = Dxgi.SwapEffect.Discard, Usage = Dxgi.Usage.RenderTargetOutput }; Device device; Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug | DeviceCreationFlags.BgraSupport, swapDesc, out device, out SwapChain); Device = device; m_context = Device.ImmediateContext; Texture2DDescription colordesc = new Texture2DDescription { BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, Format = Dxgi.Format.B8G8R8A8_UNorm, Width = Width, Height = Height, MipLevels = 1, SampleDescription = new Dxgi.SampleDescription(1, 0), Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.Shared, CpuAccessFlags = CpuAccessFlags.None, ArraySize = 1 }; Texture2DDescription depthdesc = new Texture2DDescription { BindFlags = BindFlags.DepthStencil, Format = Dxgi.Format.D24_UNorm_S8_UInt, Width = Width, Height = Height, MipLevels = 1, SampleDescription = new Dxgi.SampleDescription(1, 0), Usage = ResourceUsage.Default, OptionFlags = ResourceOptionFlags.None, CpuAccessFlags = CpuAccessFlags.None, ArraySize = 1 }; SharedTexture = new Texture2D(Device, colordesc); DepthTexture = new Texture2D(Device, depthdesc); RenderView = new RenderTargetView(Device, SharedTexture); DepthView = new DepthStencilView(Device, DepthTexture); var rastDesc = new RasterizerStateDescription() { CullMode = CullMode.None, FillMode = FillMode.Solid, }; m_context.Rasterizer.State = RasterizerState.FromDescription(Device, rastDesc); QuadIndices = RenderSupport.InitQuadIndices(Device); m_context.Flush(); }
private static void UpdateSceneFrame() { var desc = new RasterizerStateDescription(); desc.FillMode = FillMode.Solid; desc.CullMode = CullMode.None; desc.IsFrontCounterClockwise = true; desc.DepthBias = 25000; desc.DepthBiasClamp = 2; desc.SlopeScaledDepthBias = 1; MyPipelineStates.Modify(m_shadowRasterizerState, desc); MyMeshes.Load(); QueryTexturesFromEntities(); MyTextures.Load(); GatherTextures(); MyComponents.UpdateCullProxies(); MyComponents.ProcessEntities(); MyComponents.SendVisible(); MyBillboardRenderer.OnFrameStart(); MyRender11.GetRenderProfiler().StartProfilingBlock("RebuildProxies"); foreach (var renderable in MyComponentFactory <MyRenderableComponent> .GetAll()) { renderable.RebuildRenderProxies(); } MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("UpdateProxies"); UpdateActors(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyBigMeshTable.Table.MoveToGPU(); MyRender11.GetRenderProfiler().StartProfilingBlock("Update merged groups"); MyRender11.GetRenderProfiler().StartProfilingBlock("UpdateBeforeDraw"); foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll()) { r.UpdateBeforeDraw(); } MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("MoveToGPU"); foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll()) { foreach (var val in r.m_materialGroups.Values) { // optimize: keep list+set for updating val.MoveToGPU(); } } MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("Fill foliage streams"); MyGpuProfiler.IC_BeginBlock("Fill foliage streams"); MyGPUFoliageGenerating.GetInstance().PerFrame(); MyGPUFoliageGenerating.GetInstance().Begin(); foreach (var foliage in MyComponentFactory <MyFoliageComponent> .GetAll()) { if (foliage.m_owner.CalculateCameraDistance() < MyRender11.RenderSettings.FoliageDetails.GrassDrawDistance()) { foliage.FillStreams(); } else { foliage.InvalidateStreams(); } } MyGPUFoliageGenerating.GetInstance().End(); MyGpuProfiler.IC_EndBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyCommon.MoveToNextFrame(); }
Pipeline BuildPipeline(GraphicsDevice gd, SceneContext sc, SpriteShaderKey key) { var shaderCache = Resolve <IShaderCache>(); var shaderName = key.UseCylindricalShader ? "CylindricalSprite" : "Sprite"; var vertexShaderName = shaderName + "SV.vert"; var fragmentShaderName = shaderName + "SF.frag"; var vertexShaderContent = shaderCache.GetGlsl(vertexShaderName); var fragmentShaderContent = shaderCache.GetGlsl(fragmentShaderName); if (key.UseArrayTexture) { fragmentShaderName += ".array"; fragmentShaderContent = @"#define USE_ARRAY_TEXTURE " + fragmentShaderContent; } if (key.UsePalette) { fragmentShaderName += ".pal"; fragmentShaderContent = @"#define USE_PALETTE " + fragmentShaderContent; } var shaders = shaderCache.GetShaderPair( gd.ResourceFactory, vertexShaderName, fragmentShaderName, vertexShaderContent, fragmentShaderContent); _shaders.AddRange(shaders); var depthStencilMode = key.PerformDepthTest ? gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyLessEqual : DepthStencilStateDescription.DepthOnlyGreaterEqual : DepthStencilStateDescription.Disabled; var rasterizerMode = new RasterizerStateDescription( FaceCullMode.None, PolygonFillMode.Solid, FrontFace.Clockwise, key.PerformDepthTest, // depth test true); // scissor test var pipelineDescription = new GraphicsPipelineDescription( BlendStateDescription.SingleAlphaBlend, depthStencilMode, rasterizerMode, PrimitiveTopology.TriangleList, new ShaderSetDescription(new[] { VertexLayout, InstanceLayout }, shaders, ShaderHelper.GetSpecializations(gd)), new[] { _perSpriteResourceLayout, sc.CommonResourceLayout }, gd.SwapchainFramebuffer.OutputDescription); var pipeline = gd.ResourceFactory.CreateGraphicsPipeline(ref pipelineDescription); pipeline.Name = $"P_Sprite_{key}"; return(pipeline); }
public bool Initialize(DSystemConfiguration configuration, IntPtr windowHandle) { try { #region Environment Configuration VerticalSyncEnabled = DSystemConfiguration.VerticalSyncEnabled; var factory = new Factory1(); var adapter = factory.GetAdapter1(0); var monitor = adapter.GetOutput(0); var modes = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced); var rational = new Rational(0, 1); if (VerticalSyncEnabled) { foreach (var mode in modes) { if (mode.Width == configuration.Width && mode.Height == configuration.Height) { rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator); break; } } } var adapterDescription = adapter.Description; VideoCardMemory = adapterDescription.DedicatedVideoMemory >> 10 >> 10; VideoCardDescription = string.Format("VideoCard: {0}", adapterDescription.Description.Trim('\0')); monitor.Dispose(); adapter.Dispose(); factory.Dispose(); #endregion #region Initialize swap chain and d3d device var swapChainDesc = new SwapChainDescription() { BufferCount = 1, ModeDescription = new ModeDescription(configuration.Width, configuration.Height, rational, Format.R8G8B8A8_UNorm) { Scaling = DisplayModeScaling.Unspecified, ScanlineOrdering = DisplayModeScanlineOrder.Unspecified }, Usage = Usage.RenderTargetOutput, OutputHandle = windowHandle, SampleDescription = new SampleDescription(1, 0), IsWindowed = !DSystemConfiguration.FullScreen, Flags = SwapChainFlags.None, SwapEffect = SwapEffect.Discard }; SharpDX.Direct3D11.Device device; SwapChain swapChain; SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain); Device = device; SwapChain = swapChain; DeviceContext = device.ImmediateContext; #endregion #region Initialize buffers var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0); RenderTargetView = new RenderTargetView(device, backBuffer); backBuffer.Dispose(); var depthBufferDesc = new Texture2DDescription() { Width = configuration.Width, Height = configuration.Height, MipLevels = 1, ArraySize = 1, Format = Format.D24_UNorm_S8_UInt, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; DepthStencilBuffer = new Texture2D(device, depthBufferDesc); #endregion #region Initialize Depth Enabled Stencil var depthStencilDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; DepthStencilState = new DepthStencilState(Device, depthStencilDesc); #endregion #region Initialize Output Merger DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1); var depthStencilViewDesc = new DepthStencilViewDescription() { Format = Format.D24_UNorm_S8_UInt, Dimension = DepthStencilViewDimension.Texture2D, Texture2D = new DepthStencilViewDescription.Texture2DResource() { MipSlice = 0 } }; DepthStencilView = new DepthStencilView(Device, DepthStencilBuffer, depthStencilViewDesc); DeviceContext.OutputMerger.SetTargets(DepthStencilView, RenderTargetView); #endregion #region Initialize Raster State var rasterDesc = new RasterizerStateDescription() { IsAntialiasedLineEnabled = false, CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = .0f, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsFrontCounterClockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = .0f }; RasterState = new RasterizerState(Device, rasterDesc); #endregion #region Initialize Rasterizer DeviceContext.Rasterizer.State = RasterState; ViewPort = new ViewportF(0.0f, 0.0f, (float)configuration.Width, (float)configuration.Height, 0.0f, 1.0f); DeviceContext.Rasterizer.SetViewport(ViewPort); #endregion #region Initialize matrices ProjectionMatrix = Matrix.PerspectiveFovLH((float)(Math.PI / 4), ((float)configuration.Width / (float)configuration.Height), DSystemConfiguration.ScreenNear, DSystemConfiguration.ScreenDepth); WorldMatrix = Matrix.Identity; OrthoMatrix = Matrix.OrthoLH(configuration.Width, configuration.Height, DSystemConfiguration.ScreenNear, DSystemConfiguration.ScreenDepth); #endregion #region Initialize Depth Disabled Stencil var depthDisabledStencilDesc = new DepthStencilStateDescription() { IsDepthEnabled = false, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; DepthDisabledStencilState = new DepthStencilState(Device, depthDisabledStencilDesc); #endregion #region Initialize Blend States var blendStateDesc = new BlendStateDescription(); blendStateDesc.RenderTarget[0].IsBlendEnabled = true; blendStateDesc.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDesc.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDesc.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDesc.RenderTarget[0].SourceAlphaBlend = BlendOption.One; blendStateDesc.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero; blendStateDesc.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; blendStateDesc.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; AlphaEnableBlendingState = new BlendState(device, blendStateDesc); blendStateDesc.RenderTarget[0].IsBlendEnabled = false; AlphaDisableBlendingState = new BlendState(device, blendStateDesc); #endregion return(true); } catch (Exception) { return(false); } }
/// <summary> /// Creates a new instance of the SpriteRenderer /// </summary> /// <param name="device">The device to use</param> /// <param name="maxSpriteInstances">The maximum sprite instances that can be cached before a flush happens</param> public SpriteRenderer(Device device, int maxSpriteInstances = 10000) { /* Initialize our arrays to hold our sprite data */ m_spriteRenderData = new SpriteRenderData[maxSpriteInstances]; m_spriteDrawData = new SpriteDrawData[maxSpriteInstances]; /* Initialize all the items in the array */ for (int i = 0; i < maxSpriteInstances; i++) { m_spriteRenderData[i] = new SpriteRenderData(); } m_maxSpriteInstances = maxSpriteInstances; m_device = device; /* Create our default blend states using our helper */ m_blendStates = SpriteRendererBlendStateHelper.InitializeDefaultBlendStates(m_device); /* Create our vertex shader */ m_vertexShaderInstanced10 = new VertexShader10(device, SHADER_RESOURCE_NAME, Assembly.GetExecutingAssembly(), "SpriteInstancedVS", ShaderVersion.Vs_4_0); /* Create our pixel shader */ m_pixelShader10 = new PixelShader10(device, SHADER_RESOURCE_NAME, Assembly.GetExecutingAssembly(), "SpritePS", ShaderVersion.Ps_4_0,ShaderFlags.Debug); /* Create a new sprite quad that holds our GPU buffers */ m_spriteQuad = new SpriteQuad(device, maxSpriteInstances); m_spriteQuadShaderBinding = new GeometryInputShaderBinding(m_spriteQuad, m_vertexShaderInstanced10, m_pixelShader10); var rastDesc = new RasterizerStateDescription(); rastDesc.IsAntialiasedLineEnabled = false; rastDesc.CullMode = CullMode.None; rastDesc.DepthBias = 0; rastDesc.DepthBiasClamp = 1.0f; rastDesc.IsDepthClipEnabled = false; rastDesc.FillMode = FillMode.Solid; rastDesc.IsFrontCounterclockwise = false; rastDesc.IsMultisampleEnabled = false; rastDesc.IsScissorEnabled = false; rastDesc.SlopeScaledDepthBias = 0; m_rasterizerState = RasterizerState.FromDescription(m_device, rastDesc); var dsDesc = new DepthStencilStateDescription(); dsDesc.IsDepthEnabled = false; dsDesc.DepthWriteMask = DepthWriteMask.All; dsDesc.DepthComparison = Comparison.Less; dsDesc.IsStencilEnabled = false; dsDesc.StencilReadMask = 0xff; dsDesc.StencilWriteMask = 0xff; dsDesc.FrontFace = new DepthStencilOperationDescription{ DepthFailOperation = StencilOperation.Keep, FailOperation = StencilOperation.Replace, Comparison = Comparison.Always }; dsDesc.BackFace = dsDesc.FrontFace; m_dsState = DepthStencilState.FromDescription(m_device, dsDesc); var sampDesc = new SamplerDescription(); sampDesc.AddressU = TextureAddressMode.Wrap; sampDesc.AddressV = TextureAddressMode.Wrap; sampDesc.AddressW = TextureAddressMode.Wrap; sampDesc.BorderColor = new Color4(0, 0, 0, 0).InternalColor4; sampDesc.ComparisonFunction = Comparison.Never; sampDesc.Filter = Filter.MinMagMipLinear; sampDesc.MaximumAnisotropy = 1; sampDesc.MaximumLod = float.MaxValue; sampDesc.MinimumLod = 0; sampDesc.MipLodBias = 0; m_linearSamplerState = SamplerState.FromDescription(m_device, sampDesc); sampDesc.Filter = Filter.MinMagMipPoint; m_pointSamplerState = SamplerState.FromDescription(m_device, sampDesc); }
public override void Run() { #region Create renderers // Note: the renderers take care of creating their own // device resources and listen for DeviceManager.OnInitialize // Create and initialize the quad renderer var quad = ToDispose(new QuadRenderer(Color.LightGray)); quad.Initialize(this); // Scale and translate the quad quad.World = Matrix.Scaling(5f); quad.World.TranslationVector = new Vector3(0, 0, 0); // Create and initialize the mesh renderer var loadedMesh = Common.Mesh.LoadFromFile("Male_base_mesh.cmo"); var mesh = ToDispose(new MeshRenderer(loadedMesh.First())); mesh.Initialize(this); mesh.World = Matrix.Identity; // Create and initialize a Direct2D FPS text renderer var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16)); fps.Initialize(this); // Create and initialize a general purpose Direct2D text renderer // This will display some instructions and the current view and rotation offsets var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12)); textRenderer.Initialize(this); #endregion // Initialize the world matrix var worldMatrix = Matrix.Identity; // Set the camera position slightly to the right (x), above (y) and in front (+z) var cameraPosition = new Vector3(1, 1, 3); var cameraTarget = Vector3.Zero; // Looking at the origin 0,0,0 var cameraUp = Vector3.UnitY; // Y+ is Up // RIGHT-HANDED COORDINATE SYSTEM // Prepare matrices // Create the view matrix from our camera position, look target and up direction var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp); // Create the projection matrix /* FoV 60degrees = Pi/3 radians */ // Aspect ratio (based on window size), Near clip, Far clip var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.5f, 100f); // Maintain the correct aspect ratio on resize Window.Resize += (s, e) => { projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.5f, 100f); }; #region Rotation and window event handlers // Create a rotation vector to keep track of the rotation // around each of the axes var rotation = new Vector3(0.0f, 0.0f, 0.0f); // We will call this action to update text // for the text renderer Action updateText = () => { textRenderer.Text = String.Format("Rotation ({0}) (Up/Down Left/Right Wheel+-)\nView ({1}) (A/D, W/S, Shift+Wheel+-)" + "\nPress X to reinitialize the device and resources (device ptr: {2})" + "\nPress Z to show/hide depth buffer - Press F to toggle wireframe" + "\nPress 1,2,3,4 to switch shaders", rotation, viewMatrix.TranslationVector, DeviceManager.Direct3DDevice.NativePointer); }; Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>(); keyToggles[Keys.Z] = false; keyToggles[Keys.F] = false; // Support keyboard/mouse input to rotate or move camera view var moveFactor = 0.02f; // how much to change on each keypress var shiftKey = false; var ctrlKey = false; Window.KeyDown += (s, e) => { var context = DeviceManager.Direct3DContext; shiftKey = e.Shift; ctrlKey = e.Control; switch (e.KeyCode) { // WASD -> pans view case Keys.A: viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.D: viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.S: if (shiftKey) { viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2; } break; case Keys.W: if (shiftKey) { viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2; } break; // Up/Down and Left/Right - rotates around X / Y respectively // (Mouse wheel rotates around Z) case Keys.Down: worldMatrix *= Matrix.RotationX(moveFactor); rotation += new Vector3(moveFactor, 0f, 0f); break; case Keys.Up: worldMatrix *= Matrix.RotationX(-moveFactor); rotation -= new Vector3(moveFactor, 0f, 0f); break; case Keys.Left: worldMatrix *= Matrix.RotationY(moveFactor); rotation += new Vector3(0f, moveFactor, 0f); break; case Keys.Right: worldMatrix *= Matrix.RotationY(-moveFactor); rotation -= new Vector3(0f, moveFactor, 0f); break; case Keys.T: fps.Show = !fps.Show; textRenderer.Show = !textRenderer.Show; break; case Keys.X: // To test for correct resource recreation // Simulate device reset or lost. System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); DeviceManager.Initialize(DeviceManager.Dpi); System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); break; case Keys.Z: keyToggles[Keys.Z] = !keyToggles[Keys.Z]; if (keyToggles[Keys.Z]) { context.PixelShader.Set(depthPixelShader); } else { context.PixelShader.Set(pixelShader); } break; case Keys.F: keyToggles[Keys.F] = !keyToggles[Keys.F]; RasterizerStateDescription rasterDesc; if (context.Rasterizer.State != null) { rasterDesc = context.Rasterizer.State.Description; } else { rasterDesc = new RasterizerStateDescription() { CullMode = CullMode.Back, FillMode = FillMode.Solid } }; if (keyToggles[Keys.F]) { rasterDesc.FillMode = FillMode.Wireframe; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } else { rasterDesc.FillMode = FillMode.Solid; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } break; case Keys.D1: context.PixelShader.Set(pixelShader); break; case Keys.D2: context.PixelShader.Set(lambertShader); break; case Keys.D3: context.PixelShader.Set(phongShader); break; case Keys.D4: context.PixelShader.Set(blinnPhongShader); break; } updateText(); }; Window.KeyUp += (s, e) => { // Clear the shift/ctrl keys so they aren't sticky if (e.KeyCode == Keys.ShiftKey) { shiftKey = false; } if (e.KeyCode == Keys.ControlKey) { ctrlKey = false; } }; Window.MouseWheel += (s, e) => { if (shiftKey) { // Zoom in/out viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2); } else { // rotate around Z-axis viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor); rotation += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor); } updateText(); }; var lastX = 0; var lastY = 0; Window.MouseDown += (s, e) => { if (e.Button == MouseButtons.Left) { lastX = e.X; lastY = e.Y; } }; Window.MouseMove += (s, e) => { if (e.Button == MouseButtons.Left) { var yRotate = lastX - e.X; var xRotate = lastY - e.Y; lastY = e.Y; lastX = e.X; // Mouse move changes viewMatrix *= Matrix.RotationX(-xRotate * moveFactor); viewMatrix *= Matrix.RotationY(-yRotate * moveFactor); updateText(); } }; // Display instructions with initial values updateText(); #endregion var clock = new System.Diagnostics.Stopwatch(); clock.Start(); #region Render loop // Create and run the render loop RenderLoop.Run(Window, () => { // Start of frame: // Retrieve immediate context var context = DeviceManager.Direct3DContext; // Clear depth stencil view context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); // Clear render target view context.ClearRenderTargetView(RenderTargetView, new Color(30, 30, 34)); // Create viewProjection matrix var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix); // Extract camera position from view var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4; cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z); // If Keys.CtrlKey is down, auto rotate viewProjection based on time var time = clock.ElapsedMilliseconds / 1000.0f; if (ctrlKey) { viewProjection = Matrix.RotationY(time * 1.8f) * Matrix.RotationX(time * 1f) * Matrix.RotationZ(time * 0.6f) * viewProjection; } var worldRotation = Matrix.RotationAxis(Vector3.UnitY, time); var perFrame = new ConstantBuffers.PerFrame(); perFrame.Light.Color = Color.White; var lightDir = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix); perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z); perFrame.CameraPosition = cameraPosition; context.UpdateSubresource(ref perFrame, perFrameBuffer); // Render each object var perMaterial = new ConstantBuffers.PerMaterial(); perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); var perObject = new ConstantBuffers.PerObject(); // QUAD perObject.World = quad.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); quad.Render(); // MESH perObject.World = mesh.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); // Provide the material constant buffer to the mesh renderer mesh.PerMaterialBuffer = perMaterialBuffer; mesh.Render(); // Render FPS fps.Render(); // Render instructions + position changes textRenderer.Render(); // Present the frame Present(); }); #endregion }
public static void InitAll(Device device) { Debug.Assert(device != null); var wfDesc = new RasterizerStateDescription { FillMode = FillMode.Wireframe, CullMode = CullMode.Back, IsFrontCounterclockwise = false, IsDepthClipEnabled = true }; WireframeRS = RasterizerState.FromDescription(device, wfDesc); var noCullDesc = new RasterizerStateDescription { FillMode = FillMode.Solid, CullMode = CullMode.None, IsFrontCounterclockwise = false, IsDepthClipEnabled = true }; NoCullRS = RasterizerState.FromDescription(device, noCullDesc); var cullClockwiseDesc = new RasterizerStateDescription { FillMode = FillMode.Solid, CullMode = CullMode.Back, IsFrontCounterclockwise = true, IsDepthClipEnabled = true }; CullClockwiseRS = RasterizerState.FromDescription(device, cullClockwiseDesc); var atcDesc = new BlendStateDescription { AlphaToCoverageEnable = true, IndependentBlendEnable = false, }; atcDesc.RenderTargets[0].BlendEnable = false; atcDesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; AlphaToCoverageBS = BlendState.FromDescription(device, atcDesc); var transDesc = new BlendStateDescription { AlphaToCoverageEnable = false, IndependentBlendEnable = false }; transDesc.RenderTargets[0].BlendEnable = true; transDesc.RenderTargets[0].SourceBlend = BlendOption.SourceAlpha; transDesc.RenderTargets[0].DestinationBlend = BlendOption.InverseSourceAlpha; transDesc.RenderTargets[0].BlendOperation = BlendOperation.Add; transDesc.RenderTargets[0].SourceBlendAlpha = BlendOption.One; transDesc.RenderTargets[0].DestinationBlendAlpha = BlendOption.Zero; transDesc.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add; transDesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; TransparentBS = BlendState.FromDescription(device, transDesc); var noRenderTargetWritesDesc = new BlendStateDescription { AlphaToCoverageEnable = false, IndependentBlendEnable = false }; noRenderTargetWritesDesc.RenderTargets[0].BlendEnable = false; noRenderTargetWritesDesc.RenderTargets[0].SourceBlend = BlendOption.One; noRenderTargetWritesDesc.RenderTargets[0].DestinationBlend = BlendOption.Zero; noRenderTargetWritesDesc.RenderTargets[0].BlendOperation = BlendOperation.Add; noRenderTargetWritesDesc.RenderTargets[0].SourceBlendAlpha = BlendOption.One; noRenderTargetWritesDesc.RenderTargets[0].DestinationBlendAlpha = BlendOption.Zero; noRenderTargetWritesDesc.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add; noRenderTargetWritesDesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.None; NoRenderTargetWritesBS = BlendState.FromDescription(device, noRenderTargetWritesDesc); var mirrorDesc = new DepthStencilStateDescription { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.Zero, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xff, StencilWriteMask = 0xff, FrontFace = new DepthStencilOperationDescription { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Replace, Comparison = Comparison.Always }, BackFace = new DepthStencilOperationDescription { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Replace, Comparison = Comparison.Always } }; MarkMirrorDSS = DepthStencilState.FromDescription(device, mirrorDesc); var drawReflectionDesc = new DepthStencilStateDescription { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xff, StencilWriteMask = 0xff, FrontFace = new DepthStencilOperationDescription { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Keep, Comparison = Comparison.Equal }, BackFace = new DepthStencilOperationDescription { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Keep, Comparison = Comparison.Equal } }; DrawReflectionDSS = DepthStencilState.FromDescription(device, drawReflectionDesc); var noDoubleBlendDesc = new DepthStencilStateDescription { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xff, StencilWriteMask = 0xff, FrontFace = new DepthStencilOperationDescription { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Increment, Comparison = Comparison.Equal }, BackFace = new DepthStencilOperationDescription { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Increment, Comparison = Comparison.Equal } }; NoDoubleBlendDSS = DepthStencilState.FromDescription(device, noDoubleBlendDesc); var lessEqualDesc = new DepthStencilStateDescription { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.LessEqual, IsStencilEnabled = false }; LessEqualDSS = DepthStencilState.FromDescription(device, lessEqualDesc); var equalsDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.Zero, DepthComparison = Comparison.LessEqual, }; EqualsDSS = DepthStencilState.FromDescription(device, equalsDesc); var noDepthDesc = new DepthStencilStateDescription() { IsDepthEnabled = false, DepthComparison = Comparison.Always, DepthWriteMask = DepthWriteMask.Zero }; NoDepthDSS = DepthStencilState.FromDescription(device, noDepthDesc); }
public override void Initialize() { Form.SizeChanged += (o, args) => { if (_swapChain == null) { return; } renderView.Dispose(); depthView.Dispose(); DisposeBuffers(); if (Form.WindowState == FormWindowState.Minimized) { return; } _width = Form.ClientSize.Width; _height = Form.ClientSize.Height; _swapChain.ResizeBuffers(_swapChain.Description.BufferCount, 0, 0, Format.Unknown, 0); CreateBuffers(); SetSceneConstants(); }; _width = 1024; _height = 768; _nearPlane = 1.0f; ambient = new Color4(Color.Gray.ToArgb()); try { OnInitializeDevice(); } catch (Exception e) { MessageBox.Show(e.ToString(), "Could not create DirectX 10 device."); return; } // shader.fx const ShaderFlags shaderFlags = ShaderFlags.None; //const ShaderFlags shaderFlags = ShaderFlags.Debug | ShaderFlags.SkipOptimization; ShaderBytecode shaderByteCode = LoadShader("shader.fx", shaderFlags); effect = new Effect(_device, shaderByteCode); EffectTechnique technique = effect.GetTechniqueByIndex(0); shadowGenPass = technique.GetPassByIndex(0); gBufferGenPass = technique.GetPassByIndex(1); debugDrawPass = technique.GetPassByName("debug"); BufferDescription sceneConstantsDesc = new BufferDescription() { SizeInBytes = Marshal.SizeOf(typeof(ShaderSceneConstants)), Usage = ResourceUsage.Dynamic, BindFlags = BindFlags.ConstantBuffer, CpuAccessFlags = CpuAccessFlags.Write, OptionFlags = ResourceOptionFlags.None }; sceneConstantsBuffer = new Buffer(_device, sceneConstantsDesc); EffectConstantBuffer effectConstantBuffer = effect.GetConstantBufferByName("scene"); effectConstantBuffer.SetConstantBuffer(sceneConstantsBuffer); RasterizerStateDescription desc = new RasterizerStateDescription() { CullMode = CullMode.None, FillMode = FillMode.Solid, IsFrontCounterClockwise = true, DepthBias = 0, DepthBiasClamp = 0, SlopeScaledDepthBias = 0, IsDepthClipEnabled = true, }; _device.Rasterizer.State = new RasterizerState(_device, desc); DepthStencilStateDescription depthDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, IsStencilEnabled = false, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less }; depthStencilState = new DepthStencilState(_device, depthDesc); DepthStencilStateDescription lightDepthStateDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, IsStencilEnabled = false, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less }; lightDepthStencilState = new DepthStencilState(_device, lightDepthStateDesc); // grender.fx shaderByteCode = LoadShader("grender.fx", shaderFlags); effect2 = new Effect(_device, shaderByteCode); technique = effect2.GetTechniqueByIndex(0); gBufferRenderPass = technique.GetPassByIndex(0); gBufferOverlayPass = technique.GetPassByIndex(1); info = new InfoText(_device); _meshFactory = new MeshFactory(this); MeshFactory = _meshFactory; CreateBuffers(); LibraryManager.LibraryStarted(); }
/// <summary> /// Registers the specified desc. /// </summary> /// <param name="desc">The desc.</param> /// <returns></returns> public RasterizerStateProxy Register(RasterizerStateDescription desc) { return(RasterStatePool.Register(desc) as RasterizerStateProxy); }
public bool Init(IntPtr WindowHandle) { var factory = new Factory1(); var adapter = factory.GetAdapter1(0); var monitor = adapter.GetOutput(0); var modes = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced); var rational = new Rational(0, 1); if (ToolkitSettings.VSync) { foreach (var mode in modes) { if (mode.Width == ToolkitSettings.Width && mode.Height == ToolkitSettings.Height) { rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator); break; } } } var adapterDescription = adapter.Description; VideoCardMemory = adapterDescription.DedicatedVideoMemory >> 10 >> 10; VideoCardDescription = adapterDescription.Description.Trim('\0'); monitor.Dispose(); adapter.Dispose(); factory.Dispose(); var swapChainDesc = new SwapChainDescription() { BufferCount = 2, ModeDescription = new ModeDescription(ToolkitSettings.Width, ToolkitSettings.Height, rational, Format.R8G8B8A8_UNorm), Usage = Usage.RenderTargetOutput, OutputHandle = WindowHandle, SampleDescription = new SampleDescription(1, 0), IsWindowed = true, Flags = SwapChainFlags.None, SwapEffect = SwapEffect.Discard }; SharpDX.Direct3D11.Device device; SwapChain swapChain; SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain); Device = device; SwapChain = swapChain; DeviceContext = device.ImmediateContext; var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0); m_RenderTargetView = new RenderTargetView(device, backBuffer); backBuffer.Dispose(); var depthBufferDesc = new Texture2DDescription() { Width = ToolkitSettings.Width, Height = ToolkitSettings.Height, MipLevels = 0, ArraySize = 1, Format = Format.D24_UNorm_S8_UInt, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; m_depthStencilBuffer = new Texture2D(device, depthBufferDesc); var depthStencilDecs = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always, }, BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; DepthStencilState = new DepthStencilState(Device, depthStencilDecs); DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1); var depthStencilViewDesc = new DepthStencilViewDescription() { Format = Format.D24_UNorm_S8_UInt, Dimension = DepthStencilViewDimension.Texture2D, Texture2D = new DepthStencilViewDescription.Texture2DResource() { MipSlice = 0 } }; BlendStateDescription bsd = new BlendStateDescription() { AlphaToCoverageEnable = false,//true, IndependentBlendEnable = false, }; bsd.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; bsd.RenderTarget[0].BlendOperation = BlendOperation.Add; bsd.RenderTarget[0].DestinationAlphaBlend = BlendOption.One; bsd.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; bsd.RenderTarget[0].IsBlendEnabled = true; bsd.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; bsd.RenderTarget[0].SourceAlphaBlend = BlendOption.Zero; bsd.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; //bsDefault = new BlendState(device, bsd); bsd.AlphaToCoverageEnable = true; BlendState bsAlpha = new BlendState(device, bsd); DeviceContext.OutputMerger.BlendState = bsAlpha; m_DepthStencilView = new DepthStencilView(Device, m_depthStencilBuffer, depthStencilViewDesc); DeviceContext.OutputMerger.SetTargets(m_DepthStencilView, m_RenderTargetView); m_RSDesc = new RasterizerStateDescription() { IsAntialiasedLineEnabled = true, CullMode = CullMode.Back, DepthBias = 10, DepthBiasClamp = .0f, IsDepthClipEnabled = false, FillMode = FillMode.Solid, IsFrontCounterClockwise = true, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = .0f }; m_RSCullSolid = new RasterizerState(Device, m_RSDesc); m_RSDesc.CullMode = CullMode.None; m_RSSolid = new RasterizerState(Device, m_RSDesc); m_RSDesc.FillMode = FillMode.Wireframe; m_RSWireFrame = new RasterizerState(Device, m_RSDesc); m_RSDesc.CullMode = CullMode.Back; m_RSCullWireFrame = new RasterizerState(Device, m_RSDesc); UpdateRasterizer(); return(true); }
protected override void CreateDeviceDependentResources() { RemoveAndDispose(ref vertexShader); RemoveAndDispose(ref lightBuffer); RemoveAndDispose(ref RTV); RemoveAndDispose(ref SRV); RemoveAndDispose(ref rsCullBack); RemoveAndDispose(ref rsCullFront); RemoveAndDispose(ref rsWireframe); RemoveAndDispose(ref blendStateAdd); RemoveAndDispose(ref depthLessThan); RemoveAndDispose(ref depthGreaterThan); RemoveAndDispose(ref depthDisabled); RemoveAndDispose(ref perLightBuffer); RemoveAndDispose(ref psAmbientLight); RemoveAndDispose(ref psDirectionalLight); RemoveAndDispose(ref psPointLight); RemoveAndDispose(ref psSpotLight); RemoveAndDispose(ref psDebugLight); RemoveAndDispose(ref perLightBuffer); // Retrieve our SharpDX.Direct3D11.Device1 instance var device = this.DeviceManager.Direct3DDevice; int width, height; SampleDescription sampleDesc; // Retrieve DSV from GBuffer and extract width/height // then create a new read-only DSV using (var depthTexture = gbuffer.DSV.ResourceAs <Texture2D>()) { width = depthTexture.Description.Width; height = depthTexture.Description.Height; sampleDesc = depthTexture.Description.SampleDescription; // Initialize read-only DSV var dsvDesc = gbuffer.DSV.Description; dsvDesc.Flags = DepthStencilViewFlags.ReadOnlyDepth | DepthStencilViewFlags.ReadOnlyStencil; DSVReadonly = ToDispose(new DepthStencilView(device, depthTexture, dsvDesc)); } // Check if GBuffer is multi-sampled bool isMSAA = sampleDesc.Count > 1; // Initialize the light render target var texDesc = new Texture2DDescription(); texDesc.BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget; texDesc.ArraySize = 1; texDesc.CpuAccessFlags = CpuAccessFlags.None; texDesc.Usage = ResourceUsage.Default; texDesc.Width = width; texDesc.Height = height; texDesc.MipLevels = 1; // No mip levels texDesc.SampleDescription = sampleDesc; texDesc.Format = Format.R8G8B8A8_UNorm; lightBuffer = ToDispose(new Texture2D(device, texDesc)); // Render Target View description var rtvDesc = new RenderTargetViewDescription(); rtvDesc.Format = Format.R8G8B8A8_UNorm; rtvDesc.Dimension = isMSAA ? RenderTargetViewDimension.Texture2DMultisampled : RenderTargetViewDimension.Texture2D; rtvDesc.Texture2D.MipSlice = 0; RTV = ToDispose(new RenderTargetView(device, lightBuffer, rtvDesc)); // SRV description for render targets var srvDesc = new ShaderResourceViewDescription(); srvDesc.Format = Format.R8G8B8A8_UNorm; srvDesc.Dimension = isMSAA ? SharpDX.Direct3D.ShaderResourceViewDimension.Texture2DMultisampled : SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D; srvDesc.Texture2D.MipLevels = -1; srvDesc.Texture2D.MostDetailedMip = 0; SRV = ToDispose(new ShaderResourceView(device, lightBuffer, srvDesc)); // Initialize additive blend state (assuming single render target) BlendStateDescription bsDesc = new BlendStateDescription(); bsDesc.RenderTarget[0].IsBlendEnabled = true; bsDesc.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; bsDesc.RenderTarget[0].SourceAlphaBlend = BlendOption.One; bsDesc.RenderTarget[0].DestinationAlphaBlend = BlendOption.One; bsDesc.RenderTarget[0].BlendOperation = BlendOperation.Add; bsDesc.RenderTarget[0].SourceBlend = BlendOption.One; bsDesc.RenderTarget[0].DestinationBlend = BlendOption.One; bsDesc.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; blendStateAdd = ToDispose(new BlendState(device, bsDesc)); // Initialize rasterizer states RasterizerStateDescription rsDesc = new RasterizerStateDescription(); rsDesc.FillMode = FillMode.Solid; rsDesc.CullMode = CullMode.Back; rsCullBack = ToDispose(new RasterizerState(device, rsDesc)); rsDesc.CullMode = CullMode.Front; rsCullFront = ToDispose(new RasterizerState(device, rsDesc)); rsDesc.CullMode = CullMode.Front; rsDesc.FillMode = FillMode.Wireframe; rsWireframe = ToDispose(new RasterizerState(device, rsDesc)); // Initialize depth state var dsDesc = new DepthStencilStateDescription(); dsDesc.IsStencilEnabled = false; dsDesc.IsDepthEnabled = true; // Less-than depth comparison dsDesc.DepthComparison = Comparison.Less; depthLessThan = ToDispose(new DepthStencilState(device, dsDesc)); // Greater-than depth comparison dsDesc.DepthComparison = Comparison.Greater; depthGreaterThan = ToDispose(new DepthStencilState(device, dsDesc)); // Depth/stencil testing disabled dsDesc.IsDepthEnabled = false; depthDisabled = ToDispose(new DepthStencilState(device, dsDesc)); // Buffer to light parameters perLightBuffer = ToDispose(new Buffer(device, Utilities.SizeOf <PerLight>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0)); if (isMSAA) { // Compile and create the vertex shader using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "VSLight", "vs_5_0")) vertexShader = ToDispose(new VertexShader(device, bytecode)); // Compile pixel shaders using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSAmbientLight", "ps_5_0")) psAmbientLight = ToDispose(new PixelShader(device, bytecode)); using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSDirectionalLight", "ps_5_0")) psDirectionalLight = ToDispose(new PixelShader(device, bytecode)); using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSPointLight", "ps_5_0")) psPointLight = ToDispose(new PixelShader(device, bytecode)); using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSSpotLight", "ps_5_0")) psSpotLight = ToDispose(new PixelShader(device, bytecode)); using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSDebugLight", "ps_5_0")) psDebugLight = ToDispose(new PixelShader(device, bytecode)); } else { // Compile and create the vertex shader using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "VSLight", "vs_5_0")) vertexShader = ToDispose(new VertexShader(device, bytecode)); // Compile pixel shaders using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSAmbientLight", "ps_5_0")) psAmbientLight = ToDispose(new PixelShader(device, bytecode)); using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSDirectionalLight", "ps_5_0")) psDirectionalLight = ToDispose(new PixelShader(device, bytecode)); using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSPointLight", "ps_5_0")) psPointLight = ToDispose(new PixelShader(device, bytecode)); using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSSpotLight", "ps_5_0")) psSpotLight = ToDispose(new PixelShader(device, bytecode)); using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSDebugLight", "ps_5_0")) psDebugLight = ToDispose(new PixelShader(device, bytecode)); } }
public override void Run() { #region Create renderers // Note: the renderers take care of creating their own // device resources and listen for DeviceManager.OnInitialize // Create a axis-grid renderer var axisGrid = ToDispose(new AxisGridRenderer()); axisGrid.Initialize(this); // Create and initialize the mesh renderer var loadedMesh = Common.Mesh.LoadFromFile("Tree.cmo"); loadedMesh.AddRange(Common.Mesh.LoadFromFile("Plane.cmo")); loadedMesh.AddRange(Common.Mesh.LoadFromFile("Cube.cmo")); List <DisplacedMeshRenderer> meshes = new List <DisplacedMeshRenderer>(); meshes.AddRange((from mesh in loadedMesh select ToDispose(new DisplacedMeshRenderer(mesh)))); foreach (var m in meshes) { m.Initialize(this); m.World = Matrix.Identity; } // Set the first animation as the current animation and start clock foreach (var m in meshes) { if (m.Mesh.Animations != null && m.Mesh.Animations.Any()) { m.CurrentAnimation = m.Mesh.Animations.First().Value; } m.Clock.Start(); } var triangle = new TriangleRenderer(); triangle.Initialize(this); // Create and initialize a Direct2D FPS text renderer var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16)); fps.Initialize(this); // Create and initialize a general purpose Direct2D text renderer // This will display some instructions and the current view and rotation offsets var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12)); textRenderer.Initialize(this); #endregion // Initialize the world matrix var worldMatrix = Matrix.Identity; // Set the camera position var cameraPosition = new Vector3(0, 0, 2); var cameraTarget = Vector3.Zero; // Looking at the origin 0,0,0 var cameraUp = Vector3.UnitY; // Y+ is Up // Prepare matrices // Create the view matrix from our camera position, look target and up direction var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp); viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0); // Create the projection matrix /* FoV 60degrees = Pi/3 radians */ // Aspect ratio (based on window size), Near clip, Far clip var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); // Maintain the correct aspect ratio on resize Window.Resize += (s, e) => { projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f); }; #region Rotation and window event handlers // Create a rotation vector to keep track of the rotation // around each of the axes var rotation = new Vector3(0.0f, 0.0f, 0.0f); var tessellationFactor = 2f; // default to 5 var tessellationPartition = "Integer"; var tessellationMethod = "Phong"; var displacementScale = 0.02f; // We will call this action to update text // for the text renderer Action updateText = () => { textRenderer.Text = String.Format("Tessellation Factor: {0:#0.0} (+/- to change)" + "\nPartitioning: {1} (F1,F2,F3,F4 to change)" + "\nTessellation: {2} (F5,F6,F7)" + "\nDisplacement: {3:#0.000} (Shift +/- to change)" + "\nPress F to toggle wireframe | Shift+N toggle Normal Map | N show normals" + "\nPress 1-4 to switch pixel shaders | Backspace to cycle meshes", tessellationFactor, tessellationPartition, tessellationMethod, displacementScale, DeviceManager.Direct3DDevice.NativePointer); }; Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>(); keyToggles[Keys.Z] = false; keyToggles[Keys.F] = false; // Support keyboard/mouse input to rotate or move camera view var moveFactor = 0.02f; // how much to change on each keypress var shiftKey = false; var ctrlKey = false; var background = Color.White; var activeTriTessellator = tessellateTriIntegerShader; var activePnTriTessellator = pnTriIntegerShader; var usePhongTessellation = true; var usePNTessellation = false; var showNormals = false; var enableNormalMap = true; var meshIndex = 0; Window.KeyDown += (s, e) => { var context = DeviceManager.Direct3DContext; shiftKey = e.Shift; ctrlKey = e.Control; switch (e.KeyCode) { // WASD -> pans view case Keys.A: viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.D: viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f); break; case Keys.S: if (shiftKey) { viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2; } break; case Keys.W: if (shiftKey) { viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f); } else { viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2; } break; // Up/Down and Left/Right - rotates around X / Y respectively // (Mouse wheel rotates around Z) case Keys.Down: worldMatrix *= Matrix.RotationX(moveFactor); rotation += new Vector3(moveFactor, 0f, 0f); break; case Keys.Up: worldMatrix *= Matrix.RotationX(-moveFactor); rotation -= new Vector3(moveFactor, 0f, 0f); break; case Keys.Left: worldMatrix *= Matrix.RotationY(moveFactor); rotation += new Vector3(0f, moveFactor, 0f); break; case Keys.Right: worldMatrix *= Matrix.RotationY(-moveFactor); rotation -= new Vector3(0f, moveFactor, 0f); break; case Keys.T: fps.Show = !fps.Show; textRenderer.Show = !textRenderer.Show; break; case Keys.B: if (background == Color.White) { background = new Color(30, 30, 34); } else { background = Color.White; } break; case Keys.G: axisGrid.Show = !axisGrid.Show; break; case Keys.P: // Pause or resume mesh animation meshes.ForEach(m => { if (m.Clock.IsRunning) { m.Clock.Stop(); } else { m.Clock.Start(); } }); break; case Keys.X: // To test for correct resource recreation // Simulate device reset or lost. System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); DeviceManager.Initialize(DeviceManager.Dpi); System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()); break; case Keys.Z: keyToggles[Keys.Z] = !keyToggles[Keys.Z]; if (keyToggles[Keys.Z]) { context.PixelShader.Set(depthPixelShader); } else { context.PixelShader.Set(pixelShader); } break; case Keys.F: keyToggles[Keys.F] = !keyToggles[Keys.F]; RasterizerStateDescription rasterDesc; if (context.Rasterizer.State != null) { rasterDesc = context.Rasterizer.State.Description; } else { rasterDesc = new RasterizerStateDescription() { CullMode = CullMode.None, FillMode = FillMode.Solid } }; if (keyToggles[Keys.F]) { rasterDesc.FillMode = FillMode.Wireframe; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } else { rasterDesc.FillMode = FillMode.Solid; context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc)); } break; case Keys.N: if (!shiftKey) { showNormals = !showNormals; } else { enableNormalMap = !enableNormalMap; } break; case Keys.D1: context.PixelShader.Set(pixelShader); break; case Keys.D2: context.PixelShader.Set(lambertShader); break; case Keys.D3: context.PixelShader.Set(phongShader); break; case Keys.D4: context.PixelShader.Set(blinnPhongShader); break; case Keys.Add: var multiple = 1.0f; if (ctrlKey) { multiple = 3.0f; } if (!shiftKey) { tessellationFactor += 0.2f * multiple; tessellationFactor = Math.Min(tessellationFactor, 64); } else { displacementScale += 0.005f * multiple; } break; case Keys.Subtract: multiple = 1.0f; if (ctrlKey) { multiple = 3.0f; } if (!shiftKey) { tessellationFactor -= 0.2f * multiple; tessellationFactor = Math.Max(tessellationFactor, 0); } else { displacementScale -= 0.005f * multiple; } break; case Keys.F1: tessellationPartition = "Integer"; activeTriTessellator = tessellateTriIntegerShader; activePnTriTessellator = pnTriIntegerShader; break; case Keys.F2: tessellationPartition = "Pow2"; activeTriTessellator = tessellateTriPow2Shader; activePnTriTessellator = pnTriPow2Shader; break; case Keys.F3: tessellationPartition = "Fractional Even"; activeTriTessellator = tessellateTriFractionalEvenShader; activePnTriTessellator = pnTriFractionalEvenShader; break; case Keys.F4: tessellationPartition = "Fractional Odd"; activeTriTessellator = tessellateTriFractionalOddShader; activePnTriTessellator = pnTriFractionalOddShader; break; case Keys.F5: usePhongTessellation = false; usePNTessellation = false; tessellationMethod = "Tri + displacement"; break; case Keys.F6: usePhongTessellation = true; usePNTessellation = false; tessellationMethod = "Phong + displacement"; break; case Keys.F7: usePhongTessellation = false; usePNTessellation = true; tessellationMethod = "PN-Triangle + displacement"; break; case Keys.Back: meshIndex = (meshIndex + 1) % meshes.Count; break; } updateText(); }; Window.KeyUp += (s, e) => { // Clear the shift/ctrl keys so they aren't sticky if (e.KeyCode == Keys.ShiftKey) { shiftKey = false; } if (e.KeyCode == Keys.ControlKey) { ctrlKey = false; } }; Window.MouseWheel += (s, e) => { if (shiftKey) { // Zoom in/out viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2); } else { // rotate around Z-axis viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor); rotation += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor); } updateText(); }; var lastX = 0; var lastY = 0; Window.MouseDown += (s, e) => { if (e.Button == MouseButtons.Left) { lastX = e.X; lastY = e.Y; } }; Window.MouseMove += (s, e) => { if (e.Button == MouseButtons.Left) { var yRotate = lastX - e.X; var xRotate = lastY - e.Y; lastY = e.Y; lastX = e.X; // Mouse move changes viewMatrix *= Matrix.RotationX(-xRotate * moveFactor); viewMatrix *= Matrix.RotationY(-yRotate * moveFactor); updateText(); } }; // Display instructions with initial values updateText(); #endregion var clock = new System.Diagnostics.Stopwatch(); clock.Start(); #region Render loop // Create and run the render loop RenderLoop.Run(Window, () => { // Start of frame: // Retrieve immediate context var context = DeviceManager.Direct3DContext; // Clear depth stencil view context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); // Clear render target view context.ClearRenderTargetView(RenderTargetView, background); // Create viewProjection matrix var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix); // Extract camera position from view var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4; cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z); // If Keys.CtrlKey is down, auto rotate viewProjection based on time var time = clock.ElapsedMilliseconds / 1000.0f; var perFrame = new ConstantBuffers.PerFrame(); perFrame.Light.Color = new Color(0.8f, 0.8f, 0.8f, 1.0f); var lightDir = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix); perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z);// new Vector3(Vector3.Transform(new Vector3(1f, -1f, 1f), worldMatrix * worldRotation).ToArray().Take(3).ToArray()); perFrame.CameraPosition = cameraPosition; perFrame.TessellationFactor = tessellationFactor; context.UpdateSubresource(ref perFrame, perFrameBuffer); // Set decal shader resource views //context.PixelShader.SetShaderResources(3, decalDiffuse, decalNormal); context.DomainShader.SetShaderResource(2, decalDisplacement); // Render each object var perMaterial = new ConstantBuffers.PerMaterial(); perMaterial.Ambient = new Color4(0.2f); perMaterial.Diffuse = Color.White; perMaterial.Emissive = new Color4(0); perMaterial.Specular = Color.White; perMaterial.SpecularPower = 20f; perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); var perObject = new ConstantBuffers.PerObject(); // MESH context.VertexShader.Set(tessellateVertexShader); context.HullShader.Set(activeTriTessellator); if (usePhongTessellation) { context.DomainShader.Set(tessellatePhongDomainShader); } else if (usePNTessellation) { context.HullShader.Set(activePnTriTessellator); context.DomainShader.Set(pnTriDomainShader); } else { context.DomainShader.Set(tessellateTriDomainShader); } var m = meshes[meshIndex]; //meshes.ForEach((m) => //{ // Assign decal textures m.TextureViews[3] = decalDiffuse; m.TextureViews[4] = decalNormal; // Apply decal var decal = new ConstantBuffers.DecalBuffer(); decal.DecalDisplaceScale = 0.10f; var decalVectors = new Vector3[3]; if (meshIndex != 1) { Vector3.Orthonormalize(decalVectors, new[] { new Vector3(0, 0.5f, 0.5f), Vector3.UnitX, -Vector3.UnitY }); decal.DecalPosition = new Vector3(0, 1, 1); } else { Vector3.Orthonormalize(decalVectors, new[] { new Vector3(0, 0.5f, 0.2f), Vector3.UnitX, Vector3.UnitZ }); decal.DecalPosition = new Vector3(0, 0, 0); } decal.DecalNormal = decalVectors[0]; decal.DecalTangent = decalVectors[1]; // U-axis of tex decal.DecalBitangent = decalVectors[2]; // V-axis of tex decal.DecalRadius = 0.5f; context.UpdateSubresource(ref decal, decalBuffer); // TODO: set decal buffer on mouse click using "Picking" // Provide the material constant buffer to the mesh renderer perObject.World = m.World * worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); m.EnableNormalMap = enableNormalMap; m.DisplacementScale = displacementScale; m.DisplaceMidLevel = 0.5f; m.PerMaterialBuffer = perMaterialBuffer; m.PerArmatureBuffer = perArmatureBuffer; m.Render(); if (showNormals) { using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(debugNormals); m.Render(); context.PixelShader.Set(prevPixelShader); context.GeometryShader.Set(null); } } //}); // TRIANGLE //triangle.Render(); //// QUAD //context.VertexShader.Set(tessellateVertexShader); //context.HullShader.Set(activeQuadTessellator); //context.DomainShader.Set(tessellateQuadDomainShader); //quad.Render(); // BEZIER //context.VertexShader.Set(tessellateVertexShader); //context.HullShader.Set(activeBezierTessellator); //context.DomainShader.Set(tessellateBezierDomainShader); //bezier.Render(); // AXIS GRID context.VertexShader.Set(vertexShader); context.HullShader.Set(null); context.DomainShader.Set(null); context.GeometryShader.Set(null); using (var prevPixelShader = context.PixelShader.Get()) { perMaterial.HasTexture = 0; perMaterial.UVTransform = Matrix.Identity; context.UpdateSubresource(ref perMaterial, perMaterialBuffer); context.PixelShader.Set(pixelShader); perObject = new ConstantBuffers.PerObject(); perObject.World = worldMatrix; perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World)); perObject.WorldViewProjection = perObject.World * viewProjection; perObject.ViewProjection = viewProjection; perObject.Transpose(); context.UpdateSubresource(ref perObject, perObjectBuffer); axisGrid.Render(); context.PixelShader.Set(prevPixelShader); } // Render FPS fps.Render(); // Render instructions + position changes textRenderer.Render(); // Present the frame Present(); }); #endregion }
internal static RasterizerId CreateRasterizerState(RasterizerStateDescription description) { var id = new RasterizerId { Index = RasterizerStates.Allocate() }; MyArrayHelpers.Reserve(ref RasterizerObjects, id.Index + 1); RasterizerStates.Data[id.Index] = description; InitRasterizerState(id); RasterizerIndices.Add(id); return id; }
public void LoadDirect3D(SharpDX.Direct3D11.Device device) { // Set up description of swap chain /*SwapChainDescription scd = new SwapChainDescription(); * scd.BufferCount = 1; * scd.ModeDescription = new ModeDescription(Width, Height, new Rational(60, 1), Format.B8G8R8A8_UNorm); * scd.Usage = Usage.RenderTargetOutput; * scd.OutputHandle = Handle; * scd.SampleDescription.Count = 1; * scd.SampleDescription.Quality = 0; * scd.IsWindowed = true; * scd.ModeDescription.Width = Width; * scd.ModeDescription.Height = Height;*/ // Create device and swap chain according to the description above //SharpDX.Direct3D11.Device d; //SwapChain sc; //DeviceCreationFlags flags = DeviceCreationFlags.BgraSupport | DeviceCreationFlags.SingleThreaded; #if DEBUG //flags |= DeviceCreationFlags.Debug; #endif //SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, flags, scd, out d, out sc); //this.SwapChain = sc; // we have to use these temp variables //this.Device = new SharpDX.Direct3D11.Device(DriverType.Hardware, flags); //this.Device = d; // because properties can't be passed as out parameters. =( // Set up the rendering context and buffers and stuff this.Device = device; ImmediateContext = Device.ImmediateContext; //BuildBuffers(); // Build a custom rasterizer state that doesn't cull backfaces RasterizerStateDescription frs = new RasterizerStateDescription(); frs.CullMode = CullMode.None; frs.FillMode = FillMode.Solid; FillRasterizerState = new RasterizerState(Device, frs); ImmediateContext.Rasterizer.State = FillRasterizerState; // Build a custom rasterizer state for wireframe drawing RasterizerStateDescription wrs = new RasterizerStateDescription(); wrs.CullMode = CullMode.None; wrs.FillMode = FillMode.Wireframe; wrs.IsAntialiasedLineEnabled = false; wrs.DepthBias = -10; WireframeRasterizerState = new RasterizerState(Device, wrs); // Set texture sampler state SamplerStateDescription ssd = new SamplerStateDescription(); ssd.AddressU = TextureAddressMode.Wrap; ssd.AddressV = TextureAddressMode.Wrap; ssd.AddressW = TextureAddressMode.Wrap; ssd.Filter = Filter.MinMagMipLinear; ssd.MaximumAnisotropy = 1; SampleState = new SamplerState(Device, ssd); ImmediateContext.PixelShader.SetSampler(0, SampleState); // Load the default texture var path = Path.Combine(App.ExecFolder, "Default.bmp"); System.Drawing.Bitmap deftex = new System.Drawing.Bitmap(path); DefaultTexture = LoadTexture(deftex); deftex.Dispose(); DefaultTextureView = new ShaderResourceView(Device, DefaultTexture); // Load the default position-texture shader DefaultEffect = new Effect <WorldConstants, WorldVertex>(Device, Properties.Resources.StandardShader); TextureCache = new PreviewTextureCache(Device); }
private void SetRasterizerState() { var rasterizerState = new RasterizerStateDescription { CullMode = CullMode.Back, FillMode = FillMode.Solid, IsFrontCounterclockwise = false, DepthBias = 0, DepthBiasClamp = 0, SlopeScaledDepthBias = 0, IsDepthClipEnabled = true, IsScissorEnabled = false, IsMultisampleEnabled = false, IsAntialiasedLineEnabled = true, }; Device.Rasterizer.State = RasterizerState.FromDescription(Device, rasterizerState); }
public VoroniRenderer2d(String title) { m_scenes = new List <Scene>(); cameras_ = new List <Camera>(); samplerStates_ = new Dictionary <string, SamplerState>(); lastTime_ = DateTime.Now; form_ = new RenderForm(title); form_.Width = 1024; form_.Height = 768; var desc = new SwapChainDescription() { BufferCount = 1, ModeDescription = new ModeDescription(form_.ClientSize.Width, form_.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm), IsWindowed = true, OutputHandle = form_.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, desc, out device_, out swapChain_); Factory factory = swapChain_.GetParent <Factory>(); factory.SetWindowAssociation(form_.Handle, WindowAssociationFlags.IgnoreAll); backBuffer_ = Texture2D.FromSwapChain <Texture2D>(swapChain_, 0); renderView_ = new RenderTargetView(device_, backBuffer_); var depthDesc = new Texture2DDescription() { Width = form_.Width, Height = form_.Height, MipLevels = 1, ArraySize = 1, Format = Format.D24_UNorm_S8_UInt, SampleDescription = new SampleDescription() { Count = 1, Quality = 0 }, Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = 0, OptionFlags = 0 }; m_depthBuffer = new Texture2D(device_, depthDesc); device_.ImmediateContext.Rasterizer.SetViewports(new Viewport(0, 0, form_.ClientSize.Width, form_.ClientSize.Height, 0.1f, 1.0f)); RasterizerStateDescription descRast = new RasterizerStateDescription() { FillMode = FillMode.Solid, CullMode = CullMode.None, IsDepthClipEnabled = true }; m_rasterizerState = RasterizerState.FromDescription(device_, descRast); DepthStencilStateDescription dsStateDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, FrontFace = new DepthStencilOperationDescription() { Comparison = Comparison.Always, DepthFailOperation = StencilOperation.Increment, FailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Keep }, BackFace = new DepthStencilOperationDescription() { Comparison = Comparison.Always, DepthFailOperation = StencilOperation.Increment, FailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Keep }, }; DepthStencilState dsState = DepthStencilState.FromDescription(device_, dsStateDesc); device_.ImmediateContext.OutputMerger.DepthStencilState = dsState; device_.ImmediateContext.Rasterizer.State = m_rasterizerState; DepthStencilViewDescription DSVDesc = new DepthStencilViewDescription() { Format = Format.D24_UNorm_S8_UInt, Dimension = DepthStencilViewDimension.Texture2D, MipSlice = 0 }; m_depthView = new DepthStencilView(device_, m_depthBuffer, DSVDesc); dsState.Dispose(); device_.ImmediateContext.OutputMerger.SetTargets(m_depthView, renderView_); CreateSamplers(); }
private void InitalizeGraphics() { if (Window.RenderCanvasHandle == IntPtr.Zero) throw new InvalidOperationException(); SwapChainDescription swapChainDesc = new SwapChainDescription() { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, OutputHandle = Window.RenderCanvasHandle, SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput, ModeDescription = new ModeDescription() { Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm, //Format = SlimDX.DXGI.Format.B8G8R8A8_UNorm, Width = (int)Window.RenderCanvasSize.Width, Height = (int)Window.RenderCanvasSize.Height, RefreshRate = new Rational(60, 1), Scaling = DisplayModeScaling.Unspecified, ScanlineOrdering = DisplayModeScanlineOrdering.Unspecified }, SampleDescription = new SampleDescription(1, 0) }; var giFactory = new SlimDX.DXGI.Factory(); var adapter = giFactory.GetAdapter(0); Device device; SwapChain swapChain; Device.CreateWithSwapChain(adapter, DriverType.Hardware, DeviceCreationFlags.Debug, swapChainDesc, out device, out swapChain); _swapChain = swapChain; GraphicsDevice = device; // create a view of our render target, which is the backbuffer of the swap chain we just created using (var resource = SlimDX.Direct3D10.Resource.FromSwapChain<Texture2D>(swapChain, 0)) { _backBuffer = new RenderTargetView(device, resource); } // setting a viewport is required if you want to actually see anything var viewport = new Viewport(0, 0, (int)Window.RenderCanvasSize.Width, (int)Window.RenderCanvasSize.Height); device.OutputMerger.SetTargets(_backBuffer); device.Rasterizer.SetViewports(viewport); CreateDepthStencil(); LoadVisualizationEffect(); // Allocate a large buffer to write the PhysX visualization vertices into // There's more optimized ways of doing this, but for this sample a large buffer will do _userPrimitivesBuffer = new SlimDX.Direct3D10.Buffer(GraphicsDevice, VertexPositionColor.SizeInBytes * 50000, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None); var elements = new[] { new InputElement("Position", 0, Format.R32G32B32A32_Float, 0, 0), new InputElement("Color", 0, Format.R32G32B32A32_Float, 16, 0) }; _inputLayout = new InputLayout(GraphicsDevice, _visualizationEffect.RenderScenePass0.Description.Signature, elements); // States var blendDesc = new BlendStateDescription() { SourceBlend = BlendOption.One, DestinationBlend = BlendOption.Zero, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add }; blendDesc.SetBlendEnable(0, true); _blendState = BlendState.FromDescription(device, blendDesc); var rasterDesc = new RasterizerStateDescription() { IsAntialiasedLineEnabled = false, IsMultisampleEnabled = false, FillMode = FillMode.Solid, CullMode = CullMode.None }; _rasterizerState = RasterizerState.FromDescription(device, rasterDesc); }
/// <summary> /// Compute the parameters and store them in the material. /// </summary> /// <param name="log">The logger.</param> /// <returns>A boolean stating that the parameters were incorrectly created.</returns> public bool CreateParameterCollectionData(Logger log = null) { Parameters.Clear(); var hasErrors = false; var materialShaderCreator = new MaterialTreeShaderCreator(Material); var shaders = materialShaderCreator.GenerateModelShaders(); if (log != null) { (materialShaderCreator.Logger).CopyTo(log); } foreach (var keyValue in Material.Parameters) { // NOTE: cheap way to activate alpha blending Parameters.Set(keyValue.Key, keyValue.Value); if (keyValue.Key == MaterialParameters.UseTransparent && Material.GetParameter(MaterialParameters.UseTransparent)) { // using non premultiply alpha blending var blendStateDescr = new BlendStateDescription(Blend.SourceAlpha, Blend.InverseSourceAlpha); var blendState = new FakeBlendState(blendStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.BlendStateKey, ContentReference.Create((BlendState)blendState)); // disable face culling // TODO: make this programmable var rasterizerStateDescr = new RasterizerStateDescription(CullMode.None); var rasterizerState = new FakeRasterizerState(rasterizerStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.RasterizerStateKey, ContentReference.Create((RasterizerState)rasterizerState)); // disable depth write var depthStencilStateDescr = new DepthStencilStateDescription(true, false); var depthStencilState = new FakeDepthStencilState(depthStencilStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.DepthStencilStateKey, ContentReference.Create((DepthStencilState)depthStencilState)); } else if (keyValue.Key == MaterialParameters.UseTransparentMask && Material.GetParameter(MaterialParameters.UseTransparentMask)) { // disable face culling // TODO: make this programmable var rasterizerStateDescr = new RasterizerStateDescription(CullMode.None); var rasterizerState = new FakeRasterizerState(rasterizerStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.RasterizerStateKey, ContentReference.Create((RasterizerState)rasterizerState)); // enable depth write var depthStencilStateDescr = new DepthStencilStateDescription(true, true); var depthStencilState = new FakeDepthStencilState(depthStencilStateDescr); Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.DepthStencilStateKey, ContentReference.Create((DepthStencilState)depthStencilState)); } } var textureVisitor = new MaterialTextureVisitor(Material); var allTextures = textureVisitor.GetAllModelTextureValuesWithGenerics(); foreach (var texture in allTextures) { if (texture.TextureReference == null || (texture.TextureReference.Id == Guid.Empty && String.IsNullOrEmpty(texture.TextureReference.Location))) { if (log != null) { log.Error("[Material] Material {0} is missing a texture", materialUrl); } hasErrors = true; } else { Parameters.Set(texture.UsedParameterKey, new ContentReference <Graphics.Texture>(texture.TextureReference.Id, texture.TextureReference.Location)); AddSampler(texture.Sampler); } } var allSamplers = textureVisitor.GetAllSamplerValues(); foreach (var sampler in allSamplers) { AddSampler(sampler); } var parameterVisitor = new MaterialParametersVisitor(Material); var parameters = parameterVisitor.GetParameters(); foreach (var keyValue in parameters) { // The code is separated from the previous code since the key is not generated the same way. if (keyValue.Value is MaterialTextureNode) { var textureNode = (MaterialTextureNode)keyValue.Value; if (textureNode != null) { if (textureNode.TextureReference == null || textureNode.TextureReference.Id == Guid.Empty || String.IsNullOrEmpty(textureNode.TextureReference.Location)) { if (log != null) { log.Error("[Material] Material {0} is missing a texture", materialUrl); } hasErrors = true; } else { Parameters.Set(keyValue.Key, new ContentReference <Graphics.Texture>(textureNode.TextureReference.Id, textureNode.TextureReference.Location)); } } } else if (keyValue.Value is NodeParameterSampler) { var sampler = (NodeParameterSampler)keyValue.Value; if (sampler.SamplerParameterKey == null && keyValue.Key is ParameterKey <SamplerState> ) { sampler.SamplerParameterKey = (ParameterKey <SamplerState>)keyValue.Key; } AddSampler(sampler); } else { Parameters.Set(keyValue.Key, keyValue.Value); } } // NOTE: this can set the shader uniforms and potentially override what was in Material.SharedParameters foreach (var keyValue in shaders) { if (log != null && (keyValue.Key == MaterialParameters.BumpMap || keyValue.Key == MaterialParameters.EmissiveMap || keyValue.Key == MaterialParameters.ReflectionMap)) { log.Warning("[Material] Material {0} contains the key {1} which is not yet handled by the engine.", materialUrl, keyValue.Key); } Parameters.Set(keyValue.Key, keyValue.Value); } return(hasErrors); }
private Texture2D CreateTexture(int width, int height, bool multiSampling) { var description = new SlimDX.Direct3D10.Texture2DDescription(); description.ArraySize = 1; description.BindFlags = SlimDX.Direct3D10.BindFlags.RenderTarget | SlimDX.Direct3D10.BindFlags.ShaderResource; description.CpuAccessFlags = CpuAccessFlags.None; description.Format = Format.B8G8R8A8_UNorm; description.MipLevels = 1; //description.MiscellaneousResourceOptions = D3D10.MiscellaneousResourceOptions.Shared; // Multi-sample anti-aliasing //description.MiscellaneousResourceOptions = D3D10.MiscellaneousResourceOptions.Shared; int count; if (multiSampling) count = 8; else count = 1; int quality = device.CheckMultisampleQualityLevels(description.Format, count); if (count == 1) quality = 1; // Multi-sample anti-aliasing SampleDescription sampleDesc = new SampleDescription(count, 0); description.SampleDescription = sampleDesc; RasterizerStateDescription rastDesc = new RasterizerStateDescription(); rastDesc.CullMode = CullMode.Back; rastDesc.FillMode = FillMode.Solid; rastDesc.IsMultisampleEnabled = false; rastDesc.IsAntialiasedLineEnabled = false; //rastDesc.DepthBias = 0; //rastDesc.DepthBiasClamp = 0; //rastDesc.IsDepthClipEnabled = true; //rastDesc.IsFrontCounterclockwise = false; //rastDesc.IsScissorEnabled = true; //rastDesc.SlopeScaledDepthBias = 0; device.Rasterizer.State = RasterizerState.FromDescription(device, rastDesc); description.Usage = ResourceUsage.Default; description.OptionFlags = ResourceOptionFlags.Shared; description.Height = (int)height; description.Width = (int)width; return new Texture2D(device, description); }
public override void Attach(IRenderHost host) { /// --- attach this.renderTechnique = Techniques.RenderCubeMap; base.Attach(host); /// --- get variables this.vertexLayout = EffectsManager.Instance.GetLayout(this.renderTechnique); this.effectTechnique = effect.GetTechniqueByName(this.renderTechnique.Name); this.effectTransforms = new EffectTransformVariables(this.effect); /// -- attach cube map if (this.Filename != null) { /// -- attach texture using (var texture = Texture2D.FromFile<Texture2D>(this.Device, this.Filename)) { this.texCubeMapView = new ShaderResourceView(this.Device, texture); } this.texCubeMap = effect.GetVariableByName("texCubeMap").AsShaderResource(); this.texCubeMap.SetResource(this.texCubeMapView); this.bHasCubeMap = effect.GetVariableByName("bHasCubeMap").AsScalar(); this.bHasCubeMap.Set(true); /// --- set up geometry var sphere = new MeshBuilder(false,true,false); sphere.AddSphere(new Vector3(0, 0, 0)); this.geometry = sphere.ToMeshGeometry3D(); /// --- set up vertex buffer this.vertexBuffer = Device.CreateBuffer(BindFlags.VertexBuffer, CubeVertex.SizeInBytes, this.geometry.Positions.Select((x, ii) => new CubeVertex() { Position = new Vector4(x, 1f) }).ToArray()); /// --- set up index buffer this.indexBuffer = Device.CreateBuffer(BindFlags.IndexBuffer, sizeof(int), geometry.Indices.Array); /// --- set up rasterizer states var rasterStateDesc = new RasterizerStateDescription() { FillMode = FillMode.Solid, CullMode = CullMode.Back, IsMultisampleEnabled = true, IsAntialiasedLineEnabled = true, IsFrontCounterClockwise = false, }; this.rasterState = new RasterizerState(this.Device, rasterStateDesc); /// --- set up depth stencil state var depthStencilDesc = new DepthStencilStateDescription() { DepthComparison = Comparison.LessEqual, DepthWriteMask = global::SharpDX.Direct3D11.DepthWriteMask.All, IsDepthEnabled = true, }; this.depthStencilState = new DepthStencilState(this.Device, depthStencilDesc); } /// --- flush this.Device.ImmediateContext.Flush(); }
private void BeginScene() { // make sure buffers are initialized with current size EnsureOutputBuffers(); // bind the views to the output merger stage _dxDevice.OutputMerger.SetTargets(_dxDepthStencilView, _dxRenderView); // clear buffers _dxDevice.ClearDepthStencilView(_dxDepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0); _dxDevice.ClearRenderTargetView(_dxRenderView, new Color4(0f, 0, 0, 0)); // uses transparent color // set rasterization parameters var rsd = new RasterizerStateDescription { //IsAntialiasedLineEnabled = true, IsFrontCounterclockwise = false, CullMode = CullMode.None, FillMode = (_wireframe) ? FillMode.Wireframe : FillMode.Solid }; RasterizerState rsdState = RasterizerState.FromDescription(_dxDevice, rsd); _dxDevice.Rasterizer.State = rsdState; // set viewport _dxDevice.Rasterizer.SetViewports(new Viewport(0, 0, ClientWidth, ClientHeight, 0.0f, 1.0f)); }
private static void Main() { // Device creation var form = new RenderForm("Stereo test") { ClientSize = size, //FormBorderStyle = System.Windows.Forms.FormBorderStyle.None, //WindowState = FormWindowState.Maximized }; form.KeyDown += new KeyEventHandler(form_KeyDown); // form.Resize += new EventHandler(form_Resize); ModeDescription mDesc = new ModeDescription(form.ClientSize.Width, form.ClientSize.Height, new Rational(120000, 1000), Format.R8G8B8A8_UNorm); mDesc.ScanlineOrdering = DisplayModeScanlineOrdering.Progressive; mDesc.Scaling = DisplayModeScaling.Unspecified; var desc = new SwapChainDescription() { BufferCount = 1, ModeDescription = mDesc, Flags = SwapChainFlags.AllowModeSwitch, IsWindowed = false, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; Device.CreateWithSwapChain(null, DriverType.Hardware, DeviceCreationFlags.Debug, desc, out device, out swapChain); //Stops Alt+enter from causing fullscreen skrewiness. factory = swapChain.GetParent<Factory>(); factory.SetWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll); backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0); renderView = new RenderTargetView(device, backBuffer); ImageLoadInformation info = new ImageLoadInformation() { BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, FilterFlags = FilterFlags.None, Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm, MipFilterFlags = FilterFlags.None, OptionFlags = ResourceOptionFlags.None, Usage = ResourceUsage.Staging, MipLevels = 1 }; // Make texture 3D sourceTexture = Texture2D.FromFile(device, "medusa.jpg", info); ImageLoadInformation info2 = new ImageLoadInformation() { BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, FilterFlags = FilterFlags.None, Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm, MipFilterFlags = FilterFlags.None, OptionFlags = ResourceOptionFlags.None, Usage = ResourceUsage.Default, MipLevels = 1 }; Texture2D tShader = Texture2D.FromFile(device, "medusa.jpg", info2); srv = new ShaderResourceView(device, tShader); //ResizeDevice(new Size(1920, 1080), true); // Create a quad that fills the whole screen BuildQuad(); // Create world view (ortho) projection matrices //QuaternionCam qCam = new QuaternionCam(); // Load effect from file. It is a basic effect that renders a full screen quad through // an ortho projectio=n matrix effect = Effect.FromFile(device, "Texture.fx", "fx_4_0", ShaderFlags.Debug, EffectFlags.None); EffectTechnique technique = effect.GetTechniqueByIndex(0); EffectPass pass = technique.GetPassByIndex(0); InputLayout layout = new InputLayout(device, pass.Description.Signature, new[] { new InputElement( "POSITION", 0, Format. R32G32B32A32_Float, 0, 0), new InputElement( "TEXCOORD", 0, Format. R32G32_Float, 16, 0) }); //effect.GetVariableByName("mWorld").AsMatrix().SetMatrix( // Matrix.Translation(Layout.OrthographicTransform(Vector2.Zero, 99, size))); //effect.GetVariableByName("mView").AsMatrix().SetMatrix(qCam.View); //effect.GetVariableByName("mProjection").AsMatrix().SetMatrix(qCam.OrthoProjection); //effect.GetVariableByName("tDiffuse").AsResource().SetResource(srv); // Set RT and Viewports device.OutputMerger.SetTargets(renderView); device.Rasterizer.SetViewports(new Viewport(0, 0, size.Width, size.Height, 0.0f, 1.0f)); // Create solid rasterizer state RasterizerStateDescription rDesc = new RasterizerStateDescription() { CullMode = CullMode.None, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsAntialiasedLineEnabled = false, IsFrontCounterclockwise = true, //IsMultisampleEnabled = true, }; RasterizerState rState = RasterizerState.FromDescription(device, rDesc); device.Rasterizer.State = rState; Texture2DDescription rtDesc = new Texture2DDescription { ArraySize = 1, Width = size.Width, Height = size.Height, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm, OptionFlags = ResourceOptionFlags.None, Usage = ResourceUsage.Default, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }; rtTex = new Texture2D(device, rtDesc); rv = new RenderTargetView(device, rtTex); stereoizedTexture = Make3D(sourceTexture); //ResizeDevice(new Size(1920, 1080), true); Console.WriteLine(form.ClientSize); // Main Loop MessagePump.Run(form, () => { device.ClearRenderTargetView(renderView, Color.Cyan); //device.InputAssembler.SetInputLayout(layout); //device.InputAssembler.SetPrimitiveTopology(PrimitiveTopology.TriangleList); //device.OutputMerger.SetTargets(rv); //device.InputAssembler.SetVertexBuffers(0, // new VertexBufferBinding(vertices, 24, 0)); //device.InputAssembler.SetIndexBuffer(indices, Format.R16_UInt, 0); //for (int i = 0; i < technique.Description.PassCount; ++i) //{ // // Render the full screen quad // pass.Apply(); // device.DrawIndexed(6, 0, 0); //} ResourceRegion stereoSrcBox = new ResourceRegion { Front = 0, Back = 1, Top = 0, Bottom = size.Height, Left = 0, Right = size.Width }; device.CopySubresourceRegion(stereoizedTexture, 0, stereoSrcBox, backBuffer, 0, 0, 0, 0); //device.CopyResource(rv.Resource, backBuffer); swapChain.Present(0, PresentFlags.None); }); // Dispose resources vertices.Dispose(); layout.Dispose(); effect.Dispose(); renderView.Dispose(); backBuffer.Dispose(); device.Dispose(); swapChain.Dispose(); rState.Dispose(); stereoizedTexture.Dispose(); sourceTexture.Dispose(); indices.Dispose(); srv.Dispose(); }
public override bool Init() { if (!base.Init()) { return false; } BuildGeometryBuffers(); BuildFX(); BuildVertexLayout(); var wireFrameDesc = new RasterizerStateDescription { FillMode = FillMode.Wireframe, CullMode = CullMode.Back, IsFrontCounterclockwise = false, IsDepthClipEnabled = true }; _wireframeRS = RasterizerState.FromDescription(Device, wireFrameDesc); return true; }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for transparent objects. // GraphicsPipelineStateDescription transparentPsoDesc = opaquePsoDesc.Copy(); var transparencyBlendDesc = new RenderTargetBlendDescription { IsBlendEnabled = true, LogicOpEnable = false, // TODO: API suggestion: Rename to IsLogicOpEnabled similar to IsBlendEnabled. SourceBlend = BlendOption.SourceAlpha, DestinationBlend = BlendOption.InverseSourceAlpha, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, LogicOp = LogicOperation.Noop, RenderTargetWriteMask = ColorWriteMaskFlags.All }; transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc; _psos["transparent"] = Device.CreateGraphicsPipelineState(transparentPsoDesc); // // PSO for alpha tested objects. // GraphicsPipelineStateDescription alphaTestedPsoDesc = opaquePsoDesc.Copy(); alphaTestedPsoDesc.PixelShader = _shaders["alphaTestedPS"]; alphaTestedPsoDesc.RasterizerState.CullMode = CullMode.None; _psos["alphaTested"] = Device.CreateGraphicsPipelineState(alphaTestedPsoDesc); }
private void AffectConstants() { // Texture Texture2D texture2D = Texture2D.FromFile(device11, "yoda.jpg"); ShaderResourceView view = new ShaderResourceView(device11, texture2D); effect.GetVariableByName("yodaTexture").AsResource().SetResource(view); RasterizerStateDescription rasterizerStateDescription = new RasterizerStateDescription {CullMode = CullMode.None, FillMode = FillMode.Solid}; device11.ImmediateContext.Rasterizer.State = RasterizerState.FromDescription(device11, rasterizerStateDescription); // Matrices Matrix worldMatrix = Matrix.RotationY(0.5f); Matrix viewMatrix = Matrix.Translation(0, 0, 5.0f); const float fov = 0.8f; Matrix projectionMatrix = Matrix.PerspectiveFovLH(fov, ClientSize.Width / (float)ClientSize.Height, 0.1f, 1000.0f); effect.GetVariableByName("finalMatrix").AsMatrix().SetMatrix(worldMatrix * viewMatrix * projectionMatrix); }
public void BuildPSO(Device3 device, GraphicsCommandList commandList) { Projection = Matrix.PerspectiveFovLH((float)Math.PI / 3f, 4f / 3f, 1, 1000); View = Matrix.LookAtLH(new Vector3(10 * (float)Math.Sin(rotation), 5, 10 * (float)Math.Cos(rotation)), Vector3.Zero, Vector3.UnitY); World = Matrix.Translation(-2.5f, -2.5f, -2.5f); DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _perPassViewHeap = device.CreateDescriptorHeap(cbvHeapDesc); RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.All, new RootDescriptor(0, 0), RootParameterType.ConstantBufferView) }; // Create an empty root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters); _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/Untextured.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/Untextured.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/Untextured.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/Untextured.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 12, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = _rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D24_UNorm_S8_UInt, DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; _pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { //Front new Vertex() { Position = new Vector3(0, 0, 0), Color = new Vector4(0, 0, 1, 1) }, new Vertex() { Position = new Vector3(0, 5, 0), Color = new Vector4(0, 0, 1, 1) }, new Vertex() { Position = new Vector3(5, 0, 0), Color = new Vector4(0, 0, 1, 1) }, new Vertex() { Position = new Vector3(5, 5, 0), Color = new Vector4(0, 0, 1, 1) }, //Back new Vertex() { Position = new Vector3(0, 0, 5), Color = new Vector4(0, 0, 1, 1) }, new Vertex() { Position = new Vector3(0, 5, 5), Color = new Vector4(0, 0, 1, 1) }, new Vertex() { Position = new Vector3(5, 0, 5), Color = new Vector4(0, 0, 1, 1) }, new Vertex() { Position = new Vector3(5, 5, 5), Color = new Vector4(0, 0, 1, 1) }, //Left new Vertex() { Position = new Vector3(0, 0, 0), Color = new Vector4(0, 1, 0, 1) }, new Vertex() { Position = new Vector3(0, 5, 0), Color = new Vector4(0, 1, 0, 1) }, new Vertex() { Position = new Vector3(0, 0, 5), Color = new Vector4(0, 1, 0, 1) }, new Vertex() { Position = new Vector3(0, 5, 5), Color = new Vector4(0, 1, 0, 1) }, //Right new Vertex() { Position = new Vector3(5, 0, 0), Color = new Vector4(0, 1, 0, 1) }, new Vertex() { Position = new Vector3(5, 5, 0), Color = new Vector4(0, 1, 0, 1) }, new Vertex() { Position = new Vector3(5, 0, 5), Color = new Vector4(0, 1, 0, 1) }, new Vertex() { Position = new Vector3(5, 5, 5), Color = new Vector4(0, 1, 0, 1) }, //Top new Vertex() { Position = new Vector3(0, 0, 0), Color = new Vector4(1, 0, 0, 1) }, new Vertex() { Position = new Vector3(0, 0, 5), Color = new Vector4(1, 0, 0, 1) }, new Vertex() { Position = new Vector3(5, 0, 0), Color = new Vector4(1, 0, 0, 1) }, new Vertex() { Position = new Vector3(5, 0, 5), Color = new Vector4(1, 0, 0, 1) }, //Bottom new Vertex() { Position = new Vector3(0, 5, 0), Color = new Vector4(1, 0, 0, 1) }, new Vertex() { Position = new Vector3(0, 5, 5), Color = new Vector4(1, 0, 0, 1) }, new Vertex() { Position = new Vector3(5, 5, 0), Color = new Vector4(1, 0, 0, 1) }, new Vertex() { Position = new Vector3(5, 5, 5), Color = new Vector4(1, 0, 0, 1) } }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = _vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); _vertexBuffer.Unmap(0); _indicies = new int[] { 0, 1, 2, 3, 2, 1, 6, 5, 4, 5, 6, 7, 10, 9, 8, 9, 10, 11, 12, 13, 14, 15, 14, 13, 18, 17, 16, 17, 18, 19, 20, 21, 22, 23, 22, 21 }; int indBufferSize = Utilities.SizeOf(_indicies); _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead); IntPtr pIndBegin = _indexBuffer.Map(0); Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length); _indexBuffer.Unmap(0); _indexBufferView = new IndexBufferView() { BufferLocation = _indexBuffer.GPUVirtualAddress, Format = Format.R32_UInt, SizeInBytes = indBufferSize }; // Initialize the vertex buffer view. _vertexBufferView = new VertexBufferView { BufferLocation = _vertexBuffer.GPUVirtualAddress, StrideInBytes = Utilities.SizeOf <Vertex>(), SizeInBytes = vertexBufferSize }; _perPassBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <PerPass>()), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = _perPassBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <PerPass>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc, _perPassViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. _perPassPointer = _perPassBuffer.Map(0); Utilities.Write(_perPassPointer, ref buffer); _resources = new[] { new GraphicsResource() { Resource = _perPassBuffer, Register = 0, type = ResourceType.ConstantBufferView } }; }
public static void ResizeDevice(Size newSize, bool fullScreen) { //OnDeviceSuspend(EventArgs.Empty); backBuffer.Dispose(); renderView.Dispose(); vertices.Dispose(); indices.Dispose(); rv.Dispose(); device.ClearState(); SwapChainDescription swapChainDesc = swapChain.Description; Output output = factory.GetAdapter(0).GetOutput(0); var modes = output.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Scaling | DisplayModeEnumerationFlags.Interlaced); ModeDescription desc2 = modes[modes.Count - 1]; ModeDescription result2; output.GetClosestMatchingMode(device, desc2, out result2); //swapChain.SetFullScreenState(true, null); Result result; // swapChain.ResizeTarget(new ModeDescription(result2.Width, result2.Height, result2.RefreshRate, result2.Format)); swapChain.SetFullScreenState(fullScreen, null); result = swapChain.ResizeBuffers(swapChainDesc.BufferCount, result2.Width, result2.Height, result2.Format, SwapChainFlags.AllowModeSwitch); backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0); renderView = new RenderTargetView(device, backBuffer); rv = new RenderTargetView(device, rtTex); //Console.WriteLine(device.Rasterizer.State.ToString()); RasterizerStateDescription rDesc = new RasterizerStateDescription() { CullMode = CullMode.None, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsAntialiasedLineEnabled = false, IsFrontCounterclockwise = true, //IsMultisampleEnabled = true, }; RasterizerState rState = RasterizerState.FromDescription(device, rDesc); device.Rasterizer.State = rState; device.Rasterizer.SetViewports(new Viewport(0, 0, size.Width, size.Height, 0.0f, 1.0f)); //stereoizedTexture = Make3D(sourceTexture); //srv.Dispose(); //srv = new ShaderResourceView(device, stereoizedTexture); //effect.GetVariableByName("tDiffuse").AsResource().SetResource(srv); device.OutputMerger.SetTargets(renderView); BuildQuad(); //OnDeviceResize(new ResizeEventArgs(previousSize, newSize, fullScreen)); //OnDeviceResume(EventArgs.Empty); Console.WriteLine("here"); }
public void BuildPSO(Device3 device, GraphicsCommandList commandList) { buffer[0].World = Matrix.Translation(-2.5f, -2.5f, -2.5f); buffer[1].World = Matrix.Translation(2.5f, 2.5f, 2.5f); light = new Lighting { GlobalAmbientX = 1, GlobalAmbientY = 1, GlobalAmbientZ = 1, KaX = .1f, KaY = .1f, KaZ = .1f, KdX = .5f, KdY = .5f, KdZ = .5f, KeX = .25f, KeY = .25f, KeZ = .25f, KsX = .1f, KsY = .1f, KsZ = .1f, LightColorX = 1, LightColorY = 1, LightColorZ = 1, LightPositionX = 10, LightPositionY = 10, LightPositionZ = 10, shininess = 5 }; DescriptorHeapDescription srvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _srvDescriptorHeap = device.CreateDescriptorHeap(srvHeapDesc); //setup descriptor ranges DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 } }; //Get sampler state setup StaticSamplerDescription sampler = new StaticSamplerDescription() { Filter = Filter.MinimumMinMagMipPoint, AddressU = TextureAddressMode.Border, AddressV = TextureAddressMode.Border, AddressW = TextureAddressMode.Border, MipLODBias = 0, MaxAnisotropy = 0, ComparisonFunc = Comparison.Never, BorderColor = StaticBorderColor.TransparentBlack, MinLOD = 0.0f, MaxLOD = float.MaxValue, ShaderRegister = 0, RegisterSpace = 0, ShaderVisibility = ShaderVisibility.Pixel, }; Projection = Matrix.PerspectiveFovLH((float)Math.PI / 3f, 4f / 3f, 1, 1000); View = Matrix.LookAtLH(new Vector3(10 * (float)Math.Sin(rotation), 5, 10 * (float)Math.Cos(rotation)), Vector3.Zero, Vector3.UnitY); World = Matrix.Translation(-2.5f, -2.5f, -2.5f); DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _objectViewHeap = device.CreateDescriptorHeap(cbvHeapDesc); _lightingViewHeap = device.CreateDescriptorHeap(cbvHeapDesc); RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges), new RootParameter(ShaderVisibility.All, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.All, new RootDescriptor(2, 0), RootParameterType.ConstantBufferView) }; // Create an empty root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler }); _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitPixel.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitPixel.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitPixel.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitPixel.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = _rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D24_UNorm_S8_UInt, DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; _pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { //Front new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitZ }, //Back new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitZ }, //Left new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitX }, //Right new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitX }, //Top new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitY }, //Bottom new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitY } }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = _vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); _vertexBuffer.Unmap(0); _indicies = new int[] { 0, 1, 2, 3, 2, 1, 6, 5, 4, 5, 6, 7, 10, 9, 8, 9, 10, 11, 12, 13, 14, 15, 14, 13, 18, 17, 16, 17, 18, 19, 20, 21, 22, 23, 22, 21 }; int indBufferSize = Utilities.SizeOf(_indicies); _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead); IntPtr pIndBegin = _indexBuffer.Map(0); Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length); _indexBuffer.Unmap(0); _indexBufferView = new IndexBufferView() { BufferLocation = _indexBuffer.GPUVirtualAddress, Format = Format.R32_UInt, SizeInBytes = indBufferSize }; // Initialize the vertex buffer view. _vertexBufferView = new VertexBufferView { BufferLocation = _vertexBuffer.GPUVirtualAddress, StrideInBytes = Utilities.SizeOf <Vertex>(), SizeInBytes = vertexBufferSize }; _objectBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(((Utilities.SizeOf <ObjectData>() + 255) & ~255) * 2), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = _objectBuffer.GPUVirtualAddress, SizeInBytes = ((Utilities.SizeOf <ObjectData>() + 255) & ~255) * 2 }; device.CreateConstantBufferView(cbvDesc, _objectViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. _objectPointer = _objectBuffer.Map(0); _lightingBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <Lighting>()), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc2 = new ConstantBufferViewDescription() { BufferLocation = _objectBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <Lighting>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc2, _lightingViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. _lightingPointer = _lightingBuffer.Map(0); Utilities.Write(_lightingPointer, ref light); Resource textureUploadHeap; // Create the texture. // Describe and create a Texture2D. ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight); _texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination); long uploadBufferSize = GetRequiredIntermediateSize(device, _texture, 0, 1); // Create the GPU upload buffer. textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight), ResourceStates.GenericRead); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. byte[] textureData = GenerateTextureData(); GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned); IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0); textureUploadHeap.WriteToSubresource(0, null, ptr, 4 * textureWidth, textureData.Length); handle.Free(); commandList.CopyTextureRegion(new TextureCopyLocation(_texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null); commandList.ResourceBarrierTransition(_texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource); // Describe and create a SRV for the texture. ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription() { Shader4ComponentMapping = ComponentMapping(0, 1, 2, 3), Format = textureDesc.Format, Dimension = ShaderResourceViewDimension.Texture2D, }; srvDesc.Texture2D.MipLevels = 1; device.CreateShaderResourceView(_texture, srvDesc, _srvDescriptorHeap.CPUDescriptorHandleForHeapStart); _resources = new[] { new GraphicsResource() { Heap = _srvDescriptorHeap, Register = 0, type = ResourceType.DescriptorTable }, new GraphicsResource() { Resource = _objectBuffer, Register = 2, type = ResourceType.ConstantBufferView }, new GraphicsResource() { Resource = _lightingBuffer, Register = 1, type = ResourceType.ConstantBufferView } }; }
public bool Initialize(DSystemConfiguration configuration, IntPtr windowHandle) { try { #region Environment Configuration // Store the vsync setting. VerticalSyncEnabled = DSystemConfiguration.VerticalSyncEnabled; // Create a DirectX graphics interface factory. var factory = new Factory1(); // Use the factory to create an adapter for the primary graphics interface (video card). var adapter = factory.GetAdapter1(0); // Get the primary adapter output (monitor). var monitor = adapter.GetOutput(0); // Get modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). var modes = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced); // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the the refresh rate for that monitor, if vertical sync is enabled. // Otherwise we use maximum refresh rate. var rational = new Rational(0, 1); if (VerticalSyncEnabled) { foreach (var mode in modes) { if (mode.Width == configuration.Width && mode.Height == configuration.Height) { rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator); break; } } } // Get the adapter (video card) description. var adapterDescription = adapter.Description; // Store the dedicated video card memory in megabytes. VideoCardMemory = adapterDescription.DedicatedVideoMemory >> 10 >> 10; // Convert the name of the video card to a character array and store it. VideoCardDescription = adapterDescription.Description.Trim('\0'); // Release the adapter output. monitor.Dispose(); // Release the adapter. adapter.Dispose(); // Release the factory. factory.Dispose(); #endregion #region Initialize swap chain and d3d device // Initialize the swap chain description. var swapChainDesc = new SwapChainDescription() { // Set to a single back buffer. BufferCount = 1, // Set the width and height of the back buffer. ModeDescription = new ModeDescription(configuration.Width, configuration.Height, rational, Format.R8G8B8A8_UNorm) { Scaling = DisplayModeScaling.Unspecified, ScanlineOrdering = DisplayModeScanlineOrder.Unspecified }, // Set the usage of the back buffer. Usage = Usage.RenderTargetOutput, // Set the handle for the window to render to. OutputHandle = windowHandle, // Turn multisampling off. SampleDescription = new SampleDescription(1, 0), // Set to full screen or windowed mode. IsWindowed = !DSystemConfiguration.FullScreen, // Don't set the advanced flags. Flags = SwapChainFlags.None, // Discard the back buffer content after presenting. SwapEffect = SwapEffect.Discard }; // Create the swap chain, Direct3D device, and Direct3D device context. SharpDX.Direct3D11.Device device; SwapChain swapChain; SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain); Device = device; SwapChain = swapChain; DeviceContext = device.ImmediateContext; #endregion #region Initialize buffers // Get the pointer to the back buffer. var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0); // Create the render target view with the back buffer pointer. RenderTargetView = new RenderTargetView(device, backBuffer); // Release pointer to the back buffer as we no longer need it. backBuffer.Dispose(); // Initialize and set up the description of the depth buffer. var depthBufferDesc = new Texture2DDescription() { Width = configuration.Width, Height = configuration.Height, MipLevels = 1, ArraySize = 1, Format = Format.D24_UNorm_S8_UInt, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; // Create the texture for the depth buffer using the filled out description. DepthStencilBuffer = new Texture2D(device, depthBufferDesc); #endregion #region Initialize Depth Enabled Stencil // Initialize and set up the description of the stencil state. var depthStencilDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, // Stencil operation if pixel front-facing. FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, // Stencil operation if pixel is back-facing. BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; // Create the depth stencil state. DepthStencilState = new DepthStencilState(Device, depthStencilDesc); // Set the depth stencil state. DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1); #endregion #region Initialize Output Merger // Initialize and set up the depth stencil view. var depthStencilViewDesc = new DepthStencilViewDescription() { Format = Format.D24_UNorm_S8_UInt, Dimension = DepthStencilViewDimension.Texture2D, Texture2D = new DepthStencilViewDescription.Texture2DResource() { MipSlice = 0 } }; // Create the depth stencil view. DepthStencilView = new DepthStencilView(Device, DepthStencilBuffer, depthStencilViewDesc); // Bind the render target view and depth stencil buffer to the output render pipeline. DeviceContext.OutputMerger.SetTargets(DepthStencilView, RenderTargetView); #endregion #region Initialize Raster State // Setup the raster description which will determine how and what polygon will be drawn. var rasterDesc = new RasterizerStateDescription() { IsAntialiasedLineEnabled = false, CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = .0f, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsFrontCounterClockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = .0f }; // Create the rasterizer state from the description we just filled out. RasterState = new RasterizerState(Device, rasterDesc); // Now set the rasterizer state. DeviceContext.Rasterizer.State = RasterState; // Setup a raster description which turns off back face culling. var rasterNoCullDesc = new RasterizerStateDescription() { IsAntialiasedLineEnabled = false, CullMode = CullMode.None, DepthBias = 0, DepthBiasClamp = .0f, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsFrontCounterClockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = .0f }; // Create the no culling rasterizer state. RasterStateNoCulling = new RasterizerState(Device, rasterNoCullDesc); #endregion #region Initialize Rasterizer ViewPort = new ViewportF(0.0f, 0.0f, (float)configuration.Width, (float)configuration.Height, 0.0f, 1.0f); // Setup and create the viewport for rendering. DeviceContext.Rasterizer.SetViewport(ViewPort); #endregion #region Initialize matrices // Setup and create the projection matrix. ProjectionMatrix = Matrix.PerspectiveFovLH((float)(Math.PI / 4), ((float)configuration.Width / configuration.Height), DSystemConfiguration.ScreenNear, DSystemConfiguration.ScreenDepth); // Initialize the world matrix to the identity matrix. WorldMatrix = Matrix.Identity; // Create an orthographic projection matrix for 2D rendering. OrthoMatrix = Matrix.OrthoLH(configuration.Width, configuration.Height, DSystemConfiguration.ScreenNear, DSystemConfiguration.ScreenDepth); #endregion #region Initialize Depth Disabled Stencil // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. Added in Tutorial 11 // The difference is that DepthEnable is set to false. // All other parameters are the same as the other depth stencil state. var depthDisabledStencilDesc = new DepthStencilStateDescription() { IsDepthEnabled = false, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, // Stencil operation if pixel front-facing. FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, // Stencil operation if pixel is back-facing. BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; // Create the depth stencil state. DepthDisabledStencilState = new DepthStencilState(Device, depthDisabledStencilDesc); #endregion #region Initialize Blend States // Create an alpha enabled blend state description. var blendStateDesc = new BlendStateDescription(); blendStateDesc.RenderTarget[0].IsBlendEnabled = true; blendStateDesc.RenderTarget[0].SourceBlend = BlendOption.One; blendStateDesc.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDesc.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDesc.RenderTarget[0].SourceAlphaBlend = BlendOption.One; blendStateDesc.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero; blendStateDesc.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; blendStateDesc.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; // Create the blend state using the description. AlphaEnableBlendingState = new BlendState(device, blendStateDesc); // Modify the description to create an disabled blend state description. blendStateDesc.RenderTarget[0].IsBlendEnabled = false; // Create the blend state using the description. AlphaDisableBlendingState = new BlendState(device, blendStateDesc); #endregion return(true); } catch (Exception) { return(false); } }
internal static void Modify(RasterizerId id, RasterizerStateDescription desc) { RasterizerStates.Data[id.Index] = desc; InitRasterizerState(id); }
// Methods public bool Initialize(DSystemConfiguration configuration, IntPtr windowHandle) { try { // Store the vsync setting. VerticalSyncEnabled = DSystemConfiguration.VerticalSyncEnabled; // Create a DirectX graphics interface factory. var factory = new Factory1(); // Use the factory to create an adapter for the primary graphics interface (video card). var adapter = factory.GetAdapter1(0); // Get the primary adapter output (monitor). var monitor = adapter.GetOutput(0); // Get modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). var modes = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced); // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the the refresh rate for that monitor, if vertical sync is enabled. // Otherwise we use maximum refresh rate. var rational = new Rational(0, 1); if (VerticalSyncEnabled) { foreach (var mode in modes) { if (mode.Width == configuration.Width && mode.Height == configuration.Height) { rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator); break; } } } // Get the adapter (video card) description. var adapterDescription = adapter.Description; // Store the dedicated video card memory in megabytes. VideoCardMemory = adapterDescription.DedicatedVideoMemory >> 10 >> 10; // Convert the name of the video card to a character array and store it. VideoCardDescription = adapterDescription.Description; // Release the adapter output. monitor.Dispose(); // Release the adapter. adapter.Dispose(); // Release the factory. factory.Dispose(); // Initialize the swap chain description. var swapChainDesc = new SwapChainDescription() { // Set to a single back buffer. BufferCount = 1, // Set the width and height of the back buffer. ModeDescription = new ModeDescription(configuration.Width, configuration.Height, rational, Format.R8G8B8A8_UNorm), // Set the usage of the back buffer. Usage = Usage.RenderTargetOutput, // Set the handle for the window to render to. OutputHandle = windowHandle, // Turn multisampling off. SampleDescription = new SampleDescription(1, 0), // Set to full screen or windowed mode. IsWindowed = !DSystemConfiguration.FullScreen, // Don't set the advanced flags. Flags = SwapChainFlags.None, // Discard the back buffer content after presenting. SwapEffect = SwapEffect.Discard }; // Create the swap chain, Direct3D device, and Direct3D device context. SharpDX.Direct3D11.Device device; SwapChain swapChain; SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain); Device = device; SwapChain = swapChain; DeviceContext = device.ImmediateContext; // Get the pointer to the back buffer. var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0); // Create the render target view with the back buffer pointer. RenderTargetView = new RenderTargetView(device, backBuffer); // Release pointer to the back buffer as we no longer need it. backBuffer.Dispose(); // Initialize and set up the description of the depth buffer. var depthBufferDesc = new Texture2DDescription() { Width = configuration.Width, Height = configuration.Height, MipLevels = 1, ArraySize = 1, Format = Format.D24_UNorm_S8_UInt, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; // Create the texture for the depth buffer using the filled out description. DepthStencilBuffer = new Texture2D(device, depthBufferDesc); // Initialize and set up the description of the stencil state. var depthStencilDesc = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, DepthComparison = Comparison.Less, IsStencilEnabled = true, StencilReadMask = 0xFF, StencilWriteMask = 0xFF, // Stencil operation if pixel front-facing. FrontFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Increment, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always }, // Stencil operation if pixel is back-facing. BackFace = new DepthStencilOperationDescription() { FailOperation = StencilOperation.Keep, DepthFailOperation = StencilOperation.Decrement, PassOperation = StencilOperation.Keep, Comparison = Comparison.Always } }; // Create the depth stencil state. DepthStencilState = new DepthStencilState(Device, depthStencilDesc); // Set the depth stencil state. DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1); // Initialize and set up the depth stencil view. var depthStencilViewDesc = new DepthStencilViewDescription() { Format = Format.D24_UNorm_S8_UInt, Dimension = DepthStencilViewDimension.Texture2D, Texture2D = new DepthStencilViewDescription.Texture2DResource() { MipSlice = 0 } }; // Create the depth stencil view. DepthStencilView = new DepthStencilView(Device, DepthStencilBuffer, depthStencilViewDesc); // Bind the render target view and depth stencil buffer to the output render pipeline. DeviceContext.OutputMerger.SetTargets(DepthStencilView, RenderTargetView); // Setup the raster description which will determine how and what polygon will be drawn. var rasterDesc = new RasterizerStateDescription() { IsAntialiasedLineEnabled = false, CullMode = CullMode.Back, DepthBias = 0, DepthBiasClamp = .0f, IsDepthClipEnabled = true, FillMode = FillMode.Solid, IsFrontCounterClockwise = false, IsMultisampleEnabled = false, IsScissorEnabled = false, SlopeScaledDepthBias = .0f }; // Create the rasterizer state from the description we just filled out. RasterState = new RasterizerState(Device, rasterDesc); // Now set the rasterizer state. DeviceContext.Rasterizer.State = RasterState; // Setup and create the viewport for rendering. DeviceContext.Rasterizer.SetViewport(0, 0, configuration.Width, configuration.Height, 0, 1); return(true); } catch { return(false); } }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = unchecked ((int)uint.MaxValue), PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for shadow map pass. // var smapPsoDesc = opaquePsoDesc.Copy(); smapPsoDesc.RasterizerState.DepthBias = 100000; smapPsoDesc.RasterizerState.DepthBiasClamp = 0.0f; smapPsoDesc.RasterizerState.SlopeScaledDepthBias = 1.0f; smapPsoDesc.VertexShader = _shaders["shadowVS"]; smapPsoDesc.PixelShader = _shaders["shadowOpaquePS"]; // Shadow map pass does not have a render target. smapPsoDesc.RenderTargetFormats[0] = Format.Unknown; smapPsoDesc.RenderTargetCount = 0; _psos["shadow_opaque"] = Device.CreateGraphicsPipelineState(smapPsoDesc); // // PSO for debug layer. // var debugPsoDesc = opaquePsoDesc.Copy(); debugPsoDesc.VertexShader = _shaders["debugVS"]; debugPsoDesc.PixelShader = _shaders["debugPS"]; _psos["debug"] = Device.CreateGraphicsPipelineState(debugPsoDesc); // // PSO for sky. // GraphicsPipelineStateDescription skyPsoDesc = opaquePsoDesc.Copy(); // The camera is inside the sky sphere, so just turn off culling. skyPsoDesc.RasterizerState.CullMode = CullMode.None; // Make sure the depth function is LESS_EQUAL and not just LESS. // Otherwise, the normalized depth values at z = 1 (NDC) will // fail the depth test if the depth buffer was cleared to 1. skyPsoDesc.DepthStencilState.DepthComparison = Comparison.LessEqual; skyPsoDesc.VertexShader = _shaders["skyVS"]; skyPsoDesc.PixelShader = _shaders["skyPS"]; _psos["sky"] = Device.CreateGraphicsPipelineState(skyPsoDesc); }