From Eric Wing, add alternate backdrop implementations.
From Robert Osfield, updated naming and copy constructor methods.
This commit is contained in:
@@ -72,7 +72,7 @@ class OSG_EXPORT PolygonOffset : public StateAttribute
|
||||
static void setUnitsMultiplier(float multiplier);
|
||||
static float getUnitsMultiplier();
|
||||
|
||||
static bool areUnitsAndMultipliersSet();
|
||||
static bool areFactorAndUnitsMultipliersSet();
|
||||
|
||||
/** Checks with the OpenGL driver to try and pick multiplier approrpriate for the hardware.
|
||||
note, requires a valid graphics context to be current. */
|
||||
|
||||
@@ -226,6 +226,14 @@ public:
|
||||
NONE
|
||||
};
|
||||
|
||||
enum BackdropImplementation
|
||||
{
|
||||
POLYGON_OFFSET = 0,
|
||||
NO_DEPTH_BUFFER,
|
||||
DEPTH_RANGE,
|
||||
STENCIL_BUFFER
|
||||
};
|
||||
|
||||
/**
|
||||
* BackdropType gives you a background shadow text behind your regular
|
||||
* text. This helps give text extra contrast which can be useful when
|
||||
@@ -280,6 +288,85 @@ public:
|
||||
|
||||
const osg::Vec4& getBackdropColor() const { return _backdropColor; }
|
||||
|
||||
/**
|
||||
* This specifies the underlying backdrop rendering implementation.
|
||||
* Unfortunately, at this time, there is no "perfect" rendering solution
|
||||
* so this function is provided to let you 'pick your poison'. Each
|
||||
* implementation has trade-offs.
|
||||
*
|
||||
* POLYGON_OFFSET:
|
||||
* This uses glPolygonOffset to draw the text multiple times to
|
||||
* create the drop-shadow and outline effects. glPolygonOffset
|
||||
* is used to prevent z-fighting of the overlapping text.
|
||||
* This probably should have been the best option, but all the ATI
|
||||
* cards we have encountered so far have serious problems with this.
|
||||
* We see little white holes/artifacts in the rendered glyph textures
|
||||
* which move around depending on the viewing angle. For moving text,
|
||||
* the moving holes give an extremely unpleasant flickering effect.
|
||||
* Pumping up the "units" parameter in glPolygonOffset can minimize
|
||||
* this problem, but two other bad side-effects occur if you do this.
|
||||
* First, high values will cause problems with clipping, particularly
|
||||
* when there are objects behind the text. The drop-shadows or outline
|
||||
* may be culled because their computed offset is behind the object or
|
||||
* z-far plane. Second, there is an additional problem associated with
|
||||
* the Z-slope. High values can make large chunks of the backdrop
|
||||
* suddenly disappear. This can be reduced by the "factor" parameter.
|
||||
* Making the "factor" value small, can help, but experimentally, we've
|
||||
* found that it creates a new, different kind of z-fighting problem.
|
||||
* So there is no perfect solution. With units, you trade off the 'holes'
|
||||
* for the large-section clipping.
|
||||
* Experimentally, we have found units values from 150-512 to be tolerable
|
||||
* to acceptable with respect to the 'holes'. A factor of .1 seems to
|
||||
* bring down the large clipping problem without creating a new z-fighting
|
||||
* problem.
|
||||
* (You can experiment with these numbers by playing with the
|
||||
* osg:PolygonOffset multipliers which this backend tries to respect.)
|
||||
*
|
||||
* If ATI ever fixes their cards/drivers, then this might become the
|
||||
* best option.
|
||||
*
|
||||
*
|
||||
* NO_DEPTH_BUFFER
|
||||
* Instead of using glPolygonOffset to prevent z-fighting, this mode
|
||||
* just disables the depth buffer when rendering the text. This allows
|
||||
* the text to be rendered without any z-fighting. The downside to this
|
||||
* mode is that render order begins to matter and the text will not
|
||||
* necessarily correctly appear above or behind other objects in the
|
||||
* scene based on depth values.
|
||||
* This mode is best for text that only needs to be ontop and
|
||||
* not obscured by any objects.
|
||||
*
|
||||
* DEPTH_RANGE
|
||||
* This mode is inspired by Paul Martz's OpenGL FAQ, item 13.050.
|
||||
* This uses glDepthRange as a substitute for glPolygonOffset.
|
||||
* Strangely, experiments on ATI cards seem to produce cleaner results
|
||||
* than when using glPolygonOffset. The trade-off for this is that the
|
||||
* backdrop still may be placed too far back and might be culled by objects
|
||||
* directly behind the object or by the far z-plane. If ATI ever fixes
|
||||
* the glPolygonOffset problem, polygon offset is probably a slightly
|
||||
* better solution because you can use smaller offsets. But with the
|
||||
* current ATI problem, this option may be preferable.
|
||||
*
|
||||
* STENCIL_BUFFER
|
||||
* (Assuming the backend is written correctly,) the Stencil Buffer is
|
||||
* the most "correct" and reliable way of producing backdrop text.
|
||||
* The stencil buffer is a multipass system that allows writing to the
|
||||
* same z-values without needing to resort to offsets. This implementation
|
||||
* should not have any of the problems associated with the 3 previous
|
||||
* implementations. But the trade-off for this mode is that without
|
||||
* hardware acceleration for the stencil buffer, rendering will be
|
||||
* extremely slow. (There is also potentially more overhead for this
|
||||
* algorithm so it could be slower than the other implementations.
|
||||
* Benchmarking would be required to determine if the speed differences
|
||||
* are significant on your particular hardware.) This mode is best for
|
||||
* when quality is important and stencil buffer hardware acceleration
|
||||
* is available.
|
||||
*/
|
||||
void setBackdropImplementation(BackdropImplementation implementation);
|
||||
|
||||
BackdropImplementation getBackdropImplementation() const { return _backdropImplementation; }
|
||||
|
||||
|
||||
|
||||
enum ColorGradientMode
|
||||
{
|
||||
@@ -470,13 +557,22 @@ protected:
|
||||
|
||||
void computePositions();
|
||||
void computePositions(unsigned int contextID) const;
|
||||
|
||||
|
||||
void computeBackdropPositions(unsigned int contextID) const;
|
||||
void computeColorGradients() const;
|
||||
void computeColorGradientsOverall() const;
|
||||
void computeColorGradientsPerCharacter() const;
|
||||
|
||||
void drawForegroundText(osg::State& state, const GlyphQuads& glyphquad) const;
|
||||
void renderOnlyForegroundText(osg::State& state) const;
|
||||
void renderWithPolygonOffset(osg::State& state) const;
|
||||
void renderWithNoDepthBuffer(osg::State& state) const;
|
||||
void renderWithDepthRange(osg::State& state) const;
|
||||
void renderWithStencilBuffer(osg::State& state) const;
|
||||
|
||||
BackdropType _backdropType;
|
||||
BackdropImplementation _backdropImplementation;
|
||||
|
||||
float _backdropHorizontalOffset;
|
||||
float _backdropVerticalOffset;
|
||||
osg::Vec4 _backdropColor;
|
||||
|
||||
Reference in New Issue
Block a user