Ejemplo n.º 1
0
        public void SetProjectionOffCenterTest()
        {
            OrthographicProjection projection = new OrthographicProjection();

            projection.SetOffCenter(0, 4, 1, 4, 2, 10);

            OrthographicProjection camera2 = new OrthographicProjection();

            camera2.SetOffCenter(0, 4, 1, 4);
            camera2.Near = 2;
            camera2.Far  = 10;

            Projection camera3 = new OrthographicProjection
            {
                Left   = 0,
                Right  = 4,
                Bottom = 1,
                Top    = 4,
                Near   = 2,
                Far    = 10,
            };

            Matrix44F expected = Matrix44F.CreateOrthographicOffCenter(0, 4, 1, 4, 2, 10);

            Assert.IsTrue(Matrix44F.AreNumericallyEqual(expected, projection));
            Assert.IsTrue(Matrix44F.AreNumericallyEqual(expected, camera2));
            Assert.IsTrue(Matrix44F.AreNumericallyEqual(expected, camera3.ToMatrix44F()));
        }
Ejemplo n.º 2
0
        public void SetProjectionTest()
        {
            Matrix44F projectionMatrix = Matrix44F.CreateOrthographicOffCenter(1, 4, 2, 5, 6, 11);
            OrthographicProjection orthographicProjection = new OrthographicProjection();

            orthographicProjection.Set(projectionMatrix);
            CameraInstance cameraInstance = new CameraInstance(new Camera(orthographicProjection));

            Assert.AreEqual(Vector3F.Zero, cameraInstance.PoseWorld.Position);
            Assert.AreEqual(Matrix33F.Identity, cameraInstance.PoseWorld.Orientation);
            Assert.That(Numeric.AreEqual(3, cameraInstance.Camera.Projection.Width));
            Assert.That(Numeric.AreEqual(3, cameraInstance.Camera.Projection.Height));
            Assert.That(Numeric.AreEqual(1f, cameraInstance.Camera.Projection.AspectRatio));
            Assert.That(Numeric.AreEqual(6, cameraInstance.Camera.Projection.Near));
            Assert.That(Numeric.AreEqual(11, cameraInstance.Camera.Projection.Far));
            Assert.That(Numeric.AreEqual(1, cameraInstance.Camera.Projection.Left));
            Assert.That(Numeric.AreEqual(4, cameraInstance.Camera.Projection.Right));
            Assert.That(Numeric.AreEqual(2, cameraInstance.Camera.Projection.Bottom));
            Assert.That(Numeric.AreEqual(5, cameraInstance.Camera.Projection.Top));
            Assert.That(Numeric.AreEqual(5, cameraInstance.Camera.Projection.Depth));
            Assert.That(Matrix44F.AreNumericallyEqual(orthographicProjection, cameraInstance.Camera.Projection));
            Assert.That(Matrix44F.AreNumericallyEqual(orthographicProjection.Inverse, cameraInstance.Camera.Projection.Inverse));
            Assert.IsNotNull(cameraInstance.BoundingShape);

            PerspectiveProjection perspectiveProjection = new PerspectiveProjection();

            perspectiveProjection.Inverse = Matrix44F.CreatePerspectiveOffCenter(1, 5, 2, 5, 1, 10).Inverse;
            cameraInstance = new CameraInstance(new Camera(perspectiveProjection));

            Assert.AreEqual(Vector3F.Zero, cameraInstance.PoseWorld.Position);
            Assert.AreEqual(Matrix33F.Identity, cameraInstance.PoseWorld.Orientation);
            Assert.That(Numeric.AreEqual(MathHelper.ToRadians(33.690067f), cameraInstance.Camera.Projection.FieldOfViewX));
            Assert.That(Numeric.AreEqual(MathHelper.ToRadians(15.255119f), cameraInstance.Camera.Projection.FieldOfViewY));
            Assert.That(Numeric.AreEqual(4, cameraInstance.Camera.Projection.Width));
            Assert.That(Numeric.AreEqual(3, cameraInstance.Camera.Projection.Height));
            Assert.That(Numeric.AreEqual(4.0f / 3.0f, cameraInstance.Camera.Projection.AspectRatio));
            Assert.That(Numeric.AreEqual(1, cameraInstance.Camera.Projection.Left));
            Assert.That(Numeric.AreEqual(5, cameraInstance.Camera.Projection.Right));
            Assert.That(Numeric.AreEqual(2, cameraInstance.Camera.Projection.Bottom));
            Assert.That(Numeric.AreEqual(5, cameraInstance.Camera.Projection.Top));
            Assert.That(Numeric.AreEqual(1, cameraInstance.Camera.Projection.Near));
            Assert.That(Numeric.AreEqual(10, cameraInstance.Camera.Projection.Far));
            Assert.That(Numeric.AreEqual(9, cameraInstance.Camera.Projection.Depth));
            Assert.IsNotNull(cameraInstance.BoundingShape);
        }
Ejemplo n.º 3
0
 /// <inheritdoc/>
 protected override Matrix44F ComputeProjection()
 {
     return(Matrix44F.CreateOrthographicOffCenter(Left, Right, Bottom, Top, Near, Far));
 }
Ejemplo n.º 4
0
        private void Render(RenderContext context, Vector4F color, Texture2D colorTexture, bool preserveColor)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            context.Validate(_effect);
            context.ThrowIfCameraMissing();
            context.ThrowIfGBuffer0Missing();

            var graphicsDevice   = _effect.GraphicsDevice;
            var savedRenderState = new RenderStateSnapshot(graphicsDevice);

            graphicsDevice.DepthStencilState = GraphicsHelper.DepthStencilStateAlways;
            graphicsDevice.RasterizerState   = RasterizerState.CullNone;

            if (preserveColor)
            {
                graphicsDevice.BlendState = GraphicsHelper.BlendStateNoColorWrite;
            }
            else
            {
                graphicsDevice.BlendState = BlendState.Opaque;
            }

            if (colorTexture != null)
            {
                if (TextureHelper.IsFloatingPointFormat(colorTexture.Format))
                {
                    graphicsDevice.SamplerStates[1] = SamplerState.PointClamp;
                }
                else
                {
                    graphicsDevice.SamplerStates[1] = SamplerState.LinearClamp;
                }
            }

            var   projection       = context.CameraNode.Camera.Projection;
            bool  isPerspective    = projection is PerspectiveProjection;
            float near             = projection.Near * NearBias;
            float far              = projection.Far * FarBias;
            var   biasedProjection = isPerspective
                               ? Matrix44F.CreatePerspectiveOffCenter(
                projection.Left, projection.Right,
                projection.Bottom, projection.Top,
                near, far)
                               : Matrix44F.CreateOrthographicOffCenter(
                projection.Left, projection.Right,
                projection.Bottom, projection.Top,
                near, far);

            var viewport = graphicsDevice.Viewport;

            _parameterViewportSize.SetValue(new Vector2(viewport.Width, viewport.Height));
            _parameterProjection.SetValue((Matrix)biasedProjection);
            _parameterCameraFar.SetValue(projection.Far);
            _parameterGBuffer0.SetValue(context.GBuffer0);
            _parameterColor.SetValue((Vector4)color);
            _parameterSourceTexture.SetValue(colorTexture);

            _effect.CurrentTechnique = isPerspective ? _techniquePerspective : _techniqueOrthographic;
            _effect.CurrentTechnique.Passes[(colorTexture == null) ? 0 : 1].Apply();

            graphicsDevice.DrawFullScreenQuad();

            graphicsDevice.ResetTextures();

            savedRenderState.Restore();
        }
Ejemplo n.º 5
0
        public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order)
        {
            if (nodes == null)
            {
                throw new ArgumentNullException("nodes");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            int numberOfNodes = nodes.Count;

            if (numberOfNodes == 0)
            {
                return;
            }

            context.Validate(_effect);
            context.ThrowIfCameraMissing();

            var graphicsDevice   = _effect.GraphicsDevice;
            var savedRenderState = new RenderStateSnapshot(graphicsDevice);

            graphicsDevice.DepthStencilState = DepthStencilState.None;
            graphicsDevice.RasterizerState   = RasterizerState.CullNone;
            graphicsDevice.BlendState        = GraphicsHelper.BlendStateAdd;

            var viewport = graphicsDevice.Viewport;

            _parameterViewportSize.SetValue(new Vector2(viewport.Width, viewport.Height));
            _parameterGBuffer0.SetValue(context.GBuffer0);
            _parameterGBuffer1.SetValue(context.GBuffer1);

            var    cameraNode     = context.CameraNode;
            Matrix viewProjection = (Matrix)cameraNode.View * cameraNode.Camera.Projection;

            var cameraPose = cameraNode.PoseWorld;

            GraphicsHelper.GetFrustumFarCorners(cameraNode.Camera.Projection, _cameraFrustumFarCorners);

            // Convert frustum far corners from view space to world space.
            for (int i = 0; i < _cameraFrustumFarCorners.Length; i++)
            {
                _cameraFrustumFarCorners[i] = (Vector3)cameraPose.ToWorldDirection((Vector3F)_cameraFrustumFarCorners[i]);
            }

            _parameterFrustumCorners.SetValue(_cameraFrustumFarCorners);

            // Update SceneNode.LastFrame for all visible nodes.
            int frame = context.Frame;

            cameraNode.LastFrame = frame;

            var isHdrEnabled = context.IsHdrEnabled();

            for (int i = 0; i < numberOfNodes; i++)
            {
                var lightNode = nodes[i] as LightNode;
                if (lightNode == null)
                {
                    continue;
                }

                var light = lightNode.Light as DirectionalLight;
                if (light == null)
                {
                    continue;
                }

                // LightNode is visible in current frame.
                lightNode.LastFrame = frame;

                float hdrScale = isHdrEnabled ? light.HdrScale : 1;
                _parameterDiffuseColor.SetValue((Vector3)light.Color * light.DiffuseIntensity * hdrScale);
                _parameterSpecularColor.SetValue((Vector3)light.Color * light.SpecularIntensity * hdrScale);

                Pose     lightPose           = lightNode.PoseWorld;
                Vector3F lightDirectionWorld = lightPose.ToWorldDirection(Vector3F.Forward);
                _parameterLightDirection.SetValue((Vector3)lightDirectionWorld);

                bool hasShadow = (lightNode.Shadow != null && lightNode.Shadow.ShadowMask != null);
                if (hasShadow)
                {
                    switch (lightNode.Shadow.ShadowMaskChannel)
                    {
                    case 0:  _parameterShadowMaskChannel.SetValue(new Vector4(1, 0, 0, 0)); break;

                    case 1:  _parameterShadowMaskChannel.SetValue(new Vector4(0, 1, 0, 0)); break;

                    case 2:  _parameterShadowMaskChannel.SetValue(new Vector4(0, 0, 1, 0)); break;

                    default: _parameterShadowMaskChannel.SetValue(new Vector4(0, 0, 0, 1)); break;
                    }

                    _parameterShadowMask.SetValue(lightNode.Shadow.ShadowMask);
                }

                bool hasTexture = (light.Texture != null);
                if (hasTexture)
                {
                    var textureProjection = Matrix44F.CreateOrthographicOffCenter(
                        -light.TextureOffset.X,
                        -light.TextureOffset.X + Math.Abs(light.TextureScale.X),
                        light.TextureOffset.Y,
                        light.TextureOffset.Y + Math.Abs(light.TextureScale.Y),
                        1,  // Not relevant
                        2); // Not relevant.
                    var scale = Matrix44F.CreateScale(Math.Sign(light.TextureScale.X), Math.Sign(light.TextureScale.Y), 1);

                    _parameterTextureMatrix.SetValue((Matrix)(GraphicsHelper.ProjectorBiasMatrix * scale * textureProjection * lightPose.Inverse));

                    _parameterTexture.SetValue(light.Texture);
                }

                if (lightNode.Clip != null)
                {
                    var data = lightNode.RenderData as LightRenderData;
                    if (data == null)
                    {
                        data = new LightRenderData();
                        lightNode.RenderData = data;
                    }

                    data.UpdateClipSubmesh(context.GraphicsService, lightNode);

                    graphicsDevice.DepthStencilState = GraphicsHelper.DepthStencilStateOnePassStencilFail;
                    graphicsDevice.BlendState        = GraphicsHelper.BlendStateNoColorWrite;

                    _parameterWorldViewProjection.SetValue((Matrix)data.ClipMatrix * viewProjection);
                    _passClip.Apply();
                    data.ClipSubmesh.Draw();

                    graphicsDevice.DepthStencilState = lightNode.InvertClip
            ? GraphicsHelper.DepthStencilStateStencilEqual0
            : GraphicsHelper.DepthStencilStateStencilNotEqual0;
                    graphicsDevice.BlendState = GraphicsHelper.BlendStateAdd;
                }
                else
                {
                    graphicsDevice.DepthStencilState = DepthStencilState.None;
                }

                if (hasShadow)
                {
                    if (hasTexture)
                    {
                        if (light.Texture.Format == SurfaceFormat.Alpha8)
                        {
                            _passShadowedTexturedAlpha.Apply();
                        }
                        else
                        {
                            _passShadowedTexturedRgb.Apply();
                        }
                    }
                    else
                    {
                        _passShadowed.Apply();
                    }
                }
                else
                {
                    if (hasTexture)
                    {
                        if (light.Texture.Format == SurfaceFormat.Alpha8)
                        {
                            _passTexturedAlpha.Apply();
                        }
                        else
                        {
                            _passTexturedRgb.Apply();
                        }
                    }
                    else
                    {
                        _passDefault.Apply();
                    }
                }

                graphicsDevice.DrawFullScreenQuad();
            }

            savedRenderState.Restore();
        }
Ejemplo n.º 6
0
        public void OrthographicOffCenterTest()
        {
            Vector3F       position       = new Vector3F(1, 2, 3);
            QuaternionF    orientation    = QuaternionF.CreateRotation(new Vector3F(2, 3, 6), 0.123f);
            CameraInstance cameraInstance = new CameraInstance(new Camera(new OrthographicProjection()))
            {
                PoseLocal = new Pose(position, orientation),
            };

            ((OrthographicProjection)cameraInstance.Camera.Projection).SetOffCenter(0, 16, 0, 9, 2, 10);
            Matrix44F projection = Matrix44F.CreateOrthographicOffCenter(0, 16, 0, 9, 2, 10);

            Assert.AreEqual(position, cameraInstance.PoseWorld.Position);
            Assert.AreEqual(orientation.ToRotationMatrix33(), cameraInstance.PoseWorld.Orientation);
            Assert.AreEqual(16, cameraInstance.Camera.Projection.Width);
            Assert.AreEqual(9, cameraInstance.Camera.Projection.Height);
            Assert.AreEqual(16.0f / 9.0f, cameraInstance.Camera.Projection.AspectRatio);
            Assert.AreEqual(2, cameraInstance.Camera.Projection.Near);
            Assert.AreEqual(10, cameraInstance.Camera.Projection.Far);
            Assert.AreEqual(0, cameraInstance.Camera.Projection.Left);
            Assert.AreEqual(16, cameraInstance.Camera.Projection.Right);
            Assert.AreEqual(0, cameraInstance.Camera.Projection.Bottom);
            Assert.AreEqual(9, cameraInstance.Camera.Projection.Top);
            Assert.AreEqual(8, cameraInstance.Camera.Projection.Depth);
            Assert.IsTrue(Matrix44F.AreNumericallyEqual(projection, cameraInstance.Camera.Projection));
            Assert.IsTrue(Matrix44F.AreNumericallyEqual(projection.Inverse, cameraInstance.Camera.Projection.Inverse));
            Assert.IsNotNull(cameraInstance.BoundingShape);

            CollisionDetection collisionDetection = new CollisionDetection();
            var             point = new PointShape();
            CollisionObject pointCollisionObject  = new CollisionObject(new GeometricObject(point));
            CollisionObject cameraCollisionObject = new CollisionObject(cameraInstance);

            // Test shape using collision detection. Remove rotation to simplify test.
            cameraInstance.PoseWorld = new Pose(cameraInstance.PoseWorld.Position);
            point.Position           = position + new Vector3F(0, 0, -2);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3F(-0.1f, -0.1f, -1.9f);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3F(16, 9, -10);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3F(16.1f, 9.1f, -10.1f);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));

            cameraInstance.Camera.Projection.Left   = -2;
            cameraInstance.Camera.Projection.Right  = 4;
            cameraInstance.Camera.Projection.Bottom = 10;
            cameraInstance.Camera.Projection.Top    = 14;
            cameraInstance.Camera.Projection.Near   = 15;
            cameraInstance.Camera.Projection.Far    = 100;
            projection = Matrix44F.CreateOrthographicOffCenter(-2, 4, 10, 14, 15, 100);
            Assert.IsTrue(Matrix44F.AreNumericallyEqual(projection.Inverse, cameraInstance.Camera.Projection.Inverse));
            Assert.IsTrue(Matrix44F.AreNumericallyEqual(projection, cameraInstance.Camera.Projection));

            // Test shape using collision detection. Remove rotation to simplify test.
            cameraInstance.PoseWorld = new Pose(cameraInstance.PoseWorld.Position);
            point.Position           = position + new Vector3F(-2, 10, -15);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3F(-2.1f, -10.1f, -14.9f);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3F(4, 14, -100);
            Assert.IsTrue(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
            point.Position = position + new Vector3F(4.1f, 14.1f, -100.1f);
            Assert.IsFalse(collisionDetection.HaveContact(pointCollisionObject, cameraCollisionObject));
        }