/// <summary> /// Initializes a new instance of the <see cref="WorldViewProjection"/> class. /// </summary> /// <param name="graphics">The graphics interface to use.</param> public Light(GorgonGraphics graphics) { _lightData[0].Attenuation = 6.0f; _lightData[0].LightColor = GorgonColor.White; _lightData[0].LightPosition = Vector3.Zero; _lightData[0].SpecularColor = GorgonColor.White; _lightData[0].SpecularPower = 512.0f; _buffer = graphics.Buffers.CreateConstantBuffer("LightBuffer", new GorgonConstantBufferSettings { SizeInBytes = LightData.Size * _lightData.Length, Usage = BufferUsage.Default }); _lightStore = new GorgonDataStream(_buffer.SizeInBytes); unsafe { DirectAccess.ZeroMemory(_lightStore.UnsafePointer, _buffer.SizeInBytes); var data = (LightData *)_lightStore.UnsafePointer; * data = _lightData[0]; } _buffer.Update(_lightStore); graphics.Shaders.PixelShader.ConstantBuffers[1] = _buffer; }
/// <summary> /// Initializes a new instance of the <see cref="WorldViewProjection"/> class. /// </summary> /// <param name="graphics">The graphics interface to use.</param> public WorldViewProjection(GorgonGraphics graphics) { Matrix dummy = Matrix.Identity; _projViewBuffer = graphics.Buffers.CreateConstantBuffer("WVPBuffer", new GorgonConstantBufferSettings { SizeInBytes = DirectAccess.SizeOf <ViewProjectionData>(), Usage = BufferUsage.Default }); _viewProj = new ViewProjectionData { Projection = Matrix.Identity, View = Matrix.Identity, ViewProjection = Matrix.Identity }; _projViewBuffer.Update(ref _viewProj); _worldBuffer = graphics.Buffers.CreateConstantBuffer("WorldBuffer", ref dummy, BufferUsage.Default); _camData.CameraLookAt = new Vector3(0, 0, -1.0f); _camData.CameraUp = new Vector3(0, 1, 0); _cameraBuffer = graphics.Buffers.CreateConstantBuffer("CameraBuffer", ref _camData, BufferUsage.Default); graphics.Shaders.VertexShader.ConstantBuffers[0] = _projViewBuffer; graphics.Shaders.VertexShader.ConstantBuffers[1] = _worldBuffer; graphics.Shaders.PixelShader.ConstantBuffers[0] = _cameraBuffer; }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (!_disposed) { if (disposing) { if (Passes[1].PixelShader != null) { Passes[1].PixelShader.Dispose(); } if (_displacementBuffer != null) { _displacementBuffer.Dispose(); } FreeResources(); } _displacementBuffer = null; Passes[1].PixelShader = null; _disposed = true; } base.Dispose(disposing); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// </remarks> protected override void OnInitialize() { base.OnInitialize(); _xOffsets = new Vector4[13]; _yOffsets = new Vector4[13]; _kernel = new float[13]; _blurBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DGaussianBlurEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = DirectAccess.SizeOf <Vector4>() * _xOffsets.Length }); _blurStaticBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DGaussianBlurEffect Static Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = DirectAccess.SizeOf <Vector4>() * (_kernel.Length + 1) }); _blurKernelStream = new GorgonDataStream(_blurStaticBuffer.SizeInBytes); Passes[0].PixelShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.PS.GaussBlur", "GorgonPixelShaderGaussBlur", "#GorgonInclude \"Gorgon2DShaders\""); UpdateKernel(); _blurSprite = Gorgon2D.Renderables.CreateSprite("Gorgon2DGaussianBlurEffect Sprite", new GorgonSpriteSettings { Size = BlurRenderTargetsSize }); _blurSprite.BlendingMode = BlendingMode.None; _blurSprite.SmoothingMode = SmoothingMode.Smooth; _blurSprite.TextureRegion = new RectangleF(0, 0, 1, 1); }
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> public void Dispose() { for (int i = 0; i < _volumeRtSections.Length; ++i) { _volumeSections[i]?.Dispose(); _volumeRtSections[i]?.Dispose(); } _textureView = null; _cube?.Dispose(); _volumeScaleFactor?.Dispose(); _volumeRayParams?.Dispose(); _cubeTransform?.Dispose(); _cubePosShader?.Dispose(); _cubeDirShader?.Dispose(); _cubeVs?.Dispose(); _inputLayout?.Dispose(); _cubeTransform = null; _inputLayout = null; _cube = null; _volumeScaleFactor = null; _volumeRayParams = null; _cubePosShader = null; _cubeDirShader = null; _cubeVs = null; }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (!_disposed) { if (disposing) { if (Passes[0].PixelShader != null) { Passes[0].PixelShader.Dispose(); } Passes[0].PixelShader = null; if (_1BitBuffer != null) { _1BitBuffer.Dispose(); _1BitBuffer = null; } } _disposed = true; } base.Dispose(disposing); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (!_disposed) { if (disposing) { if (_linearDodgeBurn != null) { _linearDodgeBurn.Dispose(); } if (_dodgeBurn != null) { _dodgeBurn.Dispose(); } if (_burnDodgeBuffer != null) { _burnDodgeBuffer.Dispose(); } } _burnDodgeBuffer = null; _linearDodgeBurn = null; _dodgeBurn = null; _disposed = true; } base.Dispose(disposing); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// <para>When creating a custom effect, use this method to initialize the effect. Do not put initialization code in the effect constructor.</para> /// </remarks> protected override void OnInitialize() { base.OnInitialize(); Passes[0].PixelShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.Invert.PS", "GorgonPixelShaderInvert", "#GorgonInclude \"Gorgon2DShaders\""); _invertBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DInvertEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = 16 }); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// <para>When creating a custom effect, use this method to initialize the effect. Do not put initialization code in the effect constructor.</para> /// </remarks> protected override void OnInitialize() { base.OnInitialize(); Passes[0].PixelShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.SobelEdgeDetect.PS", "GorgonPixelShaderSobelEdge", "#GorgonInclude \"Gorgon2DShaders\""); _sobelBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DSobelEdgeDetectEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = DirectAccess.SizeOf <Settings>() }); _settings = new Settings(Color.Black, Vector2.Zero, 0.75f); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// <para>When creating a custom effect, use this method to initialize the effect. Do not put initialization code in the effect constructor.</para> /// </remarks> protected override void OnInitialize() { base.OnInitialize(); _sharpenShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.SharpenEmboss.PS", "GorgonPixelShaderSharpen", "#GorgonInclude \"Gorgon2DShaders\""); _embossShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.SharpenEmboss.PS", "GorgonPixelShaderEmboss", "#GorgonInclude \"Gorgon2DShaders\""); _sharpenEmbossBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DSharpenEmbossEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = 16 }); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// <para>When creating a custom effect, use this method to initialize the effect. Do not put initialization code in the effect constructor.</para> /// </remarks> protected override void OnInitialize() { base.OnInitialize(); Passes[0].PixelShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.Posterized.PS", "GorgonPixelShaderPosterize", "#GorgonInclude \"Gorgon2DShaders\""); _posterizeBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DPosterizedEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = 16 }); _settings = new Settings(false, 1.0f, 8); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// </remarks> protected override void OnInitialize() { base.OnInitialize(); _linearDodgeBurn = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.BurnDodge.PS", "GorgonPixelShaderLinearBurnDodge", "#GorgonInclude \"Gorgon2DShaders\""); _dodgeBurn = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.BurnDodge.PS", "GorgonPixelShaderBurnDodge", "#GorgonInclude \"Gorgon2DShaders\""); _burnDodgeBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DBurnDodgeEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = 16 }); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// </remarks> protected override void OnInitialize() { base.OnInitialize(); Passes[0].PixelShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.1Bit.PS", "GorgonPixelShader1Bit", "#GorgonInclude \"Gorgon2DShaders\""); _1BitBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2D1BitEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = Settings.SizeInBytes }); _settings = new Settings(new GorgonRangeF(0.5f, 1.0f), false, false, true); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// <para>When creating a custom effect, use this method to initialize the effect. Do not put initialization code in the effect constructor.</para> /// </remarks> protected override void OnInitialize() { base.OnInitialize(); Passes[0].PixelShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.Wave.PS", "GorgonPixelShaderWaveEffect", "#GorgonInclude \"Gorgon2DShaders\""); _waveBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DWaveEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = DirectAccess.SizeOf <Settings>() }); _settings = new Settings(10.0f, 50.0f, 0.0f, 100.0f, WaveType.Horizontal); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// <para>When creating a custom effect, use this method to initialize the effect. Do not put initialization code in the effect constructor.</para> /// </remarks> protected override void OnInitialize() { base.OnInitialize(); _point = Gorgon2D.Renderables.CreatePoint("Effect.OldFilm.DustPoint", Vector2.Zero, GorgonColor.Black); // Create pixel shader. Passes[0].PixelShader = Graphics.Shaders.CreateShader <GorgonPixelShader>("Effect.OldFilm.PS", "GorgonPixelShaderFilmGrain", Encoding.UTF8.GetString(Resources.FilmGrain)); _timingBuffer = Graphics.Buffers.CreateConstantBuffer("Effect.OldFilm.TimingBuffer", new GorgonConstantBufferSettings { SizeInBytes = 16 }); _scratchBuffer = Graphics.Buffers.CreateConstantBuffer("Effect.OldFilm.ScratchSettingsBuffer", new GorgonConstantBufferSettings { SizeInBytes = DirectAccess.SizeOf <ScratchSettings>() }); _sepiaBuffer = Graphics.Buffers.CreateConstantBuffer("Effect.OldFilm.SepaSettingsBuffer", new GorgonConstantBufferSettings { SizeInBytes = DirectAccess.SizeOf <SepiaSettings>() }); DirtPercent = 5; DirtAmount = 10; _scratchSettings = new ScratchSettings { ScratchIntensity = 0.49f, ScratchScrollSpeed = 0.01f, ScratchVisibleTime = 0.003f, ScratchWidth = 0.01f }; _sepiaSettings = new SepiaSettings { SepiaDesaturationAmount = 0.0f, SepiaToneAmount = 0.5f, SepiaLightColor = new GorgonColor(1, 0.9f, 0.65f, 1.0f), SepiaDarkColor = new GorgonColor(0.2f, 0.102f, 0, 1.0f) }; }
/// <summary> /// Initializes a new instance of the <see cref="Sobel"/> class. /// </summary> /// <param name="graphics">The graphics interface to use.</param> /// <param name="sobelShader">The shader for sobel edge detection.</param> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="graphics"/>, or the <paramref name="sobelShader"/> parameter is <b>null</b>.</exception> public Sobel(GorgonGraphics graphics, GorgonComputeShader sobelShader) { if (sobelShader == null) { throw new ArgumentNullException(nameof(sobelShader)); } _compute = new GorgonComputeEngine(graphics); _sobelData = new GorgonConstantBuffer(graphics, new GorgonConstantBufferInfo("SobelData") { Usage = ResourceUsage.Dynamic, SizeInBytes = 16 }); _dispatchBuilder = new GorgonDispatchCallBuilder(); _dispatchBuilder.ConstantBuffer(_sobelData.GetView()) .ComputeShader(sobelShader); }
/// <summary> /// Function called when the effect is being initialized. /// </summary> /// <remarks> /// Use this method to set up the effect upon its creation. For example, this method could be used to create the required shaders for the effect. /// </remarks> protected override void OnInitialize() { base.OnInitialize(); Passes[1].PixelShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.2D.DisplacementDecoder.PS", "GorgonPixelShaderDisplacementDecoder", "#GorgonInclude \"Gorgon2DShaders\""); _displacementBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DDisplacementEffect Constant Buffer", new GorgonConstantBufferSettings { SizeInBytes = 16 }); _displacementSprite = Gorgon2D.Renderables.CreateSprite("Gorgon2DDisplacementEffect Sprite", new GorgonSpriteSettings { Size = new Vector2(1) }); _displacementSprite.BlendingMode = BlendingMode.None; _displacementSprite.SmoothingMode = SmoothingMode.Smooth; // Set the drawing for rendering the displacement map. Passes[1].RenderAction = pass => _displacementSprite.Draw(); }
/// <summary> /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (!_disposed) { if (disposing) { FreeResources(); if (Passes[0].PixelShader != null) { Passes[0].PixelShader.Dispose(); Passes[0].PixelShader = null; } if (_timingBuffer != null) { _timingBuffer.Dispose(); _timingBuffer = null; } if (_scratchBuffer != null) { _scratchBuffer.Dispose(); _scratchBuffer = null; } if (_sepiaBuffer != null) { _sepiaBuffer.Dispose(); _sepiaBuffer = null; } } _disposed = true; } base.Dispose(disposing); }
/// <summary> /// Function to initialize the application. /// </summary> private static void Initialize() { _form = new FormMain(); _graphics = new GorgonGraphics(); _swapChain = _graphics.Output.CreateSwapChain("Swap", new GorgonSwapChainSettings { Window = _form, IsWindowed = true, DepthStencilFormat = BufferFormat.D24_UIntNormal_S8_UInt, Format = BufferFormat.R8G8B8A8_UIntNormal }); _renderer2D = _graphics.Output.Create2DRenderer(_swapChain); _font = _graphics.Fonts.CreateFont("AppFont", new GorgonFontSettings { FontFamilyName = "Calibri", FontStyle = FontStyle.Bold, FontHeightMode = FontHeightMode.Pixels, AntiAliasingMode = FontAntiAliasMode.AntiAlias, OutlineSize = 1, OutlineColor1 = Color.Black, Size = 16.0f }); _vertexShader = _graphics.Shaders.CreateShader <GorgonVertexShader>("VertexShader", "PrimVS", Resources.Shaders); _pixelShader = _graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "PrimPS", Resources.Shaders); _bumpShader = _graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "PrimPSBump", Resources.Shaders); _waterShader = _graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "PrimPSWaterBump", Resources.Shaders); _normalVertexShader = _graphics.Shaders.CreateShader <GorgonVertexShader>("NormalVertexShader", "NormalVS", Resources.Shaders); _normalPixelShader = _graphics.Shaders.CreateShader <GorgonPixelShader>("NormalPixelShader", "NormalPS", Resources.Shaders); _vertexLayout = _graphics.Input.CreateInputLayout("Vertex3D", typeof(Vertex3D), _vertexShader); _normalVertexLayout = _graphics.Input.CreateInputLayout("NormalVertex", new[] { new GorgonInputElement("SV_POSITION", BufferFormat.R32G32B32A32_Float, 0, 0, 0, false, 0), }, _normalVertexShader); _graphics.Shaders.VertexShader.Current = _vertexShader; _graphics.Shaders.PixelShader.Current = _pixelShader; _graphics.Input.Layout = _vertexLayout; _graphics.Input.PrimitiveType = PrimitiveType.TriangleList; _texture = _graphics.Textures.CreateTexture <GorgonTexture2D>("UVTexture", Resources.UV); _earf = _graphics.Textures.CreateTexture <GorgonTexture2D>("Earf", Resources.earthmap1k); _normalMap = _graphics.Textures.FromMemory <GorgonTexture2D>("RainNRM", Resources.Rain_Height_NRM, new GorgonCodecDDS()); _normalEarfMap = _graphics.Textures.FromMemory <GorgonTexture2D>("EarfNRM", Resources.earthbump1k_NRM, new GorgonCodecDDS()); _specMap = _graphics.Textures.FromMemory <GorgonTexture2D>("RainSPC", Resources.Rain_Height_SPEC, new GorgonCodecDDS()); _specEarfMap = _graphics.Textures.CreateTexture <GorgonTexture2D>("EarfSPC", Resources.earthspec1k); _cloudMap = _graphics.Textures.CreateTexture <GorgonTexture2D>("EarfClouds", Resources.earthcloudmap); _gorgNrm = _graphics.Textures.CreateTexture <GorgonTexture2D>("EarfClouds", Resources.normalmap); var depth = new GorgonDepthStencilStates { DepthComparison = ComparisonOperator.LessEqual, IsDepthEnabled = true, IsDepthWriteEnabled = true }; _graphics.Output.DepthStencilState.States = depth; _graphics.Output.SetRenderTarget(_swapChain, _swapChain.DepthStencilBuffer); _graphics.Rasterizer.States = GorgonRasterizerStates.CullBackFace; _graphics.Rasterizer.SetViewport(new GorgonViewport(0, 0, _form.ClientSize.Width, _form.ClientSize.Height, 0, 1.0f)); _graphics.Shaders.PixelShader.TextureSamplers[0] = GorgonTextureSamplerStates.LinearFilter; _wvp = new WorldViewProjection(_graphics); _wvp.UpdateProjection(75.0f, _form.ClientSize.Width, _form.ClientSize.Height); // When we resize, update the projection and viewport to match our client size. _form.Resize += (sender, args) => { _graphics.Rasterizer.SetViewport(new GorgonViewport(0, 0, _form.ClientSize.Width, _form.ClientSize.Height, 0, 1.0f)); _wvp.UpdateProjection(75.0f, _form.ClientSize.Width, _form.ClientSize.Height); }; var fnU = new Vector3(0.5f, 1.0f, 0); var fnV = new Vector3(1.0f, 1.0f, 0); Vector3 faceNormal; Vector3.Cross(ref fnU, ref fnV, out faceNormal); faceNormal.Normalize(); _triangle = new Triangle(_graphics, new Vertex3D { Position = new Vector4(-12.5f, -1.5f, 12.5f, 1), Normal = faceNormal, UV = new Vector2(0, 1.0f) }, new Vertex3D { Position = new Vector4(0, 24.5f, 12.5f, 1), Normal = faceNormal, UV = new Vector2(0.5f, 0.0f) }, new Vertex3D { Position = new Vector4(12.5f, -1.5f, 12.5f, 1), Normal = faceNormal, UV = new Vector2(1.0f, 1.0f) }) { Texture = _texture, Position = new Vector3(0, 0, 1.0f) }; _plane = new Plane(_graphics, new Vector2(25.0f, 25.0f), new RectangleF(0, 0, 1.0f, 1.0f), new Vector3(90, 0, 0), 32, 32) { Position = new Vector3(0, -1.5f, 1.0f), Texture = _texture }; _cube = new Cube(_graphics, new Vector3(1, 1, 1), new RectangleF(0, 0, 1.0f, 1.0f), new Vector3(45.0f, 0, 0), 1, 1) { Position = new Vector3(0, 0, 1.5f), Texture = _texture }; _sphere = new Sphere(_graphics, 1.0f, new RectangleF(0.0f, 0.0f, 1.0f, 1.0f), Vector3.Zero, 64, 64) { Position = new Vector3(-2.0f, 1.0f, 0.75f), Texture = _earf }; _clouds = new Sphere(_graphics, 5.175f, new RectangleF(0.0f, 0.0f, 1.0f, 1.0f), Vector3.Zero, 16, 16) { Position = new Vector3(10, 2, 9.5f), Texture = _cloudMap }; _icoSphere = new IcoSphere(_graphics, 5.0f, new RectangleF(0, 0, 1, 1), Vector3.Zero, 3) { Rotation = new Vector3(0, -45.0f, 0), Position = new Vector3(10, 2, 9.5f), Texture = _earf }; _graphics.Shaders.PixelShader.TextureSamplers[0] = new GorgonTextureSamplerStates { TextureFilter = TextureFilter.Linear, HorizontalAddressing = TextureAddressing.Wrap, VerticalAddressing = TextureAddressing.Wrap, DepthAddressing = TextureAddressing.Wrap, ComparisonFunction = ComparisonOperator.Always }; _graphics.Shaders.PixelShader.TextureSamplers[2] = new GorgonTextureSamplerStates { TextureFilter = TextureFilter.Linear, HorizontalAddressing = TextureAddressing.Wrap, VerticalAddressing = TextureAddressing.Wrap, DepthAddressing = TextureAddressing.Wrap, ComparisonFunction = ComparisonOperator.Always }; _graphics.Shaders.PixelShader.TextureSamplers[1] = new GorgonTextureSamplerStates { TextureFilter = TextureFilter.Linear, HorizontalAddressing = TextureAddressing.Wrap, VerticalAddressing = TextureAddressing.Wrap, DepthAddressing = TextureAddressing.Wrap, ComparisonFunction = ComparisonOperator.Always }; _material = new Material { UVOffset = Vector2.Zero, SpecularPower = 1.0f }; _materialBuffer = _graphics.Buffers.CreateConstantBuffer("uvOffset", ref _material, BufferUsage.Default); _graphics.Shaders.PixelShader.ConstantBuffers[2] = _materialBuffer; _light = new Light(_graphics); var lightPosition = new Vector3(1.0f, 1.0f, -1.0f); _light.UpdateLightPosition(ref lightPosition, 0); GorgonColor color = GorgonColor.White; _light.UpdateSpecular(ref color, 256.0f, 0); lightPosition = new Vector3(-5.0f, 5.0f, 8.0f); _light.UpdateLightPosition(ref lightPosition, 1); color = Color.Yellow; _light.UpdateColor(ref color, 1); _light.UpdateSpecular(ref color, 2048.0f, 1); _light.UpdateAttenuation(10.0f, 1); lightPosition = new Vector3(5.0f, 3.0f, 10.0f); _light.UpdateLightPosition(ref lightPosition, 2); color = Color.Red; _light.UpdateColor(ref color, 2); _light.UpdateAttenuation(16.0f, 2); var eye = Vector3.Zero; var lookAt = Vector3.UnitZ; var up = Vector3.UnitY; _wvp.UpdateViewMatrix(ref eye, ref lookAt, ref up); _cameraRotation = Vector2.Zero; Gorgon.PlugIns.LoadPlugInAssembly(Application.StartupPath + @"\Gorgon.Input.Raw.dll"); _input = GorgonInputFactory.CreateInputFactory("GorgonLibrary.Input.GorgonRawPlugIn"); _keyboard = _input.CreateKeyboard(_form); _mouse = _input.CreatePointingDevice(_form); _keyboard.KeyDown += (sender, args) => { if (args.Key == KeyboardKeys.L) { _lock = !_lock; } }; _mouse.PointingDeviceDown += Mouse_Down; _mouse.PointingDeviceUp += Mouse_Up; _mouse.PointingDeviceWheelMove += (sender, args) => { if (args.WheelDelta < 0) { _sensitivity -= 0.05f; if (_sensitivity < 0.05f) { _sensitivity = 0.05f; } } else if (args.WheelDelta > 0) { _sensitivity += 0.05f; if (_sensitivity > 2.0f) { _sensitivity = 2.0f; } } }; _mouse.PointingDeviceMove += (sender, args) => { if (!_mouse.Exclusive) { return; } var delta = args.RelativePosition; _cameraRotation.Y += delta.Y * _sensitivity; //((360.0f * 0.002f) * delta.Y.Sign()); _cameraRotation.X += delta.X * _sensitivity; //((360.0f * 0.002f) * delta.X.Sign()); _mouseStart = _mouse.Position; _mouse.RelativePosition = PointF.Empty; }; }
/// <summary> /// Function to initialize the application. /// </summary> private static void Initialize() { var depthFormat = BufferFormat.D24_UIntNormal_S8_UInt; // Depth buffer format. // Create our form. _mainForm = new formMain(); // Add a keybinding to switch to full screen or windowed. _mainForm.KeyDown += _mainForm_KeyDown; // Create the main graphics interface. Graphics = new GorgonGraphics(); // Validate depth buffer for this device. // Odds are good that if this fails, you should probably invest in a // better video card. Preferably something created after 2005. if (!Graphics.VideoDevice.SupportsDepthFormat(depthFormat)) { depthFormat = BufferFormat.D16_UIntNormal; if (Graphics.VideoDevice.SupportsDepthFormat(depthFormat)) { return; } GorgonDialogs.ErrorBox(_mainForm, "Video device does not support a 24 or 16 bit depth buffer."); return; } // Create a 1280x800 window with a depth buffer. // We can modify the resolution in the config file for the application, but // like other Gorgon examples, the default is 1280x800. _swap = Graphics.Output.CreateSwapChain("Main", new GorgonSwapChainSettings { Window = _mainForm, // Assign to our form. Format = BufferFormat.R8G8B8A8_UIntNormal, // Set up for 32 bit RGBA normalized display. Size = Settings.Default.Resolution, // Get the resolution from the config file. DepthStencilFormat = depthFormat, // Get our depth format. IsWindowed = Settings.Default.IsWindowed // Set up for windowed or full screen (depending on config file). }); // Center on the primary monitor. // This is necessary because we already created the window, so it'll be off center at this point. _mainForm.Location = new Point(Screen.PrimaryScreen.WorkingArea.Width / 2 - _mainForm.Width / 2, Screen.PrimaryScreen.WorkingArea.Height / 2 - _mainForm.Height / 2); // Handle any resizing. // This is here because the base graphics library will NOT handle state loss due to resizing. // This is up to the developer to handle. _swap.AfterSwapChainResized += _swap_Resized; // Create the 2D interface for our text. _2D = Graphics.Output.Create2DRenderer(_swap); // Create our shaders. // Our vertex shader. This is a simple shader, it just processes a vertex by multiplying it against // the world/view/projection matrix and spits it back out. _vertexShader = Graphics.Shaders.CreateShader <GorgonVertexShader>("VertexShader", "BoingerVS", Resources.Shader); // Our main pixel shader. This is a very simple shader, it just reads a texture and spits it back out. Has no // diffuse capability. _pixelShader = Graphics.Shaders.CreateShader <GorgonPixelShader>("PixelShader", "BoingerPS", Resources.Shader); // Our shadow shader for our ball "shadow". This is hard coded to send back black (R:0, G:0, B:0) at 50% opacity (A: 0.5). _pixelShaderShadow = Graphics.Shaders.CreateShader <GorgonPixelShader>("ShadowShader", "BoingerShadowPS", Resources.Shader); // Create the vertex input layout. // We need to create a layout for our vertex type because the shader won't know // how to interpret the data we're sending it otherwise. This is why we need a // vertex shader before we even create the layout. _inputLayout = Graphics.Input.CreateInputLayout("InputLayout", typeof(BoingerVertex), _vertexShader); // Create the view port. // This just tells the renderer how big our display is. var view = new GorgonViewport(0, 0, _mainForm.ClientSize.Width, _mainForm.ClientSize.Height, 0.0f, 1.0f); // Load our textures from the resources. // This contains our textures for the walls and ball. _texture = Graphics.Textures.CreateTexture <GorgonTexture2D>("PlaneTexture", Resources.Texture); // Set up our view matrix. // Move the camera (view matrix) back 2.2 units. This will give us enough room to see what's // going on. Matrix.Translation(0, 0, 2.2f, out _viewMatrix); // Set up our projection matrix. // This matrix is probably the cause of almost EVERY problem you'll ever run into in 3D programming. // Basically we're telling the renderer that we want to have a vertical FOV of 75 degrees, with the aspect ratio // based on our form width and height. The final values indicate how to distribute Z values across depth (tip: // it's not linear). _projMatrix = Matrix.PerspectiveFovLH((75.0f).Radians(), _mainForm.Width / (float)_mainForm.Height, 0.125f, 500.0f); // Create our constant buffer and backing store. // Our constant buffers are how we send data to our shaders. This one in particular will be responsible // for sending our world/view/projection matrix to the vertex shader. The stream we're creating after // the constant buffer is our system memory store for the data. Basically we write to the system // memory and then upload that data to the video card. This is very different from how things used to // work, but allows a lot more flexibility. _wvpBuffer = Graphics.Buffers.CreateConstantBuffer("WVPBuffer", new GorgonConstantBufferSettings { SizeInBytes = Matrix.SizeInBytes }); _wvpBufferStream = new GorgonDataStream(_wvpBuffer.SizeInBytes); // Create our planes. // Here's where we create the 2 planes for our rear wall and floor. We set the texture size to texel units // because that's how the video card expects them. However, it's a little hard to eyeball 0.67798223f by looking // at the texture image display, so we use the ToTexel function to determine our texel size. var textureSize = _texture.ToTexel(new Vector2(500, 500)); _planes = new[] { new Plane(new Vector2(3.5f), new RectangleF(Vector2.Zero, textureSize)), new Plane(new Vector2(3.5f), new RectangleF(Vector2.Zero, textureSize)) }; // Set up default positions and orientations. _planes[0].Position = new Vector3(0, 0, 3.0f); _planes[1].Position = new Vector3(0, -3.5f, 3.5f); _planes[1].Rotation = new Vector3(90.0f, 0, 0); // Create our sphere. // Again, here we're using texels to align the texture coordinates to the other image // packed into the texture (atlasing). var textureOffset = _texture.ToTexel(new Vector2(516, 0)); // This is to scale our texture coordinates because the actual image is much smaller // (256x256) than the full texture (1024x512). textureSize.X = 0.245f; textureSize.Y = 0.5f; // Give the sphere a place to live. _sphere = new Sphere(1.0f, textureOffset, textureSize) { Position = new Vector3(2.2f, 1.5f, 2.5f) }; // Bind our objects to the pipeline and set default states. // At this point we need to give the graphics card a bunch of things // it needs to do its job. // Give our current input layout. Graphics.Input.Layout = _inputLayout; // We're drawing individual triangles for this (and this is usyally the case). Graphics.Input.PrimitiveType = PrimitiveType.TriangleList; // Bind our current vertex shader and send over our world/view/projection matrix // constant buffer. Graphics.Shaders.VertexShader.Current = _vertexShader; Graphics.Shaders.VertexShader.ConstantBuffers[0] = _wvpBuffer; // Do the same with the pixel shader, only we're binding our texture to it as well. // We also need to bind a sampler to the texture because without it, the shader won't // know how to interpret the texture data (e.g. how will the shader know if the texture // is supposed to be bilinear filtered or point filtered?) Graphics.Shaders.PixelShader.Current = _pixelShader; Graphics.Shaders.PixelShader.Resources[0] = _texture; Graphics.Shaders.PixelShader.TextureSamplers[0] = GorgonTextureSamplerStates.LinearFilter; // Turn on alpha blending. Graphics.Output.BlendingState.States = GorgonBlendStates.ModulatedBlending; // Turn on depth writing. // This is our depth writing state. When this is on, all polygon data sent to the card // will write to our depth buffer. Normally we want this, but for translucent objects, it's // problematic.... _depth = new GorgonDepthStencilStates { DepthComparison = ComparisonOperator.LessEqual, IsDepthEnabled = true, IsDepthWriteEnabled = true, IsStencilEnabled = false }; // Turn off depth writing. // So, we copy the depth state and turn off depth writing so that translucent objects // won't write to the depth buffer but can still read it. _noDepth = _depth; _noDepth.IsDepthWriteEnabled = false; Graphics.Output.DepthStencilState.States = _depth; // Bind our swap chain and set up the default rasterizer states. Graphics.Output.SetRenderTarget(_swap, _swap.DepthStencilBuffer); Graphics.Rasterizer.States = GorgonRasterizerStates.CullBackFace; Graphics.Rasterizer.SetViewport(view); // I know, there's a lot in here. Thing is, if this were Direct 3D 11 code, it'd probably MUCH // more code and that's even before creating our planes and sphere. }
/// <summary> /// Function used to build the resources required by the volume renderer. /// </summary> public void CreateResources() { _cubeVs = GorgonShaderFactory.Compile <GorgonVertexShader>(_graphics, Resources.VolumeRenderShaders, "VolumeVS", true); _cubePosShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics, Resources.VolumeRenderShaders, "VolumePositionPS", true); _cubeDirShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics, Resources.VolumeRenderShaders, "VolumeRayCastPS", true); _inputLayout = GorgonInputLayout.CreateUsingType <CubeVertex>(_graphics, _cubeVs); _cube = new Cube(_graphics, _inputLayout); _cubeTransform = new GorgonConstantBuffer(_graphics, new GorgonConstantBufferInfo { SizeInBytes = DX.Matrix.SizeInBytes }); _volumeRayParams = new GorgonConstantBuffer(_graphics, new GorgonConstantBufferInfo { SizeInBytes = Unsafe.SizeOf <VolumeRayParameters>() }); _volumeScaleFactor = new GorgonConstantBuffer(_graphics, new GorgonConstantBufferInfo { SizeInBytes = DX.Vector4.SizeInBytes }); // Our camera is never changing, so we only need to define it here. DX.Matrix.Translation(0, 0, 1.5f, out _view); ResizeRenderRegion(); UpdateCubeTransform(); var pipelineBuilder = new GorgonPipelineStateBuilder(_graphics); var drawBuilder = new GorgonDrawIndexCallBuilder(); pipelineBuilder .PixelShader(_cubePosShader) .VertexShader(_cubeVs); // Position draw calls. _cubePosDrawCull = drawBuilder .ConstantBuffer(ShaderType.Vertex, _cubeTransform.GetView()) .ConstantBuffer(ShaderType.Vertex, _volumeScaleFactor.GetView(), 1) .PipelineState(pipelineBuilder) .IndexBuffer(_cube.IndexBuffer, indexCount: _cube.IndexBuffer.IndexCount) .VertexBuffer(_inputLayout, _cube.VertexBuffer[0]) .Build(); pipelineBuilder .RasterState(GorgonRasterState.CullFrontFace); _cubePosDrawFrontCull = drawBuilder .PipelineState(pipelineBuilder) .Build(); // Raycasting draw call. pipelineBuilder .PixelShader(_cubeDirShader) .RasterState(GorgonRasterState.Default); _cubeDirDrawCall = drawBuilder .ConstantBuffer(ShaderType.Pixel, _volumeRayParams.GetView(), 0) .PipelineState(pipelineBuilder) .Build(); }
private void UpdateDeferred(GorgonConstantBuffer constantBuffer) { _tasks.Add(Task.Run(() => { var wvp = new WVPBuffer { Projection = _wvp.Projection, View = _wvp.View }; if (!_bouncy[0]) { _positions[0] = new Vector3(_positions[0].X + 1.0f * GorgonTiming.Delta, _positions[0].Y - 2.5f * GorgonTiming.Delta, _positions[0].Z + 1.85f * GorgonTiming.Delta); } else { _positions[0] = new Vector3(_positions[0].X - 1.0f * GorgonTiming.Delta, _positions[0].Y + 2.5f * GorgonTiming.Delta, _positions[0].Z - 1.85f * GorgonTiming.Delta); } if ((_positions[0].X > 2.0f) || (_positions[0].Y < -2.0f) || (_positions[0].Z > 6.0)) { _bouncy[0] = true; } if ((_positions[0].X < -2.0f) || (_positions[0].Y > 2.0f) || (_positions[0].Z < 1.0f)) { _bouncy[0] = false; } Matrix.Translation(ref _positions[0], out wvp.World); Matrix.Transpose(ref wvp.World, out wvp.World); constantBuffer.Update(ref wvp, _deferred[0]); _deferred[0].Output.DrawIndexed(0, 0, 6); _commands[0] = _deferred[0].FinalizeDeferred(); })); _tasks.Add(Task.Run(() => { var wvp = new WVPBuffer(); Matrix rot; Quaternion quat; wvp.Projection = _wvp.Projection; wvp.View = _wvp.View; if (!_bouncy[1]) { _positions[1].Z += (30.0f * GorgonTiming.Delta); _positions[1].Y += (15.0f * GorgonTiming.Delta); _positions[1].X += (10.0f * GorgonTiming.Delta); } else { _positions[1].Z -= (15.0f * GorgonTiming.Delta); _positions[1].Y -= (30.0f * GorgonTiming.Delta); _positions[1].X -= (25.0f * GorgonTiming.Delta); } if (_positions[1].Z > 195.0f) { _bouncy[1] = true; _positions[1].Z = 195.0f; } if (_positions[1].Z < 0.0f) { _bouncy[1] = true; _positions[1].Z = 0.0f; } Quaternion.RotationYawPitchRoll(_positions[1].Y.Radians(), _positions[1].X.Radians() * 0, _positions[1].Z.Radians() * 0, out quat); Matrix.RotationQuaternion(ref quat, out rot); Matrix.Translation(-2.0f, 0.0f, 6.0f, out wvp.World); Matrix.Multiply(ref rot, ref wvp.World, out wvp.World); Matrix.Transpose(ref wvp.World, out wvp.World); constantBuffer.Update(ref wvp, _deferred[1]); _deferred[1].Output.DrawIndexed(0, 0, 6); _commands[1] = _deferred[1].FinalizeDeferred(); })); try { Action runDeferred = async() => { var task = await Task.WhenAny(_tasks); _tasks.Remove(task); await task; }; while (_tasks.Count > 0) { runDeferred(); Thread.Sleep(5); } } catch (Exception ex) { GorgonDialogs.ErrorBox(null, ex); Gorgon.Quit(); } }