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); } } }
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); }
/// <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); }
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); }
/// <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); } } }
/// <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); }