コード例 #1
0
    //-----------------------------------------------------------------------
	void QueuedRenderableCollection::sort(const Camera* cam)
    {
		// ascending and descending sort both set bit 1
		if (mOrganisationMode & OM_SORT_DESCENDING)
		{
			
			// We can either use a stable_sort and the 'less' implementation,
			// or a 2-pass radix sort (once by pass, then by distance, since
			// radix sorting is inherently stable this will work)
			// We use stable_sort if the number of items is 512 or less, since
			// the complexity of the radix sort is approximately O(10N), since 
			// each sort is O(5N) (1 pass histograms, 4 passes sort)
			// Since stable_sort has a worst-case performance of O(N(logN)^2)
			// the performance tipping point is from about 1500 items, but in
			// stable_sorts best-case scenario O(NlogN) it would be much higher.
			// Take a stab at 2000 items.
			
			if (mSortedDescending.size() > 2000)
			{
				// sort by pass
				msRadixSorter1.sort(mSortedDescending, RadixSortFunctorPass());
				// sort by depth
				msRadixSorter2.sort(mSortedDescending, RadixSortFunctorDistance(cam));
			}
			else
			{
				std::stable_sort(
					mSortedDescending.begin(), mSortedDescending.end(), 
					DepthSortDescendingLess(cam));
			}
		}

		// Nothing needs to be done for pass groups, they auto-organise

    }
コード例 #2
0
    //-----------------------------------------------------------------------
	void QueuedRenderableCollection::sort(const Camera* cam)
    {
		// ascending and descending sort both set bit 1
		// We always sort descending, becuase the only difference is in the
		// acceptVisitor method, where we iterate in reverse in ascending mode
		if (mOrganisationMode & OM_SORT_DESCENDING)
		{
			
			// We can either use a stable_sort and the 'less' implementation,
			// or a 2-pass radix sort (once by pass, then by distance, since
			// radix sorting is inherently stable this will work)
			// We use stable_sort if the number of items is 512 or less, since
			// the complexity of the radix sort is approximately O(10N), since 
			// each sort is O(5N) (1 pass histograms, 4 passes sort)
			// Since stable_sort has a worst-case performance of O(N(logN)^2)
			// the performance tipping point is from about 1500 items, but in
			// stable_sorts best-case scenario O(NlogN) it would be much higher.
			// Take a stab at 2000 items.
		  bool performRadixSort = mSortedDescending.size() > 2000;
		  if (performRadixSort)
			{
				// sort by pass
				msRadixSorter1.sort(mSortedDescending, RadixSortFunctorPass());
				// sort by depth
				msRadixSorter2.sort(mSortedDescending, RadixSortFunctorDistance(cam));
			}
			else
			{
				std::stable_sort(
					mSortedDescending.begin(), mSortedDescending.end(), 
					DepthSortDescendingLess(cam));
			}
			/*
      #ManuallySpecifyingRenderOrder
      
      For a given renderable, we introduced a hack that lets you say it renders either immediately before or after another renderable. We do this by readjusting the render order after Ogre's depth sort.
        
        Caveats:
        * items must be in the same render queue
        * items must be in the same sub-render queue (in our case, everything is in the transparency bucket)
       
	*/
		  if (performRadixSort)
			for (int i = 0; i < mSortedDescending.size(); i++) {
			  Renderable* renderable1 = mSortedDescending[i].renderable;

			  int inc = renderable1->renderAfterOtherRenderable() ? 1 : -1;
        
			  // If we've manually specified the render order, fix renderable1's render position
			  // We modified the sort algorithms in OgreRenderQueueSortingGrouping.h so that the depth of renderable1 is the 
			  //    same as the renderable it's tied to; all we have to do is swap renderable1 with the renderable it's
			  //    tied to (unless it's in the correct order, in which case we do nothing at all)
			  if (renderable1->renderOrderTiedToOtherRenderable()) {
			    Real depth1 = renderable1->getSquaredViewDepth(cam);
    
			    for (int j = i + inc;
				 0 <= j && j < mSortedDescending.size();
				 j += inc) {
			      Renderable* renderable2 = mSortedDescending[j].renderable;
			      if (renderable2 == renderable1->getRenderableToRenderNextTo()) {
				// swap the two values
				RenderablePass rp = mSortedDescending[i];
				mSortedDescending[i] = mSortedDescending[j];
				mSortedDescending[j] = rp;
				break;
			      }
			      // We know that the renderable that renderable1 is tied to has the same depth as renderable1, so if we've reached items
			      //    with different depths, we can quit the loop (the items must have already been in the correct order)
			      if (Math::RealEqual(renderable2->getSquaredViewDepth(cam), depth1))
				break;
			    }
			  }
			}
		}

		// Nothing needs to be done for pass groups, they auto-organise

    }