/// <summary> /// Function to update the view matrix. /// </summary> /// <param name="eyePosition">Position of the eye.</param> /// <param name="lookAt">Point in space to look at.</param> /// <param name="up">The current up vector.</param> public void UpdateViewMatrix(ref Vector3 eyePosition, ref Vector3 lookAt, ref Vector3 up) { Matrix.LookAtLH(ref eyePosition, ref lookAt, ref up, out _viewProj.View); Matrix.Multiply(ref _viewProj.View, ref _viewProj.Projection, out _viewProj.ViewProjection); _camData.CameraPosition = eyePosition; _camData.CameraLookAt = lookAt; _camData.CameraUp = up; _projViewBuffer.Update(ref _viewProj); _cameraBuffer.Update(ref _camData); }
/// <summary> /// Function called before rendering begins. /// </summary> /// <returns> /// TRUE to continue rendering, FALSE to exit. /// </returns> protected override bool OnBeforeRender() { if ((_displacementTarget == null) || (_backgroundTarget == null)) { UpdateDisplacementMap(_targetFormat); } #if DEBUG if ((_displacementTarget == null) || (_backgroundTarget == null)) { throw new GorgonException(GorgonResult.CannotWrite, Resources.GOR2D_EFFECT_NO_DISPLACEMENT_TARGET); } #endif RememberConstantBuffer(ShaderType.Pixel, 1); RememberShaderResource(ShaderType.Pixel, 1); Gorgon2D.PixelShader.ConstantBuffers[1] = _displacementBuffer; if (!_isUpdated) { return(base.OnBeforeRender()); } var settings = new Vector4(1.0f / _backgroundTarget.Settings.Width, 1.0f / _backgroundTarget.Settings.Height, _displacementStrength, 0); _displacementBuffer.Update(ref settings); _isUpdated = false; return(base.OnBeforeRender()); }
/// <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> /// Function to update the blur kernel. /// </summary> /// <remarks>This implementation is ported from the Java code appearing in "Filthy Rich Clients: Developing Animated and Graphical Effects for Desktop Java".</remarks> private void UpdateKernel() { float sigma = _blurRadius / _blurAmount; float sqSigmaDouble = 2.0f * sigma * sigma; float sigmaRoot = (sqSigmaDouble * (float)System.Math.PI).Sqrt(); float total = 0.0f; int blurKernelSize = (_blurRadius * 2) + 1; for (int i = -_blurRadius, index = 0; i <= _blurRadius; ++i, ++index) { float distance = i * i; _kernel[index] = (-distance / sqSigmaDouble).Exp() / sigmaRoot; total += _kernel[index]; } _blurKernelStream.Position = 0; _blurKernelStream.Write(_blurRadius); for (int i = 0; i < blurKernelSize; i++) { _blurKernelStream.Write(new Vector4(0, 0, 0, _kernel[i] / total)); } // Send to constant buffer. _blurKernelStream.Position = 0; _blurStaticBuffer.Update(_blurKernelStream); }
/// <summary> /// Function to render a pass. /// </summary> /// <param name="pass">Pass that is to be rendered.</param> protected override void OnRenderPass(GorgonEffectPass pass) { Gorgon2D.Target = _hTarget; // Render horizontal pass. _hTarget.Clear(GorgonColor.Transparent); _blurBuffer.Update(_xOffsets); // Render the scene. pass.RenderAction(pass); // Render vertical pass. Gorgon2D.Target = _vTarget; _blurBuffer.Update(_yOffsets); _blurSprite.Draw(); }
/// <summary> /// Function to update the correct light buffer data to the constant buffer. /// </summary> /// <param name="index">Index of the light to update.</param> private unsafe void UpdateIndex(int index) { var data = (LightData *)_lightStore.UnsafePointer; for (int i = 0; i < _lightData.Length; ++i) { *(data++) = _lightData[i]; } _buffer.Update(_lightData); }
/// <summary> /// Function called before rendering begins. /// </summary> /// <returns> /// TRUE to continue rendering, FALSE to exit. /// </returns> protected override bool OnBeforeRender() { if (_isUpdated) { _posterizeBuffer.Update(ref _settings); _isUpdated = false; } RememberConstantBuffer(ShaderType.Pixel, 1); Gorgon2D.PixelShader.ConstantBuffers[1] = _posterizeBuffer; return(base.OnBeforeRender()); }
/// <summary> /// Function called before rendering begins. /// </summary> /// <returns> /// TRUE to continue rendering, FALSE to exit. /// </returns> protected override bool OnBeforeRender() { if (_isUpdated) { _burnDodgeBuffer.Update(ref _useDodge); _isUpdated = false; } RememberConstantBuffer(ShaderType.Pixel, 1); Gorgon2D.PixelShader.ConstantBuffers[1] = _burnDodgeBuffer; return(base.OnBeforeRender()); }
/// <summary> /// Function called before rendering begins. /// </summary> /// <returns> /// TRUE to continue rendering, FALSE to exit. /// </returns> protected override bool OnBeforeRender() { if (_isUpdated) { var settings = new Vector3(1.0f / Area.X, 1.0f / Area.Y, _amount); _sharpenEmbossBuffer.Update(ref settings); _isUpdated = false; } RememberConstantBuffer(ShaderType.Pixel, 1); Gorgon2D.PixelShader.ConstantBuffers[1] = _sharpenEmbossBuffer; return(base.OnBeforeRender()); }
/// <summary> /// Function to update the world/view/projection matrix. /// </summary> /// <param name="world">The world matrix to update.</param> public static void UpdateWVP(ref Matrix world) { Matrix temp; Matrix wvp; // Build our world/view/projection matrix to send to // the shader. Matrix.Multiply(ref world, ref _viewMatrix, out temp); Matrix.Multiply(ref temp, ref _projMatrix, out wvp); // Direct 3D 11 requires that we transpose our matrix // before sending it to the shader. Matrix.Transpose(ref wvp, out wvp); // Update the constant buffer. _wvpBufferStream.Write(wvp); _wvpBufferStream.Position = 0; _wvpBuffer.Update(_wvpBufferStream); }
/// <summary> /// Function called before a pass is rendered. /// </summary> /// <param name="pass">Pass to render.</param> /// <returns> /// TRUE to continue rendering, FALSE to stop. /// </returns> protected override bool OnBeforePassRender(GorgonEffectPass pass) { float renderTime = Time; if (_isScratchUpdated) { _scratchBuffer.Update(ref _scratchSettings); _isScratchUpdated = false; } if (_isSepiaUpdated) { _sepiaBuffer.Update(ref _sepiaSettings); _isSepiaUpdated = false; } _timingBuffer.Update(ref renderTime); return(base.OnBeforePassRender(pass)); }
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(); } }
/// <summary> /// Main application loop. /// </summary> /// <returns>TRUE to continue processing, FALSE to stop.</returns> private static bool Idle() { Matrix world; _swapChain.Clear(Color.CornflowerBlue, 1.0f); _cloudRotation += 2.0f * GorgonTiming.Delta; _objRotation += 50.0f * GorgonTiming.Delta; if (_cloudRotation > 359.9f) { _cloudRotation -= 359.9f; } if (_objRotation > 359.9f) { _objRotation -= 359.9f; } ProcessKeys(); _material.UVOffset = new Vector2(0, _material.UVOffset.Y - 0.125f * GorgonTiming.Delta); _graphics.Shaders.PixelShader.Current = _waterShader; if (_material.UVOffset.Y < 0.0f) { _material.UVOffset = new Vector2(0, 1.0f + _material.UVOffset.Y); } _materialBuffer.Update(ref _material); world = _triangle.World; _wvp.UpdateWorldMatrix(ref world); _graphics.Shaders.PixelShader.Resources[0] = _triangle.Texture; _graphics.Shaders.PixelShader.Resources[1] = _normalMap; _graphics.Shaders.PixelShader.Resources[2] = _specMap; _graphics.Input.VertexBuffers[0] = new GorgonVertexBufferBinding(_triangle.VertexBuffer, Vertex3D.Size); _graphics.Input.IndexBuffer = _triangle.IndexBuffer; _graphics.Input.PrimitiveType = _triangle.PrimitiveType; _graphics.Output.DrawIndexed(0, 0, _triangle.IndexCount); //_plane.Rotation = new Vector3(_objRotation, 0, 0); world = _plane.World; _wvp.UpdateWorldMatrix(ref world); _graphics.Shaders.PixelShader.Resources[0] = _plane.Texture; _graphics.Input.VertexBuffers[0] = new GorgonVertexBufferBinding(_plane.VertexBuffer, Vertex3D.Size); _graphics.Input.IndexBuffer = _plane.IndexBuffer; _graphics.Input.PrimitiveType = _plane.PrimitiveType; _graphics.Output.DrawIndexed(0, 0, _plane.IndexCount); var worldRot = _icoSphere.Rotation; worldRot.Y += 4.0f * GorgonTiming.Delta; _icoSphere.Rotation = worldRot; world = _icoSphere.World; _wvp.UpdateWorldMatrix(ref world); _graphics.Shaders.PixelShader.Current = _bumpShader; _graphics.Shaders.PixelShader.Resources[0] = _icoSphere.Texture; _graphics.Shaders.PixelShader.Resources[1] = _normalEarfMap; _graphics.Shaders.PixelShader.Resources[2] = _specEarfMap; _graphics.Input.VertexBuffers[0] = new GorgonVertexBufferBinding(_icoSphere.VertexBuffer, Vertex3D.Size); _graphics.Input.IndexBuffer = _icoSphere.IndexBuffer; _graphics.Input.PrimitiveType = _icoSphere.PrimitiveType; _graphics.Output.DrawIndexed(0, 0, _icoSphere.IndexCount); var cubeMat = new Material { UVOffset = Vector2.Zero, SpecularPower = 0.0f }; _materialBuffer.Update(ref cubeMat); _cube.Rotation = new Vector3(_objRotation, _objRotation, _objRotation); world = _cube.World; _wvp.UpdateWorldMatrix(ref world); _graphics.Shaders.PixelShader.Resources[0] = _cube.Texture; _graphics.Shaders.PixelShader.Resources[1] = _gorgNrm; _graphics.Input.VertexBuffers[0] = new GorgonVertexBufferBinding(_cube.VertexBuffer, Vertex3D.Size); _graphics.Input.IndexBuffer = _cube.IndexBuffer; _graphics.Input.PrimitiveType = _cube.PrimitiveType; _graphics.Output.DrawIndexed(0, 0, _cube.IndexCount); var sphereMat = new Material { UVOffset = Vector2.Zero, SpecularPower = 0.75f }; _materialBuffer.Update(ref sphereMat); _yPos = (_objRotation.Radians().Sin().Abs() * 2.0f) - 1.10f; _sphere.Position = new Vector3(-2.0f, _yPos, 0.75f); _sphere.Rotation = new Vector3(_objRotation, _objRotation, 0); world = _sphere.World; _wvp.UpdateWorldMatrix(ref world); _graphics.Shaders.PixelShader.Current = _pixelShader; _graphics.Shaders.PixelShader.Resources[0] = _sphere.Texture; _graphics.Input.VertexBuffers[0] = new GorgonVertexBufferBinding(_sphere.VertexBuffer, Vertex3D.Size); _graphics.Input.IndexBuffer = _sphere.IndexBuffer; _graphics.Input.PrimitiveType = _sphere.PrimitiveType; _graphics.Output.DrawIndexed(0, 0, _sphere.IndexCount); sphereMat = new Material { UVOffset = Vector2.Zero, SpecularPower = 0.0f }; _materialBuffer.Update(ref sphereMat); _graphics.Shaders.PixelShader.Resources[0] = _clouds.Texture; _graphics.Input.VertexBuffers[0] = new GorgonVertexBufferBinding(_clouds.VertexBuffer, Vertex3D.Size); _graphics.Input.IndexBuffer = _clouds.IndexBuffer; _graphics.Input.PrimitiveType = _clouds.PrimitiveType; _clouds.Rotation = new Vector3(0, _cloudRotation, 0); world = _clouds.World; _wvp.UpdateWorldMatrix(ref world); _graphics.Output.BlendingState.States = GorgonBlendStates.AdditiveBlending; _graphics.Output.DrawIndexed(0, 0, _clouds.IndexCount); _graphics.Output.BlendingState.States = GorgonBlendStates.NoBlending; world = _sphere.World; _wvp.UpdateWorldMatrix(ref world); _graphics.Input.Layout = _normalVertexLayout; _graphics.Input.PrimitiveType = PrimitiveType.LineList; _graphics.Shaders.PixelShader.Current = _normalPixelShader; _graphics.Shaders.VertexShader.Current = _normalVertexShader; _graphics.Input.IndexBuffer = null; _graphics.Input.VertexBuffers[0] = new GorgonVertexBufferBinding(_sphere.Normals, Vector4.SizeInBytes); _graphics.Output.Draw(0, _sphere.VertexCount * 2); _graphics.Input.Layout = _vertexLayout; _graphics.Shaders.VertexShader.Current = _vertexShader; var state = _renderer2D.Begin2D(); _renderer2D.Drawing.DrawString(_font, string.Format( "FPS: {0:0.0}, Delta: {1:0.000} ms Tris: {3:0} CamRot: {2} Mouse: {4:0}x{5:0} Sensitivity: {6:0.0##}", GorgonTiming.FPS, GorgonTiming.Delta * 1000, _cameraRotation, (_triangle.TriangleCount) + (_plane.TriangleCount) + (_cube.TriangleCount) + (_sphere.TriangleCount) + (_icoSphere.TriangleCount) + (_clouds.TriangleCount), _mouse.Position.X, _mouse.Position.Y, _sensitivity), Vector2.Zero, Color.White); _renderer2D.Flush(); _renderer2D.End2D(state); _swapChain.Flip(); return(true); }
/// <summary> /// Function to update the world matrix. /// </summary> /// <param name="world">World matrix to update.</param> public void UpdateWorldMatrix(ref Matrix world) { _worldBuffer.Update(ref world); }