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())); }
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); }
/// <inheritdoc/> protected override Matrix44F ComputeProjection() { return(Matrix44F.CreateOrthographicOffCenter(Left, Right, Bottom, Top, Near, Far)); }
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(); }
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(); }
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)); }