예제 #1
0
        public MainWindow()
        {
            _dxgiDevice = AvaloniaLocator.Current.GetService <SharpDX.DXGI.Device>();
            _d3dDevice  = _dxgiDevice.QueryInterface <SharpDX.Direct3D11.Device>();
            _d2dDevice  = AvaloniaLocator.Current.GetService <SharpDX.Direct2D1.Device>();
            DataContext = _model = new MainWindowViewModel();
            _desc       = new SwapChainDescription()
            {
                BufferCount     = 1,
                ModeDescription =
                    new ModeDescription((int)ClientSize.Width, (int)ClientSize.Height,
                                        new Rational(60, 1), Format.R8G8B8A8_UNorm),
                IsWindowed        = true,
                OutputHandle      = PlatformImpl?.Handle.Handle ?? IntPtr.Zero,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect        = SwapEffect.Discard,
                Usage             = Usage.RenderTargetOutput
            };

            _swapChain = new SwapChain(new Factory1(), _d3dDevice, _desc);

            _d2dContext = new SharpDX.Direct2D1.DeviceContext(_d2dDevice, DeviceContextOptions.None)
            {
                DotsPerInch = new Size2F(96, 96)
            };

            CreateMesh();
            _view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
            this.GetObservable(ClientSizeProperty).Subscribe(Resize);
            Resize(ClientSize);
            AvaloniaXamlLoader.Load(this);
            Background = Avalonia.Media.Brushes.Transparent;
        }
예제 #2
0
        public Matrix CreateViewMatrix2(double w, double h)
        {
            // Prepare matrices

            Matrix worldMatrix = Matrix.Identity;
            var    view        = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
            var    proj        = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)w / (float)h, 0.1f, 100.0f);

            return(Matrix.Multiply(view, proj));
        }
예제 #3
0
        void SetSceneConstants()
        {
            FreeLook freelook    = Demo.FreeLook;
            Vector3  up          = MathHelper.Convert(freelook.Up);
            Vector3  eye         = MathHelper.Convert(freelook.Eye);
            Vector4  eyePosition = new Vector4(eye, 1);

            sceneConstants.View = Matrix.LookAtLH(eye, MathHelper.Convert(freelook.Target), up);
            Matrix.PerspectiveFovLH(FieldOfView, AspectRatio, _nearPlane, FarPlane, out sceneConstants.Projection);
            Matrix.Invert(ref sceneConstants.View, out sceneConstants.ViewInverse);

            Texture2DDescription depthBuffer = lightDepthTexture.Description;
            Vector3 lightPosition            = sunLightDirection * -60;
            Matrix  lightView = Matrix.LookAtLH(lightPosition, Vector3.Zero, up);
            //Matrix lightProjection = Matrix.OrthoLH(depthBuffer.Width / 8.0f, depthBuffer.Height / 8.0f, _nearPlane, FarPlane);
            Matrix lightProjection = Matrix.PerspectiveFovLH(FieldOfView, (float)depthBuffer.Width / (float)depthBuffer.Height, _nearPlane, FarPlane);

            sceneConstants.LightViewProjection = lightView * lightProjection;

            DataStream data;

            _immediateContext.MapSubresource(sceneConstantsBuffer, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out data);
            Marshal.StructureToPtr(sceneConstants, data.DataPointer, false);
            _immediateContext.UnmapSubresource(sceneConstantsBuffer, 0);
            data.Dispose();

            sunLightDirectionVar.Set(new Vector4(sunLightDirection, 1));

            Matrix overlayMatrix = Matrix.Scaling(info.Width / _width, info.Height / _height, 1.0f);

            overlayMatrix *= Matrix.Translation(-(_width - info.Width) / _width, (_height - info.Height) / _height, 0.0f);
            overlayViewProjectionVar.SetMatrix(overlayMatrix);


            lightProjectionVar.SetMatrixTranspose(ref sceneConstants.Projection);
            lightViewVar.SetMatrixTranspose(ref sceneConstants.View);
            lightViewInverseVar.SetMatrix(ref sceneConstants.ViewInverse);
            lightViewportWidthVar.Set(_width);
            lightViewportHeightVar.Set(_height);
            lightEyePositionVar.Set(ref eyePosition);

            float   tanHalfFovY    = (float)Math.Tan(FieldOfView * 0.5f);
            float   tanHalfFovX    = tanHalfFovY * AspectRatio;
            float   projectionA    = FarPlane / (FarPlane - _nearPlane);
            float   projectionB    = -projectionA * _nearPlane;
            Vector4 viewParameters = new Vector4(tanHalfFovX, tanHalfFovY, projectionA, projectionB);

            lightViewParametersVar.Set(ref viewParameters);


            viewportWidthVar.Set(_width);
            viewportHeightVar.Set(_height);
            viewParametersVar.Set(ref viewParameters);
        }
예제 #4
0
        public void Render(Camera camera, params Mesh[] meshes)
        {
            var viewMatrix       = Matrix.LookAtLH(camera.Position, camera.Target, camera.Up);
            var projectionMatrix = Matrix.PerspectiveFovLH(0.78f, (float)width / height, 0.01f, 1.0f);

            foreach (var mesh in meshes)
            {
                var worldMatrix = Matrix.RotationYawPitchRoll(mesh.Rotation.Y, mesh.Rotation.X, mesh.Rotation.Z) *
                                  Matrix.Translation(mesh.Position);

                var worldView       = worldMatrix * viewMatrix;
                var transformMatrix = worldView * projectionMatrix;

                Parallel.For(0, mesh.Faces.Length, faceIndex =>
                {
                    var face = mesh.Faces[faceIndex];

                    // Face-back culling
                    //var transformedNormal = Vector3.TransformNormal(face.Normal, worldView);

                    //if (transformedNormal.Z >= 0)
                    //{
                    //    return;
                    //}

                    // Render this face
                    var vertexA = mesh.Vertices[face.A];
                    var vertexB = mesh.Vertices[face.B];
                    var vertexC = mesh.Vertices[face.C];

                    var pixelA = Project(vertexA, transformMatrix, worldMatrix);
                    var pixelB = Project(vertexB, transformMatrix, worldMatrix);
                    var pixelC = Project(vertexC, transformMatrix, worldMatrix);

                    //var color = 0.25f + (faceIndex % mesh.Faces.Length) * 0.75f / mesh.Faces.Length;
                    var color = 1.0f;


                    if (Wireframe)
                    {
                        Algorithm.Line(pixelA.Coordinates.X, pixelA.Coordinates.Y, pixelB.Coordinates.X,
                                       pixelB.Coordinates.Y, Color.White, DrawPoint);
                        Algorithm.Line(pixelB.Coordinates.X, pixelB.Coordinates.Y, pixelC.Coordinates.X,
                                       pixelC.Coordinates.Y, Color.White, DrawPoint);
                        Algorithm.Line(pixelC.Coordinates.X, pixelC.Coordinates.Y, pixelA.Coordinates.X,
                                       pixelA.Coordinates.Y, Color.White, DrawPoint);
                    }
                    else
                    {
                        DrawTriangle(pixelA, pixelB, pixelC, new Color4(color, color, color, 1), mesh.Texture);
                    }
                });
            }
        }
예제 #5
0
        private void Prepare()
        {
            var vertexShaderByteCode = ShaderBytecode.CompileFromFile("shaders.fx", "VS", "vs_4_0");
            var vertexShader         = new VertexShader(_manager.Device, vertexShaderByteCode);

            var pixelShaderByteCode = ShaderBytecode.CompileFromFile("shaders.fx", "PS", "ps_4_0");
            var pixelShader         = new PixelShader(_manager.Device, pixelShaderByteCode);

            var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);

            var layout = new InputLayout(_manager.Device, signature, new[]
            {
                new InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 0, 0),
                new InputElement("COLOR", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 16, 0),
                new InputElement("NORMAL", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 32, 0),
            });

            _sphere = new Sphere(1f, 4);

            var sphereVert =
                _sphere.Vertices.SelectMany(el =>
                                            new[]
            {
                new Vector4(el.Position, 1f),
                Color.LawnGreen.ToVector4(),
                new Vector4(el.Normal, 0f)
            }).ToArray();

            _sphereVertBuffer = Buffer.Create(_manager.Device, BindFlags.VertexBuffer, sphereVert);
            _sphereIndBuffer  = Buffer.Create(_manager.Device, BindFlags.IndexBuffer, _sphere.Indices);


            _constantBuffer = new Buffer(_manager.Device, Utilities.SizeOf <ConstantBuffer>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

            var context = _manager.Device.ImmediateContext;

            context.InputAssembler.InputLayout       = layout;
            context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

            context.VertexShader.SetConstantBuffer(0, _constantBuffer);
            context.VertexShader.Set(vertexShader);
            context.PixelShader.SetConstantBuffer(0, _constantBuffer);
            context.PixelShader.Set(pixelShader);

            _view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
            _proj = Matrix.Identity;

            _clock = new Stopwatch();
            _clock.Start();

            _cbuf = new ConstantBuffer();
        }
예제 #6
0
        public override void Update(float timeTotal, float timeDelta)
        {
            //timeDelta; // Unused parameter.
            int width  = (int)_renderTargetSize.Width;
            int height = (int)_renderTargetSize.Height;

            _view     = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
            _proj     = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, width / (float)height, 0.1f, 100.0f);
            _viewProj = Matrix.Multiply(_view, _proj);

            _worldViewProj = Matrix.Scaling(1.0f) * Matrix.RotationX(timeTotal) * Matrix.RotationY(timeTotal * 2.0f) * Matrix.RotationZ(timeTotal * .7f) * _viewProj;
            _worldViewProj.Transpose();
        }
예제 #7
0
        void SetSceneConstants()
        {
            FreeLook freelook = Demo.Freelook;
            Vector3  up       = MathHelper.Convert(freelook.Up);

            sceneConstants.View        = Matrix.LookAtLH(MathHelper.Convert(freelook.Eye), MathHelper.Convert(freelook.Target), up);
            sceneConstants.Projection  = Matrix.PerspectiveFovLH(FieldOfView, AspectRatio, _nearPlane, FarPlane);
            sceneConstants.ViewInverse = Matrix.Invert(sceneConstants.View);

            Vector3 light = new Vector3(20, 30, 10);
            Texture2DDescription depthBuffer = lightDepthTexture.Description;
            Matrix lightView       = Matrix.LookAtLH(light, Vector3.Zero, up);
            Matrix lightProjection = Matrix.OrthoLH(depthBuffer.Width / 8.0f, depthBuffer.Height / 8.0f, _nearPlane, FarPlane);

            sceneConstants.LightViewProjection = lightView * lightProjection;

            DataStream data;

            _immediateContext.MapSubresource(sceneConstantsBuffer, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out data);
            Marshal.StructureToPtr(sceneConstants, data.DataPointer, false);
            _immediateContext.UnmapSubresource(sceneConstantsBuffer, 0);
            data.Dispose();

            inverseProjectionVar.SetMatrix(Matrix.Invert(sceneConstants.Projection));
            inverseViewVar.SetMatrix(sceneConstants.ViewInverse);
            lightInverseViewProjectionVar.SetMatrix(Matrix.Invert(sceneConstants.LightViewProjection));
            lightPositionVar.Set(new Vector4(light, 1));
            eyePositionVar.Set(new Vector4(MathHelper.Convert(freelook.Eye), 1));
            eyeZAxisVar.Set(new Vector4(Vector3.Normalize(MathHelper.Convert(freelook.Target - freelook.Eye)), 1));

            float tanHalfFOVY = (float)Math.Tan(FieldOfView * 0.5f);

            tanHalfFOVXVar.Set(tanHalfFOVY * AspectRatio);
            tanHalfFOVYVar.Set(tanHalfFOVY);
            float projectionA = FarPlane / (FarPlane - _nearPlane);
            float projectionB = -projectionA * _nearPlane;

            projectionAVar.Set(projectionA);
            projectionBVar.Set(projectionB);

            Matrix overlayMatrix = Matrix.Scaling(info.Width / _width, info.Height / _height, 1.0f);

            overlayMatrix *= Matrix.Translation(-(_width - info.Width) / _width, (_height - info.Height) / _height, 0.0f);
            overlayViewProjectionVar.SetMatrix(overlayMatrix);
        }
예제 #8
0
        void SetSceneConstants()
        {
            FreeLook freelook = Demo.Freelook;
            Vector3  up       = MathHelper.Convert(freelook.Up);

            sceneConstants.View        = Matrix.LookAtLH(MathHelper.Convert(freelook.Eye), MathHelper.Convert(freelook.Target), up);
            sceneConstants.Projection  = Matrix.PerspectiveFovLH(FieldOfView, AspectRatio, _nearPlane, FarPlane);
            sceneConstants.ViewInverse = Matrix.Invert(sceneConstants.View);

            Vector3 light = new Vector3(20, 30, 10);
            Texture2DDescription depthBuffer = lightDepthTexture.Description;
            Matrix lightView       = Matrix.LookAtLH(light, Vector3.Zero, up);
            Matrix lightProjection = Matrix.OrthoLH(depthBuffer.Width / 8.0f, depthBuffer.Height / 8.0f, _nearPlane, FarPlane);

            sceneConstants.LightViewProjection = lightView * lightProjection;

            using (var data = sceneConstantsBuffer.Map(MapMode.WriteDiscard))
            {
                Marshal.StructureToPtr(sceneConstants, data.DataPointer, false);
                sceneConstantsBuffer.Unmap();
            }

            effect2.GetVariableByName("InverseProjection").AsMatrix().SetMatrix(Matrix.Invert(sceneConstants.Projection));
            effect2.GetVariableByName("InverseView").AsMatrix().SetMatrix(sceneConstants.ViewInverse);
            effect2.GetVariableByName("LightInverseViewProjection").AsMatrix().SetMatrix(Matrix.Invert(sceneConstants.LightViewProjection));
            effect2.GetVariableByName("LightPosition").AsVector().Set(new Vector4(light, 1));
            effect2.GetVariableByName("EyePosition").AsVector().Set(new Vector4(MathHelper.Convert(freelook.Eye), 1));
            effect2.GetVariableByName("EyeZAxis").AsVector().Set(new Vector4(Vector3.Normalize(MathHelper.Convert(freelook.Target - freelook.Eye)), 1));

            float tanHalfFOVY = (float)Math.Tan(FieldOfView * 0.5f);

            effect2.GetVariableByName("TanHalfFOVX").AsScalar().Set(tanHalfFOVY * AspectRatio);
            effect2.GetVariableByName("TanHalfFOVY").AsScalar().Set(tanHalfFOVY);
            float projectionA = FarPlane / (FarPlane - _nearPlane);
            float projectionB = -projectionA * _nearPlane;

            effect2.GetVariableByName("ProjectionA").AsScalar().Set(projectionA);
            effect2.GetVariableByName("ProjectionB").AsScalar().Set(projectionB);

            Matrix overlayMatrix = Matrix.Scaling(2 * info.Width / _width, 2 * info.Height / _height, 1.0f);

            overlayMatrix *= Matrix.Translation(-(_width - info.Width) / _width, (_height - info.Height) / _height, 0.0f);
            effect2.GetVariableByName("OverlayViewProjection").AsMatrix().SetMatrix(overlayMatrix);
        }
예제 #9
0
        public override void Render()
        {
            int width  = (int)_renderTargetSize.Width;
            int height = (int)_renderTargetSize.Height;

            // Prepare matrices
            var view     = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
            var proj     = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, width / (float)height, 0.1f, 100.0f);
            var viewProj = Matrix.Multiply(view, proj);

            var time = (float)(_clock.ElapsedMilliseconds / 1000.0);


            // Set targets (This is mandatory in the loop)
            _deviceContext.OutputMerger.SetTargets(_depthStencilView, _renderTargetview);

            _deviceContext.ClearDepthStencilView(_depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);

            // Clear the views
            _deviceContext.ClearRenderTargetView(_renderTargetview, Color.CornflowerBlue);

            //if (ShowCube)
            //{
            // Calculate WorldViewProj
            var worldViewProj = Matrix.Scaling(1.0f) * Matrix.RotationX(time) * Matrix.RotationY(time * 2.0f) * Matrix.RotationZ(time * .7f) * viewProj;

            worldViewProj.Transpose();

            // Setup the pipeline
            _deviceContext.InputAssembler.SetVertexBuffers(0, _vertexBufferBinding);
            _deviceContext.InputAssembler.InputLayout       = _vertexLayout;
            _deviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
            _deviceContext.VertexShader.SetConstantBuffer(0, _constantBuffer);
            _deviceContext.VertexShader.Set(_vertexShader);
            _deviceContext.PixelShader.Set(_pixelShader);

            // Update Constant Buffer
            _deviceContext.UpdateSubresource(ref worldViewProj, _constantBuffer, 0);

            // Draw the cube
            _deviceContext.Draw(36, 0);
            //}
        }
예제 #10
0
        public MainWindow()
        {
            DataContext = _model = new MainWindowViewModel();

            _desc = new SwapChainDescription1()
            {
                BufferCount       = 1,
                Width             = (int)ClientSize.Width,
                Height            = (int)ClientSize.Height,
                Format            = Format.R8G8B8A8_UNorm,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect        = SwapEffect.Discard,
                Usage             = Usage.RenderTargetOutput
            };

            using (var factory = Direct2D1Platform.DxgiDevice.Adapter.GetParent <Factory2>())
            {
                _swapChain = new SwapChain1(factory, Direct2D1Platform.DxgiDevice, PlatformImpl?.Handle.Handle ?? IntPtr.Zero, ref _desc);
            }

            _deviceContext = new DeviceContext(Direct2D1Platform.Direct2D1Device, DeviceContextOptions.None)
            {
                DotsPerInch = new Size2F(96, 96)
            };

            CreateMesh();

            _view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);

            this.GetObservable(ClientSizeProperty).Subscribe(Resize);

            Resize(ClientSize);

            AvaloniaXamlLoader.Load(this);

            Background = Avalonia.Media.Brushes.Transparent;
        }
        private void SharpDXRenderingAction(RenderingContext renderingContext)
        {
            // Just in case the data were already disposed
            if (_constantBuffer == null)
            {
                return;
            }


            var context = renderingContext.DXDevice.ImmediateContext;

            // NOTE:
            // Because DXEngine by default uses different culling mode than SharpDX,
            // we first need to set the culling mode to the one that is used in the ShardDX sample - CounterClockwise culling
            // The SharpDX way to do that is (we are using the already defined CullCounterClockwise rasterizer state):
            //context.Rasterizer.State = renderingContext.DXDevice.CommonStates.CullCounterClockwise;

            // But it is better to do that in the DXEngine's way with ImmediateContextStatesManager
            // That prevents to many state changes with checking the current state and also ensures that any DXEngine's objects that would be rendered after
            // SharpDX objects would be rendered correctly:
            renderingContext.DXDevice.ImmediateContextStatesManager.RasterizerState = renderingContext.DXDevice.CommonStates.CullCounterClockwise;


            // Prepare All the stages
            context.InputAssembler.InputLayout       = _layout;
            context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
            context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(_vertices, SharpDX.Utilities.SizeOf <Vector4>() * 2, 0));
            context.VertexShader.SetConstantBuffer(0, _constantBuffer);
            context.VertexShader.Set(_vertexShader);
            context.PixelShader.Set(_pixelShader);


            // Clear views - this is done by DXEngine in PrepareRenderTargetsRenderingStep
            //context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
            //context.ClearRenderTargetView(renderView, Color.Black);


            // Prepare matrices
            var view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);

            // Setup new projection matrix with correct aspect ratio
            var proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)renderingContext.DXScene.Width / (float)renderingContext.DXScene.Height, 0.1f, 100.0f);

            var viewProj = Matrix.Multiply(view, proj);


            var time = _clock.ElapsedMilliseconds / 1000.0f;

            // Update WorldViewProj Matrix
            var worldViewProj = Matrix.RotationX(time) * Matrix.RotationY(time * 2) * Matrix.RotationZ(time * .7f) * viewProj;

            // If the matrixes in the shaders are written in default format, then we need to transpose them.
            // To remove the need for transposal we can define the matrixes in HLSL as row_major (this is used in DXEngine's shaders, but here the original shader from SharpDX is preserved).
            worldViewProj.Transpose();

            // Write the new world view projection matrix to the constant buffer
            context.UpdateSubresource(ref worldViewProj, _constantBuffer);

            // Draw the cube
            context.Draw(36, 0);

            // Present is called by DXEngine in CompleteRenderingStep
            //swapChain.Present(0, PresentFlags.None);
        }