/// <summary>
        /// Updades all subscription info for given subscription row.
        /// This method is needed because 'RenderPassSubscription" is a struct and values are changed by host object.
        /// </summary>
        /// <param name="newSubscriptionInfo">The subscription information passed by host object.</param>
        /// <param name="layerViewSubset">The host object.</param>
        internal void UpdateSubscription(RenderPassSubscription newSubscriptionInfo, ViewRelatedSceneLayerSubset layerViewSubset)
        {
            // Get the subscription list
            // (may be null if object was removed from the layer)
            List <RenderPassSubscription> subscriptionList = m_viewRelatedSubscriptions[layerViewSubset.ViewIndex];

            if (subscriptionList == null)
            {
                return;
            }

            // Update the corresponding subscription entry
            int subscriptionCount = subscriptionList.Count;
            int entryCount        = 0;

            for (int loop = 0; loop < subscriptionCount; loop++)
            {
                RenderPassSubscription currentSubscriptionInfo = subscriptionList[loop];
                if ((currentSubscriptionInfo.SceneObject == newSubscriptionInfo.SceneObject) &&
                    (currentSubscriptionInfo.RenderPass == newSubscriptionInfo.RenderPass) &&
                    (currentSubscriptionInfo.RenderMethod == newSubscriptionInfo.RenderMethod))
                {
                    subscriptionList[loop] = newSubscriptionInfo;
                    entryCount++;
                }
            }
            if (entryCount > 1)
            {
                throw new SeeingSharpGraphicsException("Inconsistency: Too much subscriptions for SceneObject detected!");
            }
        }
        /// <summary>
        /// Clears all subscriptions on the given view subset.
        /// Only for internal use.. this method gets called when a view is deregistered.
        /// </summary>
        internal void ClearSubscriptionsWithoutUnsubscribeCall(ViewRelatedSceneLayerSubset layerViewSubset, RenderPassSubscription subscription)
        {
            // Get the subscription list
            // (may be null if object was removed from the layer)
            List <RenderPassSubscription> subscriptionList = m_viewRelatedSubscriptions[layerViewSubset.ViewIndex];

            if (subscriptionList == null)
            {
                return;
            }

            // Remove the given entry from subscription list
            int subscriptionCount = subscriptionList.Count;
            int entryCount        = 0;

            for (int loop = 0; loop < subscriptionCount; loop++)
            {
                RenderPassSubscription currentSubscriptionInfo = subscriptionList[loop];
                if ((currentSubscriptionInfo.SceneObject == subscription.SceneObject) &&
                    (currentSubscriptionInfo.RenderPass == subscription.RenderPass) &&
                    (currentSubscriptionInfo.RenderMethod == subscription.RenderMethod))
                {
                    subscriptionList.RemoveAt(loop);
                    loop--;
                    subscriptionCount--;
                    entryCount++;
                }
            }
            if (entryCount > 1)
            {
                throw new SeeingSharpGraphicsException("Inconsistency: Too much subscriptions for SceneObject detected!");
            }
        }
示例#3
0
        /// <summary>
        /// Unsubscribes the given object from the given render pass.
        /// </summary>
        internal void UnsubscribeForPass(RenderPassSubscription subscription)
        {
            if (!m_isSubscribeUnsubscribeAllowed)
            {
                throw new SeeingSharpException("Subscription is not allowed currently!");
            }

            if (subscription.IsSubscribed)
            {
                // Set unsubscribed flag
                m_anythingUnsubscribed = true;

                // Register unsubscription call
                var subscriptionInfo = m_objectsPerPassDict[subscription.RenderPass];

                subscriptionInfo.UnsubscribeCallCount++;

                // Update subscription info and reinsert it on the pass collection
                subscription.IsSubscribed = false;
                subscriptionInfo.Subscriptions[subscription.SubscriptionIndex] = subscription;

                // Post changes to the scene object holding this info too
                subscription.SceneObject.UpdateSubscription(subscription, this);
            }
        }
示例#4
0
        /// <summary>
        /// Rendering logic for lines renderings.
        /// </summary>
        private void RenderPass(
            RenderPassBase renderPass, PassSubscribionProperties subscriptions,
            RenderState renderState, ref List <SceneObject> invalidObjects)
        {
            if (subscriptions.Subscriptions.Count > 0)
            {
                if (renderPass != null)
                {
                    //Ensure loaded resources for transparency pass
                    if (!renderPass.IsLoaded)
                    {
                        renderPass.LoadResource();
                    }

                    //Render all subscriptions
                    renderPass.Apply(renderState);
                }
                try
                {
                    int subscriptionCount = subscriptions.Subscriptions.Count;
                    for (int loopPass = 0; loopPass < subscriptionCount; loopPass++)
                    {
                        RenderPassSubscription actSubscription = subscriptions.Subscriptions[loopPass];
                        try
                        {
                            actSubscription.RenderMethod(renderState);
                        }
                        catch (Exception ex)
                        {
                            GraphicsCore.PublishInternalExceptionInfo(
                                ex, InternalExceptionLocation.Rendering3DObject);

                            // Mark this object as invalid
                            if (invalidObjects == null)
                            {
                                invalidObjects = new List <SceneObject>();
                            }
                            invalidObjects.Add(actSubscription.SceneObject);
                        }
                    }
                }
                finally
                {
                    if (renderPass != null)
                    {
                        renderPass.Discard(renderState);
                    }
                }
            }
        }
示例#5
0
        /// <summary>
        /// Subscribes the given object to the given render pass.
        /// </summary>
        internal RenderPassSubscription SubscribeForPass(
            RenderPassInfo passInfo,
            SceneObject sceneObject, Action <RenderState> renderMethod,
            int zOrder)
        {
            if (!m_isSubscribeUnsubscribeAllowed)
            {
                throw new SeeingSharpException("Subscription is not allowed currently!");
            }

            var subscriptionProperties = m_objectsPerPassDict[passInfo];

            // Append new subscription to subscription list
            List <RenderPassSubscription> subscriptions = subscriptionProperties.Subscriptions;
            int subscriptionsCount = subscriptions.Count;
            RenderPassSubscription newSubscription = new RenderPassSubscription(this, passInfo, sceneObject, renderMethod, zOrder);

            if (!passInfo.IsSorted)
            {
                // No sort, so put the new subscription to the end of the collection
                newSubscription.SubscriptionIndex = subscriptionsCount;
                subscriptions.Add(newSubscription);
            }
            else
            {
                // Perform BinaryInsert to the correct position
                int newIndex = CommonTools.BinaryInsert(subscriptions, newSubscription, SubscriptionZOrderComparer.Instance);

                // Increment all subscription indices after the inserted position
                subscriptionsCount++;
                RenderPassSubscription actSubscription;
                for (int loop = newIndex; loop < subscriptionsCount; loop++)
                {
                    actSubscription = subscriptions[loop];
                    if (actSubscription.SubscriptionIndex != loop)
                    {
                        actSubscription.SubscriptionIndex = loop;
                        subscriptions[loop] = actSubscription;

                        actSubscription.SceneObject.UpdateSubscription(actSubscription, this);
                    }
                }
                newSubscription = subscriptions[newIndex];
            }

            return(newSubscription);
        }
示例#6
0
        /// <summary>
        /// Executes view update using the given update state object.
        /// </summary>
        /// <param name="updateState">The update state.</param>
        internal void UpdateForView(SceneRelatedUpdateState updateState)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("ViewRelatedLayerSubset");
            }

            // TODO: Trigger some other logic to update transparent object order
            // TODO: Performance improvement!!!
            bool         anyOrderChanges = false;
            Camera3DBase camera          = m_viewInformation.Camera;

            m_objectsPassTransparentRender.Subscriptions.Sort(new Comparison <RenderPassSubscription>((left, right) =>
            {
                SceneSpacialObject leftSpacial  = left.SceneObject as SceneSpacialObject;
                SceneSpacialObject rightSpacial = right.SceneObject as SceneSpacialObject;
                if ((leftSpacial != null) && (rightSpacial != null))
                {
                    float leftDistance  = (camera.Position - leftSpacial.Position).LengthSquared();
                    float rightDistance = (camera.Position - rightSpacial.Position).LengthSquared();
                    anyOrderChanges     = true;
                    return(rightDistance.CompareTo(leftDistance));
                }
                else if (leftSpacial != null)
                {
                    anyOrderChanges = true; return(-1);
                }
                else if (rightSpacial != null)
                {
                    anyOrderChanges = true; return(1);
                }
                {
                    return(0);
                }
            }));
            if (anyOrderChanges)
            {
                // Synchronize ordering changes with corresponding scene object
                for (int loop = 0; loop < m_objectsPassTransparentRender.Subscriptions.Count; loop++)
                {
                    var actSubscription = m_objectsPassTransparentRender.Subscriptions[loop];
                    actSubscription.SubscriptionIndex = loop;
                    actSubscription.SceneObject.UpdateSubscription(actSubscription, this);
                    m_objectsPassTransparentRender.Subscriptions[loop] = actSubscription;
                }
            }

            // Update all objects related to this view
            m_isSubscribeUnsubscribeAllowed = true;
            try
            {
                // Update subscriptions based on visibility check result
                if (m_changedVisibilitiesAction != null)
                {
                    m_changedVisibilitiesAction();
                    m_changedVisibilitiesAction = null;
                }

                // Unsubscribe all invalid objects
                SceneObject actInvalidObject = null;
                while (m_invalidObjectsToDeregister.Count > 0)
                {
                    actInvalidObject = m_invalidObjectsToDeregister.Dequeue();
                    actInvalidObject.UnsubsribeFromAllPasses(this);
                }

                // Update subsccriptions based on boject state
                List <SceneObject> allObjects = m_sceneLayer.ObjectsInternal;
                int allObjectsLength          = allObjects.Count;
                int visibleObjectCount        = m_viewInformation.Owner.VisibleObjectCountInternal;
                for (int loop = 0; loop < allObjectsLength; loop++)
                {
                    SceneObject actSceneObject = allObjects[loop];
                    if (m_invalidObjects.ContainsKey(actSceneObject))
                    {
                        continue;
                    }

                    if (actSceneObject.IsLayerViewSubsetRegistered(this.ViewIndex) &&
                        actSceneObject.IsVisible(m_viewInformation))
                    {
                        actSceneObject.UpdateForView(updateState, this);
                        visibleObjectCount++;
                    }
                }
                m_viewInformation.Owner.VisibleObjectCountInternal = visibleObjectCount;
            }
            finally
            {
                m_isSubscribeUnsubscribeAllowed = false;
            }

            // Reorganize subscriptions if there is anything unsubscribed
            if (m_anythingUnsubscribed)
            {
                m_anythingUnsubscribed = false;
                foreach (var actPassProperties in m_objectsPerPass)
                {
                    if (actPassProperties.UnsubscribeCallCount <= 0)
                    {
                        continue;
                    }

                    // Variables for consistency checking
                    int givenUnsubscribeCount = actPassProperties.UnsubscribeCallCount;
                    int trueUnsubscribeCount  = 0;

                    // Handle case where we have unsubscribed some
                    //  => Build new subscription list and ignore all whith 'IsSubscribed' == false
                    List <RenderPassSubscription> newSubscriptionList = new List <RenderPassSubscription>(
                        (actPassProperties.Subscriptions.Count - actPassProperties.UnsubscribeCallCount) + 128);
                    for (int loop = 0; loop < actPassProperties.Subscriptions.Count; loop++)
                    {
                        RenderPassSubscription actSubscription = actPassProperties.Subscriptions[loop];
                        if (!actSubscription.IsSubscribed)
                        {
                            actSubscription.SceneObject.ClearSubscriptionsWithoutUnsubscribeCall(this, actSubscription);
                            trueUnsubscribeCount++;
                            continue;
                        }

                        // Add this item to new subscription list
                        actSubscription.SubscriptionIndex = newSubscriptionList.Count;
                        newSubscriptionList.Add(actSubscription);

                        actSubscription.SceneObject.UpdateSubscription(actSubscription, this);
                    }
                    actPassProperties.Subscriptions        = newSubscriptionList;
                    actPassProperties.UnsubscribeCallCount = 0;

                    // Check for consistency: Does unsubscribe-count match true unsubscriptions using IsSubscribed flag
                    if (givenUnsubscribeCount != trueUnsubscribeCount)
                    {
                        throw new SeeingSharpException("Inconsistency: Given unsubscribe count does not mach true count of unsubscriptions!");
                    }
                }
            }
        }