From Eric Wing, add alternate backdrop implementations.

From Robert Osfield, updated naming  and copy constructor methods.
This commit is contained in:
Robert Osfield
2006-07-18 12:24:04 +00:00
parent f2d50d943b
commit 419e185895
5 changed files with 517 additions and 81 deletions

View File

@@ -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. */

View File

@@ -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;