Пример #1
0
        /// <summary>
        /// Create the corresponding <see cref="LightsState.Light"/> for this object.
        /// </summary>
        /// <returns>
        /// It returns the <see cref="LightsState.Light"/> equivalent to this SceneObjectLight.
        /// </returns>
        public override LightsState.Light ToLight(GraphicsContext ctx, SceneGraphContext sceneCtx)
        {
            TransformStateBase transformState = (TransformStateBase)sceneCtx.GraphicsStateStack.Current[TransformStateBase.StateSetIndex];

            LightsState.LightSpot light = new LightsState.LightSpot();

            SetLightParameters(sceneCtx, light);

            IModelMatrix worldModel   = transformState.LocalModelView;
            IMatrix3x3   normalMatrix = worldModel.GetComplementMatrix(3, 3).GetInverseMatrix().Transpose();

            light.Direction          = ((Vertex3f)normalMatrix.Multiply((Vertex3f)Direction)).Normalized;
            light.Position           = (Vertex3f)worldModel.Multiply(Vertex3f.Zero);
            light.AttenuationFactors = AttenuationFactors;
            light.FallOff            = new Vertex2f((float)Math.Cos(Angle.ToRadians(FalloffAngle)), FalloffExponent);

            // Shadow mapping
            if (_ShadowMap != null && _ShadowViewMatrix != null)
            {
                // Determined later: light.ShadowMapIndex
                light.ShadowMapMvp.Set(_ShadowViewMatrix);
                light.ShadowMap2D = _ShadowMap;
            }
            else
            {
                light.ShadowMapIndex = -1;
                light.ShadowMap2D    = null;
            }

            return(light);
        }
Пример #2
0
 /// <summary>
 /// Draw this SceneGraphObject instance.
 /// </summary>
 /// <param name="ctx">
 /// The <see cref="GraphicsContext"/> used for drawing.
 /// </param>
 /// <param name="ctxScene">
 /// The <see cref="SceneGraphContext"/> used for drawing.
 /// </param>
 protected override void DrawThis(GraphicsContext ctx, SceneGraphContext ctxScene)
 {
     // Apply current state
     ctxScene.GraphicsStateStack.Current.Apply(ctx, _Program);
     // Draw arrays
     _VertexArray.Draw(ctx, _Program);
 }
Пример #3
0
        /// <summary>
        /// Create the corresponding <see cref="LightsState.Light"/> for this object.
        /// </summary>
        /// <returns>
        /// It returns the <see cref="LightsState.Light"/> equivalent to this SceneObjectLight.
        /// </returns>
        public override LightsState.Light ToLight(GraphicsContext ctx, SceneGraphContext sceneCtx)
        {
            TransformState transformState = (TransformState)sceneCtx.GraphicsStateStack.Current[TransformState.StateSetIndex];

            LightsState.LightSpot light = new LightsState.LightSpot();

            SetLightParameters(sceneCtx, light);

            Matrix4x4f worldModel   = transformState.ModelView;
            Matrix3x3f normalMatrix = new Matrix3x3f(worldModel, 3, 3).Inverse.Transposed;

            light.Direction          = (normalMatrix * (Vertex3f)Direction).Normalized;
            light.Position           = (Vertex3f)(worldModel * Vertex3f.Zero);
            light.AttenuationFactors = AttenuationFactors;
            light.FallOff            = new Vertex2f((float)Math.Cos(Angle.ToRadians(FalloffAngle)), FalloffExponent);

            // Shadow mapping
            if (_ShadowMap != null)
            {
                // Determined later: light.ShadowMapIndex
                light.ShadowMapMvp = _ShadowViewMatrix;
                light.ShadowMap2D  = _ShadowMap;
            }
            else
            {
                light.ShadowMapIndex = -1;
                light.ShadowMap2D    = null;
            }

            return(light);
        }
Пример #4
0
        private static bool DrawDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            // Draw this object
            sceneObject.DrawThis(ctx, ctxScene);

            return(true);
        }
Пример #5
0
        /// <summary>
        /// Traverse the scene graph from the current SceneObject to the leaf SceneObject.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing/updating objects, if any.
        /// </param>
        /// <param name="ctxScene">
        /// The <see cref="SceneGraphContext"/> used for drawing/updating objects, if any.
        /// </param>
        /// <param name="traverseFunc">
        /// The <see cref="TraverseDelegate"/> executed for each SceneObject instance visited during traversal.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="traverseFunc"/> is null.
        /// </exception>
        protected internal void TraverseDirect(GraphicsContext ctx, SceneGraphContext ctxScene, TraverseContext traverseFunc, object data)
        {
            CheckCurrentContext(ctx);

            if (ctxScene == null)
            {
                throw new ArgumentNullException("ctxScene");
            }
            if (traverseFunc == null)
            {
                throw new ArgumentNullException("traverseFunc");
            }

            traverseFunc.PreContract?.Invoke(ctx, ctxScene, this, data);
            try {
                // Visit this object
                if (traverseFunc.Visit(ctx, ctxScene, this, data) == false)
                {
                    return;
                }
                // Visit children
                foreach (SceneObject sceneObject in _Children)
                {
                    sceneObject.TraverseDirect(ctx, ctxScene, traverseFunc, data);
                }
            } finally {
                traverseFunc.PostContract?.Invoke(ctx, ctxScene, this, data);
            }
        }
Пример #6
0
        private static bool GraphDrawPreDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            // Push and merge the graphics state
            ctxScene.GraphicsStateStack.Push(sceneObject.ObjectState);

            return(true);
        }
Пример #7
0
        private SceneGraphFlags _Flags = SceneGraphFlags.None;         // SceneGraphFlags.CullingViewFrustum | SceneGraphFlags.StateSorting; // | SceneGraphFlags.BoundingVolumes;

        /// <summary>
        /// Draw this SceneGraph.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        public void Draw(GraphicsContext ctx)
        {
            CheckCurrentContext(ctx);

            using (SceneGraphContext ctxScene = new SceneGraphContext(this, _CurrentView)) {
                ObjectBatchContext objectBatchContext = new ObjectBatchContext();

                // Override model-view-projection matrices if a camera is defined
                if (_CurrentView != null)
                {
                    LocalProjection = _CurrentView.ProjectionMatrix;
                    LocalModel      = _CurrentView.LocalModel.GetInverseMatrix();
                }

                // View-frustum culling
                objectBatchContext.ViewFrustumPlanes = Plane.GetFrustumPlanes(LocalProjection);
                // Collect geometries to be batched
                TraverseDirect(ctx, ctxScene, _TraverseDrawContext, objectBatchContext);

                // Sort geometries
                List <SceneObjectBatch> sceneObjects = objectBatchContext.Objects;
                if (((SceneFlags & SceneGraphFlags.StateSorting) != 0) && (_SorterRoot != null))
                {
                    sceneObjects = _SorterRoot.Sort(objectBatchContext.Objects);
                }

                // Draw all batches
                foreach (SceneObjectBatch objectBatch in sceneObjects)
                {
                    objectBatch.Draw(ctx);
                }
            }
        }
Пример #8
0
        protected static bool DrawPostDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            // Restore previous state
            ctxScene.GraphicsStateStack.Pop();

            return(true);
        }
Пример #9
0
        /// <summary>
        /// The internal light parameters.
        /// </summary>
        /// <param name="light">
        /// The <see cref="LightsState.Light"/> to be set.
        /// </param>
        protected void SetLightParameters(SceneGraphContext sceneCtx, LightsState.Light light)
        {
            light.AmbientColor  = AmbientColor;
            light.DiffuseColor  = DiffuseColor;
            light.SpecularColor = SpecularColor;

            light.ShadowMapIndex = -1;
        }
Пример #10
0
        protected static bool DrawPreDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            // Update object before applying state
            sceneObject.UpdateThis(ctx, ctxScene);
            // Push and merge the graphics state
            ctxScene.GraphicsStateStack.Push(sceneObject.ObjectState);

            return(true);
        }
Пример #11
0
        /// <summary>
        /// Create the corresponding <see cref="LightsState.Light"/> for this object.
        /// </summary>
        /// <returns>
        /// It returns the <see cref="LightsState.Light"/> equivalent to this SceneObjectLight.
        /// </returns>
        public override LightsState.Light ToLight(SceneGraphContext sceneCtx)
        {
            LightsState.LightSpot light = new LightsState.LightSpot();

            SetLightParameters(sceneCtx, light);

            light.FallOff = new Vertex2f(FalloffAngle, FalloffExponent);

            return(light);
        }
Пример #12
0
        internal void ResetLights(SceneGraphContext ctxScene, List <SceneObjectLight> lights)
        {
            State.LightsState lightState = (State.LightsState)ObjectState[State.LightsState.StateSetIndex];

            lightState.Lights.Clear();
            foreach (SceneObjectLight lightObject in lights)
            {
                lightState.Lights.Add(lightObject.ToLight(ctxScene));
            }
        }
Пример #13
0
        /// <summary>
        /// Update this SceneGraphObject instance.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        /// <param name="ctxScene">
        /// The <see cref="SceneGraphContext"/> used for drawing.
        /// </param>
        protected internal override void UpdateThis(GraphicsContext ctx, SceneGraphContext ctxScene)
        {
            //List<SceneObject> lightObjects = FindChildren(delegate(SceneObject item) { return (item is SceneObjectLight); });

            //SceneLightingState lightingState = (SceneLightingState)ObjectState[SceneLightingState.StateSetIndex];

            //lightingState.CurrentSceneContext = ctxScene;
            //lightingState.ResetLights();
            //lightingState.AddLights(lightObjects.ConvertAll(delegate(SceneObject item) { return ((SceneObjectLight)item); }));
        }
Пример #14
0
        private void PostObject(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObjectLightZone sceneObject)
        {
            if (sceneObject == null)
            {
                throw new ArgumentNullException("sceneObject");
            }

            _LightState.Pop();

            ctxScene.GraphicsStateStack.Current.DefineState(CurrentZone);
        }
Пример #15
0
        /// <summary>
        /// Create the corresponding <see cref="LightsState.Light"/> for this object.
        /// </summary>
        /// <returns>
        /// It returns the <see cref="LightsState.Light"/> equivalent to this SceneObjectLight.
        /// </returns>
        public override LightsState.Light ToLight(GraphicsContext ctx, SceneGraphContext sceneCtx)
        {
            LightsState.LightPoint light = new LightsState.LightPoint();

            SetLightParameters(sceneCtx, light);

            light.Position           = (Vertex3f)(WorldModel * Vertex3f.Zero);
            light.AttenuationFactors = AttenuationFactors;

            return(light);
        }
Пример #16
0
        /// <summary>
        /// Draw this SceneGraphObject hierarchy.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        /// <param name="ctxScene">
        /// The <see cref="SceneGraphContext"/> used for drawing.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="ctx"/> is null.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="ctx"/> is not current on the calling thread.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="ctxScene"/>.
        /// </exception>
        protected internal virtual void Draw(GraphicsContext ctx, SceneGraphContext ctxScene)
        {
            CheckCurrentContext(ctx);

            if (ctxScene == null)
            {
                throw new ArgumentNullException("ctxScene");
            }

            TraverseDirect(ctx, ctxScene, _TraverseDrawContext, null);
        }
Пример #17
0
        public void PostObject(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject)
        {
            if (sceneObject == null)
            {
                throw new ArgumentNullException("sceneObject");
            }

            if (sceneObject.ObjectType == SceneObjectLightZone.ClassObjectType)
            {
                PostObject(ctx, ctxScene, (SceneObjectLightZone)sceneObject);
            }
        }
Пример #18
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();
            TransformState   sceneGeometryModel = (TransformState)currentState[TransformState.StateSetIndex];
            Matrix4x4f       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));
            }
        }
        /// <summary>
        /// Create the corresponding <see cref="LightsState.Light"/> for this object.
        /// </summary>
        /// <returns>
        /// It returns the <see cref="LightsState.Light"/> equivalent to this SceneObjectLight.
        /// </returns>
        public override LightsState.Light ToLight(GraphicsContext ctx, SceneGraphContext sceneCtx)
        {
            LightsState.LightDirectional light = new LightsState.LightDirectional();

            SetLightParameters(sceneCtx, light);

            TransformState transformState = (TransformState)sceneCtx.GraphicsStateStack.Current[TransformState.StateSetIndex];
            Matrix3x3f     normalMatrix   = transformState.NormalMatrix;

            light.Direction  = (normalMatrix * (Vertex3f)Direction).Normalized;
            light.HalfVector = (Vertex3f.UnitZ + light.Direction).Normalized;

            return(light);
        }
Пример #20
0
        /// <summary>
        /// Traverse delegate for creating resources.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for creating resources.
        /// </param>
        /// <param name="ctxScene"></param>
        /// <param name="sceneObject"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private static bool CreateDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            SceneObjectGeometry sceneGeometry = sceneObject as SceneObjectGeometry;

            if (sceneGeometry != null)
            {
                GraphicsStateSet sceneGeometryState = ctxScene.GraphicsStateStack.Current;

                sceneGeometry.Create(ctx);
                sceneGeometryState.Create(ctx, sceneGeometry.Program);
            }

            return(true);
        }
Пример #21
0
        /// <summary>
        /// Create the corresponding <see cref="LightsState.Light"/> for this object.
        /// </summary>
        /// <returns>
        /// It returns the <see cref="LightsState.Light"/> equivalent to this SceneObjectLight.
        /// </returns>
        public override LightsState.Light ToLight(SceneGraphContext sceneCtx)
        {
            LightsState.LightDirectional light = new LightsState.LightDirectional();

            SetLightParameters(sceneCtx, light);

            // Note: avoiding to invert the view matrix twice
            IMatrix3x3 normalMatrix = sceneCtx.CurrentView.LocalModel.GetComplementMatrix(3, 3).Transpose();

            light.Direction  = ((Vertex3f)normalMatrix.Multiply((Vertex3f)Direction)).Normalized;
            light.HalfVector = (Vertex3f.UnitZ + light.Direction).Normalized;

            return(light);
        }
Пример #22
0
        private void ManageObject(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObjectLightZone sceneObject)
        {
            if (sceneObject == null)
            {
                throw new ArgumentNullException("sceneObject");
            }

            if (_LightState.Count == 1)
            {
                ShadowLights.Clear();
            }
            _LightState.Push(new State.LightsState());

            ctxScene.GraphicsStateStack.Current.DefineState(CurrentZone);
        }
Пример #23
0
        /// <summary>
        /// Actually create this GraphicsResource resources.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> used for allocating resources.
        /// </param>
        /// <remarks>
        /// All resources linked with <see cref="LinkResource(IGraphicsResource)"/> will be automatically created.
        /// </remarks>
        protected override void CreateObject(GraphicsContext ctx)
        {
            // Bounding volume program
            LinkResource(_BoundingVolumeProgram = ctx.CreateProgram("OpenGL.Standard"));
            // Bounding volume arrays
            LinkResource(_BoundingBoxArray = CreateBBoxVertexArray());

            // Base implementation
            base.CreateObject(ctx);

            // Collect geometries to be batched
            using (SceneGraphContext ctxScene = new SceneGraphContext(this)) {
                TraverseDirect(ctx, ctxScene, _TraverseCreateContext, null);
            }
        }
Пример #24
0
        private static bool GraphDrawPostDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            ObjectBatchContext objectBatchContext = (ObjectBatchContext)data;

            // Restore previous state
            ctxScene.GraphicsStateStack.Pop();

            // Perform lighting
            if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.Lighting) != 0)
            {
                ctxScene.Scene._LightManager.PostObject(ctx, ctxScene, sceneObject);
            }

            return(true);
        }
Пример #25
0
        /// <summary>
        /// Traverse delegate for collecting geometries to be drawn.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        /// <param name="ctxScene"></param>
        /// <param name="sceneObject"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private static bool GraphDrawDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            ObjectBatchContext objectBatchContext = (ObjectBatchContext)data;

            if (sceneObject.ObjectType == SceneObjectGeometry.ClassObjectType)
            {
                SceneObjectGeometry sceneGeometry      = (SceneObjectGeometry)sceneObject;
                GraphicsStateSet    sceneGeometryState = ctxScene.GraphicsStateStack.Current;
                TransformStateBase  sceneGeometryModel = (TransformStateBase)sceneGeometryState[TransformStateBase.StateSetIndex];

                IEnumerable <SceneObjectBatch> geometries;

                if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.CullingViewFrustum) != 0)
                {
                    // View-frustum culling
                    geometries = sceneGeometry.GetGeometries(sceneGeometryState, objectBatchContext.ViewFrustumPlanes, sceneGeometryModel.ModelView);
                }
                else
                {
                    // All geometries
                    geometries = sceneGeometry.GetGeometries(sceneGeometryState);
                }

                objectBatchContext.Objects.AddRange(geometries);

                // Bounding volumes
                if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.BoundingVolumes) != 0)
                {
                }
            }
            else if (sceneObject.ObjectType == SceneObjectLightZone.ClassObjectType)
            {
                SceneObjectLightZone sceneObjectLightZone = (SceneObjectLightZone)sceneObject;

                // TODO: Push instead of Clear to support stacked zones
                objectBatchContext.Lights.Clear();
                objectBatchContext.LightZone = sceneObjectLightZone;
            }
            else if (sceneObject.ObjectType == SceneObjectLight.ClassObjectType)
            {
                objectBatchContext.Lights.Add((SceneObjectLight)sceneObject);
            }

            return(true);
        }
Пример #26
0
        private static bool GraphDrawPostDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            ObjectBatchContext objectBatchContext = (ObjectBatchContext)data;

            if (sceneObject.ObjectType == SceneObjectLightZone.ClassObjectType)
            {
                SceneObjectLightZone sceneObjectLightZone = (SceneObjectLightZone)sceneObject;

                sceneObjectLightZone.ResetLights(ctxScene, objectBatchContext.Lights);
                // TODO: Pop instead of Clear to support stacked zones
                objectBatchContext.Lights.Clear();
            }

            // Restore previous state
            ctxScene.GraphicsStateStack.Pop();

            return(true);
        }
Пример #27
0
        internal IEnumerable <SceneObjectBatch> GetBoundingVolumes(SceneGraphContext ctxScene)
        {
            GraphicsStateSet currentState       = ctxScene.GraphicsStateStack.Current.Push();
            TransformState   sceneGeometryModel = (TransformState)currentState[TransformState.StateSetIndex];
            Matrix4x4f       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));
            }
        }
Пример #28
0
        /// <summary>
        /// Draw this SceneGraph.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        /// <param name="programOverride">
        /// A <see cref="ShaderProgram"/> that overrides the default one used for rendering the batch. It can be null.
        /// </param>
        public void Draw(GraphicsContext ctx, ShaderProgram programOverride)
        {
            CheckCurrentContext(ctx);

            // View parameters
            SceneRoot.LocalProjection          = ProjectionMatrix;
            SceneRoot.LocalModel               = new ModelMatrix();
            SceneRoot.LocalModelView           = ViewMatrix;
            SceneRoot.LocalModelViewProjection = new ModelMatrix((Matrix4x4)ProjectionMatrix.Multiply(ViewMatrix));

            using (SceneGraphContext ctxScene = new SceneGraphContext(this)) {
                ObjectBatchContext objectBatchContext = new ObjectBatchContext();

                // Traverse the scene graph
                SceneRoot.TraverseDirect(ctx, ctxScene, _TraverseDrawContext, objectBatchContext);
                // Generate shadow maps
                if ((SceneFlags & SceneGraphFlags.Lighting) != 0 && (SceneFlags & SceneGraphFlags.ShadowMaps) != 0)
                {
                    _LightManager.GenerateShadowMaps(ctx, this);
                }

                // Sort geometries
                List <SceneObjectBatch> sceneObjects = objectBatchContext.Objects;
                if (((SceneFlags & SceneGraphFlags.StateSorting) != 0) && (_SorterRoot != null))
                {
                    sceneObjects = _SorterRoot.Sort(objectBatchContext.Objects);
                }

                // Draw all batches
                KhronosApi.LogComment("*** Draw Graph");
                foreach (SceneObjectBatch objectBatch in sceneObjects)
                {
                    objectBatch.Draw(ctx, programOverride);
                }

                // Debug: shadow maps
                if ((SceneFlags & SceneGraphFlags.Lighting) != 0 && (SceneFlags & SceneGraphFlags.ShadowMaps) != 0)
                {
                    DisplayShadowMaps(ctx);
                }
            }
        }
Пример #29
0
        /// <summary>
        /// Traverse delegate for collecting geometries to be drawn.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        /// <param name="ctxScene"></param>
        /// <param name="sceneObject"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private static bool GraphDrawDelegate(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObject sceneObject, object data)
        {
            ObjectBatchContext objectBatchContext = (ObjectBatchContext)data;

            // Collect available geometries
            IEnumerable <SceneObjectBatch> geometries = sceneObject.GetGeometries(ctx, ctxScene);

            if (geometries != null)
            {
                objectBatchContext.Objects.AddRange(geometries);
            }

            // Perform lighting
            if ((ctxScene.Scene.SceneFlags & SceneGraphFlags.Lighting) != 0)
            {
                ctxScene.Scene._LightManager.ManageObject(ctx, ctxScene, sceneObject);
            }

            return(true);
        }
Пример #30
0
        private void ManageObject(GraphicsContext ctx, SceneGraphContext ctxScene, SceneObjectLight sceneObject)
        {
            if (sceneObject == null)
            {
                throw new ArgumentNullException("sceneObject");
            }

            State.LightsState.Light lightObject = sceneObject.ToLight(ctx, ctxScene);

            CurrentZone.Lights.Add(lightObject);

            if (sceneObject.HasShadowMap)
            {
                lightObject.ShadowMapIndex = ShadowLights.Count;
                if (ShadowLights.Contains(sceneObject) == false)
                {
                    ShadowLights.Add(sceneObject);
                }
            }
        }