377 lines
15 KiB
C++
377 lines
15 KiB
C++
/**************************************************************************************/
|
|
/* */
|
|
/* Visualization Library */
|
|
/* http://visualizationlibrary.org */
|
|
/* */
|
|
/* Copyright (c) 2005-2020, Michele Bosi */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* Redistribution and use in source and binary forms, with or without modification, */
|
|
/* are permitted provided that the following conditions are met: */
|
|
/* */
|
|
/* - Redistributions of source code must retain the above copyright notice, this */
|
|
/* list of conditions and the following disclaimer. */
|
|
/* */
|
|
/* - Redistributions in binary form must reproduce the above copyright notice, this */
|
|
/* list of conditions and the following disclaimer in the documentation and/or */
|
|
/* other materials provided with the distribution. */
|
|
/* */
|
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
|
|
/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
|
|
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
|
|
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
|
|
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
|
|
/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
|
|
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
|
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
|
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
|
|
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|
/* */
|
|
/**************************************************************************************/
|
|
|
|
#ifndef RenderQueueSorter_INCLUDE_ONCE
|
|
#define RenderQueueSorter_INCLUDE_ONCE
|
|
|
|
#include <vlGraphics/RenderToken.hpp>
|
|
|
|
namespace vl
|
|
{
|
|
//------------------------------------------------------------------------------
|
|
// RenderQueueSorter
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
* The RenderQueueSorter class is the abstract base class of all the algorithms used to sort a set of RenderToken.
|
|
*/
|
|
class RenderQueueSorter: public Object
|
|
{
|
|
VL_INSTRUMENT_ABSTRACT_CLASS(vl::RenderQueueSorter, Object)
|
|
|
|
public:
|
|
RenderQueueSorter()
|
|
{
|
|
VL_DEBUG_SET_OBJECT_NAME()
|
|
}
|
|
virtual bool operator()(const RenderToken* a, const RenderToken* b) const = 0;
|
|
virtual bool confirmZCameraDistanceNeed(const RenderToken*) const = 0;
|
|
virtual bool mightNeedZCameraDistance() const = 0;
|
|
};
|
|
//------------------------------------------------------------------------------
|
|
// RenderQueueSorterByShader
|
|
//------------------------------------------------------------------------------
|
|
//! Sorts the RenderTokens by their Shader pointer.
|
|
// no z sort, no effect render rank, no actor render rank
|
|
class RenderQueueSorterByShader: public RenderQueueSorter
|
|
{
|
|
VL_INSTRUMENT_CLASS(vl::RenderQueueSorterByShader, RenderQueueSorter)
|
|
|
|
public:
|
|
RenderQueueSorterByShader()
|
|
{
|
|
VL_DEBUG_SET_OBJECT_NAME()
|
|
}
|
|
virtual bool mightNeedZCameraDistance() const { return false; }
|
|
virtual bool confirmZCameraDistanceNeed(const RenderToken*) const { return false; }
|
|
virtual bool operator()(const RenderToken* a, const RenderToken* b) const
|
|
{
|
|
return a->mShader < b->mShader;
|
|
}
|
|
};
|
|
//------------------------------------------------------------------------------
|
|
// RenderQueueSorterByRenderable
|
|
//------------------------------------------------------------------------------
|
|
//! Sorts the RenderTokens by their Renderable pointer.
|
|
// no z sort, no effect render rank, no actor render rank
|
|
class RenderQueueSorterByRenderable: public RenderQueueSorter
|
|
{
|
|
VL_INSTRUMENT_CLASS(vl::RenderQueueSorterByRenderable, RenderQueueSorter)
|
|
|
|
public:
|
|
RenderQueueSorterByRenderable()
|
|
{
|
|
VL_DEBUG_SET_OBJECT_NAME()
|
|
}
|
|
virtual bool mightNeedZCameraDistance() const { return false; }
|
|
virtual bool confirmZCameraDistanceNeed(const RenderToken*) const { return false; }
|
|
virtual bool operator()(const RenderToken* a, const RenderToken* b) const
|
|
{
|
|
return a->mRenderable < b->mRenderable;
|
|
}
|
|
};
|
|
//------------------------------------------------------------------------------
|
|
// RenderQueueSorterBasic
|
|
//------------------------------------------------------------------------------
|
|
//! Sorts the RenderTokens by their Effect rank -> Actor rank -> Shader pointer -> Renderable pointer
|
|
class RenderQueueSorterBasic: public RenderQueueSorter
|
|
{
|
|
VL_INSTRUMENT_CLASS(vl::RenderQueueSorterBasic, RenderQueueSorter)
|
|
|
|
public:
|
|
RenderQueueSorterBasic()
|
|
{
|
|
VL_DEBUG_SET_OBJECT_NAME()
|
|
}
|
|
virtual bool mightNeedZCameraDistance() const { return true; }
|
|
virtual bool confirmZCameraDistanceNeed(const RenderToken*) const { return false; }
|
|
virtual bool operator()(const RenderToken* a, const RenderToken* b) const
|
|
{
|
|
// Actor's render-block
|
|
if (a->mActor->renderBlock() != b->mActor->renderBlock())
|
|
return a->mActor->renderBlock() < b->mActor->renderBlock();
|
|
else
|
|
// Effect's render-rank
|
|
if (a->mEffectRenderRank != b->mEffectRenderRank)
|
|
return a->mEffectRenderRank < b->mEffectRenderRank;
|
|
else
|
|
// Actor's render-rank
|
|
if (a->mActor->renderRank() != b->mActor->renderRank())
|
|
return a->mActor->renderRank() < b->mActor->renderRank();
|
|
else
|
|
// shader sorting
|
|
if (a->mShader != b->mShader)
|
|
return a->mShader < b->mShader;
|
|
// renderable sorting
|
|
else
|
|
return a->mRenderable < b->mRenderable;
|
|
}
|
|
};
|
|
//------------------------------------------------------------------------------
|
|
// RenderQueueSorterStandard
|
|
//------------------------------------------------------------------------------
|
|
//! Implements the default RenderQueueSorter.
|
|
//! Sorts the RenderTokens by:
|
|
//! -# Actor render block
|
|
//! -# Effect render rank
|
|
//! -# Actor render rank
|
|
//! -# Solid objects first, translucent objects last
|
|
//! -# Sort translucent objects back-to-front
|
|
//! -# Sort solid objects by Shader
|
|
//! -# Sort solid objects by Renderable
|
|
class RenderQueueSorterStandard: public RenderQueueSorter
|
|
{
|
|
VL_INSTRUMENT_CLASS(vl::RenderQueueSorterStandard, RenderQueueSorter)
|
|
|
|
public:
|
|
RenderQueueSorterStandard(): mDepthSortMode(AlphaDepthSort)
|
|
{
|
|
VL_DEBUG_SET_OBJECT_NAME()
|
|
}
|
|
|
|
virtual bool mightNeedZCameraDistance() const { return true; }
|
|
virtual bool confirmZCameraDistanceNeed(const RenderToken* a) const
|
|
{
|
|
return mDepthSortMode != NeverDepthSort && (mDepthSortMode == AlwaysDepthSort ||
|
|
(a->mShader->isBlendingEnabled() && (mDepthSortMode == AlphaDepthSort)) );
|
|
}
|
|
|
|
virtual bool operator()(const RenderToken* a, const RenderToken* b) const
|
|
{
|
|
// --------------- user defined sorting ---------------
|
|
|
|
// Actor's render-block
|
|
if (a->mActor->renderBlock() != b->mActor->renderBlock())
|
|
return a->mActor->renderBlock() < b->mActor->renderBlock();
|
|
else
|
|
// Effect's render-rank
|
|
if (a->mEffectRenderRank != b->mEffectRenderRank)
|
|
return a->mEffectRenderRank < b->mEffectRenderRank;
|
|
else
|
|
// Actor's render-rank
|
|
if (a->mActor->renderRank() != b->mActor->renderRank())
|
|
return a->mActor->renderRank() < b->mActor->renderRank();
|
|
else
|
|
|
|
// --------------- shader based sorting ---------------
|
|
|
|
if ( mDepthSortMode != AlwaysDepthSort && (a->mShader->isBlendingEnabled() != b->mShader->isBlendingEnabled()))
|
|
{
|
|
// first render opaque objects
|
|
return !a->mShader->isBlendingEnabled();
|
|
}
|
|
// A/b->mShader->isEnabled(OGL_BLEND) are equal or AlwaysDepthSort
|
|
else
|
|
if ( confirmZCameraDistanceNeed(a) )
|
|
{
|
|
// render first far objects then the close ones
|
|
return a->mCameraDistance > b->mCameraDistance;
|
|
}
|
|
else
|
|
|
|
/*// glsl
|
|
if ( a->mShader->glslProgram() != b->mShader->glslProgram() )
|
|
return a->mShader->glslProgram() < b->mShader->glslProgram();
|
|
else*/
|
|
|
|
/*sort by textures: removed*/
|
|
|
|
// shader sorting
|
|
if (a->mShader != b->mShader)
|
|
return a->mShader < b->mShader;
|
|
// renderable sorting
|
|
else
|
|
return a->mRenderable < b->mRenderable;
|
|
}
|
|
|
|
EDepthSortMode depthSortMode() const { return mDepthSortMode; }
|
|
void setDepthSortMode(EDepthSortMode mode) { mDepthSortMode = mode; }
|
|
|
|
public:
|
|
EDepthSortMode mDepthSortMode;
|
|
};
|
|
//------------------------------------------------------------------------------
|
|
// RenderQueueSorterOcclusion
|
|
//------------------------------------------------------------------------------
|
|
//! Implements a RenderQueueSorter that maximizes the z-buffer test efficiency as much as possible.
|
|
//! Sorts the RenderTokens by:
|
|
//! -# Actor render block
|
|
//! -# Effect render rank
|
|
//! -# Actor render rank
|
|
//! -# Solid objects first, translucent objects last
|
|
//! -# Sort solid objects front-to-back
|
|
//! -# Sort translucent objects back-to-front
|
|
class RenderQueueSorterOcclusion: public RenderQueueSorter
|
|
{
|
|
VL_INSTRUMENT_CLASS(vl::RenderQueueSorterOcclusion, RenderQueueSorter)
|
|
|
|
public:
|
|
RenderQueueSorterOcclusion()
|
|
{
|
|
VL_DEBUG_SET_OBJECT_NAME()
|
|
}
|
|
|
|
virtual bool mightNeedZCameraDistance() const { return true; }
|
|
virtual bool confirmZCameraDistanceNeed(const RenderToken*) const { return true; }
|
|
|
|
virtual bool operator()(const RenderToken* a, const RenderToken* b) const
|
|
{
|
|
// --------------- user defined sorting ---------------
|
|
|
|
// Actor's render-block
|
|
if (a->mActor->renderBlock() != b->mActor->renderBlock())
|
|
return a->mActor->renderBlock() < b->mActor->renderBlock();
|
|
else
|
|
// Effect's render-rank
|
|
if (a->mEffectRenderRank != b->mEffectRenderRank)
|
|
return a->mEffectRenderRank < b->mEffectRenderRank;
|
|
else
|
|
// Actor's render-rank
|
|
if (a->mActor->renderRank() != b->mActor->renderRank())
|
|
return a->mActor->renderRank() < b->mActor->renderRank();
|
|
else
|
|
|
|
// --------------- shader based sorting ---------------
|
|
|
|
if ( a->mShader->isBlendingEnabled() != b->mShader->isBlendingEnabled() )
|
|
{
|
|
// first render opaque objects
|
|
return !a->mShader->isBlendingEnabled();
|
|
}
|
|
else
|
|
// blending on: render first far objects then the close ones
|
|
if ( a->mShader->isBlendingEnabled() )
|
|
{
|
|
return a->mCameraDistance > b->mCameraDistance;
|
|
}
|
|
else
|
|
// blending off: render first close objects then far ones -> i.e. -> if ( !a->mShader->isBlendingEnabled() )
|
|
if (a->mCameraDistance != b->mCameraDistance)
|
|
{
|
|
return a->mCameraDistance < b->mCameraDistance;
|
|
}
|
|
else
|
|
// shader sorting
|
|
if (a->mShader != b->mShader)
|
|
return a->mShader < b->mShader;
|
|
// renderable sorting
|
|
else
|
|
return a->mRenderable < b->mRenderable;
|
|
}
|
|
};
|
|
//------------------------------------------------------------------------------
|
|
// RenderQueueSorterAggressive
|
|
//------------------------------------------------------------------------------
|
|
//! Sorts the RenderTokens by Effect rank -> Actor rank -> blending on/off -> Z distance form the Camera ->
|
|
//! GLSL program -> render state set -> enable set -> texture set -> light set -> Shader pointer -> Renderable pointer
|
|
class RenderQueueSorterAggressive: public RenderQueueSorter
|
|
{
|
|
VL_INSTRUMENT_CLASS(vl::RenderQueueSorterAggressive, RenderQueueSorter)
|
|
|
|
public:
|
|
RenderQueueSorterAggressive(): mDepthSortMode(AlphaDepthSort)
|
|
{
|
|
VL_DEBUG_SET_OBJECT_NAME()
|
|
}
|
|
|
|
virtual bool mightNeedZCameraDistance() const { return true; }
|
|
virtual bool confirmZCameraDistanceNeed(const RenderToken* a) const
|
|
{
|
|
return mDepthSortMode != NeverDepthSort &&
|
|
(mDepthSortMode == AlwaysDepthSort || (a->mShader->isBlendingEnabled() && (mDepthSortMode == AlphaDepthSort)) );
|
|
}
|
|
|
|
virtual bool operator()(const RenderToken* a, const RenderToken* b) const
|
|
{
|
|
// --------------- user defined sorting ---------------
|
|
|
|
// Actor's render-block
|
|
if (a->mActor->renderBlock() != b->mActor->renderBlock())
|
|
return a->mActor->renderBlock() < b->mActor->renderBlock();
|
|
else
|
|
// Effect's render-rank
|
|
if (a->mEffectRenderRank != b->mEffectRenderRank)
|
|
return a->mEffectRenderRank < b->mEffectRenderRank;
|
|
else
|
|
// Actor's render-rank
|
|
if (a->mActor->renderRank() != b->mActor->renderRank())
|
|
return a->mActor->renderRank() < b->mActor->renderRank();
|
|
else
|
|
|
|
// --------------- shader based sorting ---------------
|
|
|
|
if ( mDepthSortMode != AlwaysDepthSort && (a->mShader->isBlendingEnabled() != b->mShader->isBlendingEnabled()))
|
|
{
|
|
return !a->mShader->isBlendingEnabled(); // first render opaque objects
|
|
}
|
|
else // A/b->mShader->isEnabled(OGL_BLEND) are equal or AlwaysDepthSort
|
|
if ( confirmZCameraDistanceNeed(a) )
|
|
{
|
|
return a->mCameraDistance > b->mCameraDistance; // render first far objects then the close ones
|
|
}
|
|
else
|
|
|
|
// glsl
|
|
if ( a->mShader->glslProgram() != b->mShader->glslProgram() )
|
|
return a->mShader->glslProgram() < b->mShader->glslProgram();
|
|
else
|
|
|
|
// render state set
|
|
if ( a->mShader->getRenderStateSet() != b->mShader->getRenderStateSet() )
|
|
return a->mShader->getRenderStateSet() < b->mShader->getRenderStateSet();
|
|
else
|
|
|
|
// enables
|
|
if ( a->mShader->getEnableSet() != b->mShader->getEnableSet() )
|
|
return a->mShader->getEnableSet() < b->mShader->getEnableSet();
|
|
else
|
|
|
|
/*sort by textures: removed*/
|
|
|
|
/*sort by lights: removed*/
|
|
|
|
// shader sorting
|
|
if (a->mShader != b->mShader)
|
|
return a->mShader < b->mShader;
|
|
// renderable sorting
|
|
else
|
|
return a->mRenderable < b->mRenderable;
|
|
}
|
|
|
|
EDepthSortMode depthSortMode() const { return mDepthSortMode; }
|
|
void setDepthSortMode(EDepthSortMode mode) { mDepthSortMode = mode; }
|
|
|
|
public:
|
|
EDepthSortMode mDepthSortMode;
|
|
};
|
|
}
|
|
|
|
#endif
|