예제 #1
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);
                }
            }
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
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);
                }
            }
        }
예제 #6
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);
        }