Beispiel #1
0
        /// <summary>
        /// Update shadow map.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> used for allocating resources.
        /// </param>
        public override void UpdateShadowMap(GraphicsContext ctx, SceneGraph shadowGraph)
        {
            CheckCurrentContext(ctx);
            if (shadowGraph == null)
            {
                throw new ArgumentNullException("shadowGraph");
            }

            // Compute light matrix
            IModelMatrix viewMatrix = new ModelMatrix();             // LocalModel.Multiply(LightMatrix.GetInverseMatrix()).GetInverseMatrix();

            viewMatrix.LookAtDirection((Vertex3d)LocalModel.Position, (Vertex3f)Direction, Vertex3d.UnitY);

            // Set light scene view
            shadowGraph.ProjectionMatrix = new PerspectiveProjectionMatrix(FalloffAngle * 2.0f, 1.0f, 0.1f, 100.0f);
            shadowGraph.ViewMatrix       = viewMatrix;

            _ShadowFramebuffer.BindDraw(ctx);

            // Reset viewport
            new ViewportState(0, 0, (int)_ShadowMap.Width, (int)_ShadowMap.Height).Apply(ctx, null);

            _ShadowFramebuffer.Clear(ctx, ClearBufferMask.DepthBufferBit);

            shadowGraph.Draw(ctx, _ShadowProgram);

            _ShadowFramebuffer.UnbindDraw(ctx);

            // Cache view matrix
            _ShadowViewMatrix = _BiasMatrix.Multiply(shadowGraph.ProjectionMatrix.Multiply(viewMatrix));
        }
Beispiel #2
0
        /// <summary>
        /// Extract the top plane from a model-view-projection matrix.
        /// </summary>
        /// <param name="modelViewProjection">
        /// The <see cref="IMatrix4x4"/> that specify the matrix used for drawing the clipped object.
        /// </param>
        /// <returns>
        /// It returns a <see cref="Plane"/> defining the top clipping plane.
        /// </returns>
        public static Plane GetFrustumTopPlane(IMatrix4x4 modelViewProjection)
        {
            // Compute plane
            Vertex4d a = new Vertex4d(modelViewProjection.GetRow(3));
            Vertex4d b = new Vertex4d(modelViewProjection.GetRow(1));

            return(NormalizePlane(NameTop, a - b));
        }
Beispiel #3
0
        /// <summary>
        /// Extract the far plane from a model-view-projection matrix.
        /// </summary>
        /// <param name="modelViewProjection">
        /// The <see cref="IMatrix4x4"/> that specify the matrix used for drawing the clipped object.
        /// </param>
        /// <returns>
        /// It returns a <see cref="Plane"/> defining the far clipping plane.
        /// </returns>
        public static Plane GetFrustumFarPlane(IMatrix4x4 modelViewProjection)
        {
            // Compute plane
            Vertex4d a = new Vertex4d(modelViewProjection.GetRow(2));
            Vertex4d b = new Vertex4d(modelViewProjection.GetRow(3));

            return(NormalizePlane(NameFar, b - a));
        }
Beispiel #4
0
        /// <summary>
        /// Extract the far plane from a model-view-projection matrix.
        /// </summary>
        /// <param name="modelViewProjection">
        /// The <see cref="IMatrix4x4"/> that specify the matrix used for drawing the clipped object.
        /// </param>
        /// <returns>
        /// It returns a <see cref="Plane"/> defining the far clipping plane.
        /// </returns>
        public static Plane GetFrustumFarPlane(IMatrix4x4 modelViewProjection)
        {
            // Compute plane
            Vertex4d a = new Vertex4d(modelViewProjection.GetRow(3));
            Vertex4d b = new Vertex4d(modelViewProjection.GetRow(2));

            Plane plane = NormalizePlane(NameFar, a - b);

            plane.Distance = -plane.Distance;
            return(plane);
        }
Beispiel #5
0
        private void RenderChildren(RenderObject obj, IMatrix4x4 viewProjectionMatrix, Camera camera)
        {
            foreach (RenderObject child in obj.Children)
            {
                RenderChildren(child, viewProjectionMatrix, camera);
            }

            if (obj.Model?.Mesh != null && obj.Model?.Shader != null)
            {
                Vector <double> cameraPos = camera.GetWorldPosition().Subtract(obj.GetWorldPosition());
                RenderModel(obj.Model, viewProjectionMatrix, obj.GetObjectToWorldTransform(), cameraPos);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Extract all six planes from a model-view-projection matrix.
        /// </summary>
        /// <param name="modelViewProjection">
        /// The <see cref="IMatrix4x4"/> that specify the matrix used for drawing the clipped object.
        /// </param>
        /// <returns>
        /// It returns a <see cref="IEnumerable{Plane}"/> containing all six clipping planes defined
        /// by <paramref name="modelViewProjection"/>.
        /// </returns>
        public static IEnumerable <Plane> GetFrustumPlanes(IMatrix4x4 modelViewProjection)
        {
            List <Plane> planes = new List <Plane>(6);

            planes.Add(GetFrustumLeftPlane(modelViewProjection));
            planes.Add(GetFrustumRightPlane(modelViewProjection));
            planes.Add(GetFrustumNearPlane(modelViewProjection));
            planes.Add(GetFrustumFarPlane(modelViewProjection));
            planes.Add(GetFrustumBottomPlane(modelViewProjection));
            planes.Add(GetFrustumTopPlane(modelViewProjection));

            return(planes);
        }
Beispiel #7
0
        /// <summary>
        /// Get all geometries compositing this SceneObjectGeometry, filtering them using view-frustum.
        /// </summary>
        /// <param name="currentState">
        /// A <see cref="State.GraphicsStateSet"/> that specifies the current graphics state to be merged with
        /// each returned geometry.
        /// </param>
        /// <param name="clippingPlanes">
        ///
        /// </param>
        /// <param name="viewModel">
        ///
        /// </param>
        /// <returns>
        /// It returns a <see cref="IEnumerable{SceneObjectBatch}"/>.
        /// </returns>
        private IEnumerable <SceneObjectBatch> GetGeometriesViewFrustum(SceneGraphContext ctxScene)
        {
            GraphicsStateSet   currentState       = ctxScene.GraphicsStateStack.Current.Push();
            TransformStateBase sceneGeometryModel = (TransformStateBase)currentState[TransformStateBase.StateSetIndex];
            IMatrix4x4         viewModel          = sceneGeometryModel.ModelView;

            if (_GeometryInstances.Count > 0)
            {
                foreach (Geometry sceneObjectBatch in _GeometryInstances)
                {
                    IBoundingVolume instanceVolume = sceneObjectBatch.BoundingVolume ?? _BoundingVolume;

                    if (instanceVolume != null && instanceVolume.IsClipped(ctxScene.ViewFrustumPlanes, viewModel))
                    {
                        continue;
                    }

                    GraphicsStateSet geometryState;

                    if (sceneObjectBatch.State != null)
                    {
                        geometryState = currentState.Push();
                        geometryState.Merge(sceneObjectBatch.State);
                    }
                    else
                    {
                        geometryState = currentState;
                    }

                    yield return(new SceneObjectBatch(
                                     sceneObjectBatch.VertexArray ?? VertexArray,
                                     geometryState,
                                     sceneObjectBatch.Program ?? Program
                                     ));
                }
            }
            else
            {
                if (_BoundingVolume != null && _BoundingVolume.IsClipped(ctxScene.ViewFrustumPlanes, viewModel))
                {
                    yield break;
                }

                if (VertexArray == null)
                {
                    yield break;
                }

                yield return(new SceneObjectBatch(VertexArray, currentState, Program));
            }
        }
Beispiel #8
0
        public void Render(int width, int height, RenderObject root, Camera camera)
        {
            Gl.Viewport(0, 0, width, height);

            Gl.Enable(EnableCap.DepthTest);
            Gl.Enable(EnableCap.CullFace);
            Gl.CullFace(CullFaceMode.Back);

            Gl.ClearColor(0, 0, 0, 1);
            Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            IMatrix4x4 viewMatrix           = CreateViewMatrix(camera);
            IMatrix4x4 projectionMatrix     = CreateProjectionMatrix(camera);
            IMatrix4x4 viewProjectionMatrix = projectionMatrix.Multiply(viewMatrix);

            RenderChildren(root, viewProjectionMatrix, camera);
        }
Beispiel #9
0
        private void RenderModel(Render.Model model, IMatrix4x4 viewProjectionMatrix, Matrix <double> modelMatrix, Vector <double> cameraPosition)
        {
            if (!model.Shader.SetUniformMatrix("viewProjectionTransformation", viewProjectionMatrix))
            {
                throw new Exception("Vertex shader is missing 'viewProjectionTransformation'");
            }
            if (!model.Shader.SetUniformMatrix("modelTransformation", modelMatrix))
            {
                throw new Exception("Vertex shader is missing 'modelTransformation'");
            }
            model.Shader.SetUniformVector("cameraPos", cameraPosition);

            Gl.BindVertexArray(model.Mesh.VertexArrayObjectId);
            Gl.ActiveTexture(TextureUnit.Texture0);
            Gl.BindTexture(TextureTarget.Texture2d, model.Texture?.Id ?? 0);
            Gl.UseProgram(model.Shader.Id);

            Gl.DrawElements(PrimitiveType.Triangles, model.Mesh.IndexCount, DrawElementsType.UnsignedInt, IntPtr.Zero);
        }
Beispiel #10
0
        /// <summary>
        /// Determine whether this bound volume is clipped by all specified planes.
        /// </summary>
        /// <param name="clippingPlanes">
        /// A <see cref="IEnumerable{Plane}"/> that are used to perform geometry clipping.
        /// </param>
        /// <returns>
        /// It returns a boolean value indicating whether this bound volume is entirely
        /// clipped by <paramref name="clippingPlanes"/>.
        /// </returns>
        public bool IsClipped(IEnumerable <Plane> clippingPlanes, IMatrix4x4 viewModel)
        {
            if (clippingPlanes == null)
            {
                throw new ArgumentNullException("clippingPlanes");
            }

            Vertex3f[] boundVertices = new Vertex3f[8];
            Vertex3f[] viewVertices  = new Vertex3f[2];

            for (int i = 0; i < 2; i++)
            {
                viewVertices[i] = (Vertex3f)viewModel.Multiply(_Bounds[i]);
            }

            // Lower box vertices
            boundVertices[0] = new Vertex3f(viewVertices[1].x, viewVertices[0].y, viewVertices[1].z);
            boundVertices[1] = new Vertex3f(viewVertices[0].x, viewVertices[0].y, viewVertices[1].z);
            boundVertices[2] = new Vertex3f(viewVertices[0].x, viewVertices[0].y, viewVertices[0].z);
            boundVertices[3] = new Vertex3f(viewVertices[1].x, viewVertices[0].y, viewVertices[0].z);
            // Higher box vertices
            boundVertices[4] = new Vertex3f(viewVertices[1].x, viewVertices[1].y, viewVertices[1].z);
            boundVertices[5] = new Vertex3f(viewVertices[0].x, viewVertices[1].y, viewVertices[1].z);
            boundVertices[6] = new Vertex3f(viewVertices[0].x, viewVertices[1].y, viewVertices[0].z);
            boundVertices[7] = new Vertex3f(viewVertices[1].x, viewVertices[1].y, viewVertices[0].z);

            foreach (Plane clipPlane in clippingPlanes)
            {
                bool outsidePlane = true;

                for (int i = 0; i < boundVertices.Length && outsidePlane; i++)
                {
                    outsidePlane &= clipPlane.GetDistance(boundVertices[i]) < 0.0f;
                }

                if (outsidePlane)
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #11
0
        internal IEnumerable <SceneObjectBatch> GetBoundingVolumes(SceneGraphContext ctxScene)
        {
            GraphicsStateSet   currentState       = ctxScene.GraphicsStateStack.Current.Push();
            TransformStateBase sceneGeometryModel = (TransformStateBase)currentState[TransformStateBase.StateSetIndex];
            IMatrix4x4         viewModel          = sceneGeometryModel.ModelView;

            if (_GeometryInstances.Count > 0)
            {
                foreach (Geometry sceneObjectBatch in _GeometryInstances)
                {
                    IBoundingVolume instanceVolume = sceneObjectBatch.BoundingVolume ?? _BoundingVolume;

                    if (instanceVolume != null && instanceVolume.IsClipped(ctxScene.ViewFrustumPlanes, viewModel))
                    {
                        continue;
                    }

                    GraphicsStateSet volumeState = currentState.Push();

                    SetBoundingVolumeState(instanceVolume, volumeState);

                    yield return(new SceneObjectBatch(
                                     _BoundingVolumeArray,
                                     volumeState,
                                     _BoundingVolumeProgram
                                     ));
                }
            }
            else
            {
                if (_BoundingVolume == null || _BoundingVolume.IsClipped(ctxScene.ViewFrustumPlanes, viewModel))
                {
                    yield break;
                }

                GraphicsStateSet volumeState = currentState.Push();

                SetBoundingVolumeState(_BoundingVolume, volumeState);

                yield return(new SceneObjectBatch(_BoundingVolumeArray, volumeState, _BoundingVolumeProgram));
            }
        }
Beispiel #12
0
        public void TestProjectionFrustum()
        {
            PerspectiveProjectionMatrix projectionMatrix = new PerspectiveProjectionMatrix(90.0f, 1.0f, 1.0f, 10.0f);
            ModelMatrix modelMatrix = new ModelMatrix();

            IMatrix4x4 frustumMatrix = projectionMatrix * modelMatrix;

            Plane planeL = Plane.GetFrustumLeftPlane(frustumMatrix);
            Plane planeR = Plane.GetFrustumRightPlane(frustumMatrix);
            Plane planeB = Plane.GetFrustumBottomPlane(frustumMatrix);
            Plane planeT = Plane.GetFrustumTopPlane(frustumMatrix);

            Plane planeN = Plane.GetFrustumNearPlane(frustumMatrix);

            Assert.IsTrue(planeN.GetDistance(new Vertex3f(0.0f, 0.0f, -5.0f)) > 0.0f);

            Plane planeF = Plane.GetFrustumFarPlane(frustumMatrix);

            Assert.IsTrue(planeF.GetDistance(new Vertex3f(0.0f, 0.0f, -5.0f)) > 0.0f);
        }
        /// <summary>
        /// Set uniform state variable (variant type).
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> used for operations.
        /// </param>
        /// <param name="uniformName">
        /// A <see cref="String"/> that specify the variable name in the shader source.
        /// </param>
        /// <param name="m">
        /// A <see cref="IMatrix4x4"/> holding the uniform variabile data.
        /// </param>
        public void SetVariantUniform(GraphicsContext ctx, string uniformName, IMatrix4x4 m)
        {
            if (ctx == null)
            {
                throw new ArgumentNullException("ctx");
            }

            UniformBinding uniform = GetUniform(uniformName);

            switch (uniform.UniformType)
            {
            case ShaderUniformType.Mat4x4:
                SetUniform(ctx, uniformName, (Matrix4x4)m);
                break;

            case ShaderUniformType.DoubleMat4x4:
                SetUniform(ctx, uniformName, (MatrixDouble4x4)m);
                break;

            default:
                throw new ShaderException("unable to set double-precision floating-point matrix 4x4 data to uniform of type {0}", uniform.UniformType);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Compute the product of this IMatrix with another IMatrix.
        /// </summary>
        /// <param name="a">
        /// A <see cref="IMatrix4x4"/> that specify the right multiplication operand.
        /// </param>
        /// <returns>
        /// A <see cref="IMatrix"/> resulting from the product of this matrix and the matrix <paramref name="a"/>.
        /// </returns>
        IMatrix4x4 IMatrix4x4.Multiply(IMatrix4x4 a)
        {
            if (a == null)
            {
                throw new ArgumentNullException("a");
            }

            MatrixDouble4x4 otherMatrix = a as MatrixDouble4x4;

            if (otherMatrix != null)
            {
                return(this * otherMatrix);
            }

            Matrix4x4 otherMatrix4x4 = a as Matrix4x4;

            if (otherMatrix4x4 != null)
            {
                return(this * (MatrixDouble4x4)otherMatrix4x4);
            }

            throw new NotSupportedException("unknown IMatrix4x4 implementation");
        }
		/// <summary>
		/// Set uniform state variable (variant type).
		/// </summary>
		/// <param name="ctx">
		/// A <see cref="GraphicsContext"/> used for operations.
		/// </param>
		/// <param name="uniformName">
		/// A <see cref="String"/> that specify the variable name in the shader source.
		/// </param>
		/// <param name="m">
		/// A <see cref="IMatrix4x4"/> holding the uniform variabile data.
		/// </param>
		public void SetVariantUniform(GraphicsContext ctx, string uniformName, IMatrix4x4 m)
		{
			if (ctx == null)
				throw new ArgumentNullException("ctx");

			UniformBinding uniform = GetUniform(uniformName);

			switch (uniform.UniformType) {
				case ShaderUniformType.Mat4x4:
					SetUniform(ctx, uniformName, (Matrix4x4)m);
					break;
				case ShaderUniformType.DoubleMat4x4:
					SetUniform(ctx, uniformName, (MatrixDouble4x4)m);
					break;
				default:
					throw new ShaderException("unable to set double-precision floating-point matrix 4x4 data to uniform of type {0}", uniform.UniformType);
			}
		}
        internal IEnumerable <SceneObjectBatch> GetGeometries(State.GraphicsStateSet currentState, IEnumerable <Plane> clippingPlanes, IMatrix4x4 viewModel)
        {
            if (_GeometryInstances.Count > 0)
            {
                foreach (Geometry sceneObjectBatch in _GeometryInstances)
                {
                    IBoundingVolume instanceVolume = sceneObjectBatch.BoundingVolume ?? _BoundingVolume;

                    if (instanceVolume != null && instanceVolume.IsClipped(clippingPlanes, viewModel))
                    {
                        continue;
                    }

                    State.GraphicsStateSet geometryState;

                    if (sceneObjectBatch.State != null)
                    {
                        geometryState = currentState.Push();
                        geometryState.Merge(sceneObjectBatch.State);
                    }
                    else
                    {
                        geometryState = currentState;
                    }

                    yield return(new SceneObjectBatch(
                                     sceneObjectBatch.VertexArray ?? VertexArray,
                                     geometryState,
                                     sceneObjectBatch.Program ?? Program
                                     ));
                }
            }
            else
            {
                if (_BoundingVolume != null && _BoundingVolume.IsClipped(clippingPlanes, viewModel))
                {
                    yield break;
                }

                yield return(new SceneObjectBatch(VertexArray, currentState, Program));
            }
        }
Beispiel #17
0
 /// <summary>
 /// Matrix copy constructor.
 /// </summary>
 /// <param name="m">
 /// A <see cref="Matrix"/> to be copied.
 /// </param>
 public Matrix4x4(IMatrix4x4 m) :
     base(m)
 {
 }
Beispiel #18
0
		/// <summary>
		/// Matrix copy constructor.
		/// </summary>
		/// <param name="m">
		/// A <see cref="Matrix"/> to be copied.
		/// </param>
		public Matrix4x4(IMatrix4x4 m) :
			base(m)
		{

		}
Beispiel #19
0
		/// <summary>
		/// Compute the product of this IMatrix with another IMatrix.
		/// </summary>
		/// <param name="a">
		/// A <see cref="IMatrix4x4"/> that specifies the right multiplication operand.
		/// </param>
		/// <returns>
		/// A <see cref="IMatrix"/> resulting from the product of this matrix and the matrix <paramref name="a"/>.
		/// </returns>
		IMatrix4x4 IMatrix4x4.Multiply(IMatrix4x4 a)
		{
			if (a == null)
				throw new ArgumentNullException("a");
			
			Matrix4x4 otherMatrix4x4 = a as Matrix4x4;
			if (otherMatrix4x4 != null)
				return (this * otherMatrix4x4);
			
			MatrixDouble4x4 otherMatrixDouble4x4 = a as MatrixDouble4x4;
			if (otherMatrixDouble4x4 != null)
				return ((MatrixDouble4x4)this * otherMatrixDouble4x4);
			
			throw new NotSupportedException("unknown IMatrix4x4 implementation");
		}
Beispiel #20
0
 bool IBoundingVolume.IsClipped(IEnumerable <Plane> clippingPlanes, IMatrix4x4 viewModel)
 {
     throw new NotImplementedException();
 }