Merge pull request #372 from openscenegraph/text_improvements

Text improvements, introducing implementation of Signed Distance Function texture generation and new shaders for outlines and shadows replacing old multi-pass approach
This commit is contained in:
OpenSceneGraph git repository
2017-10-26 14:26:01 +01:00
committed by GitHub
31 changed files with 1642 additions and 791 deletions

View File

@@ -20,6 +20,7 @@
#include <string>
#include <vector>
#include <map>
namespace osg {
@@ -319,9 +320,15 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
SHADER_GLES3
};
void setShaderHint(ShaderHint hint) { _shaderHint = hint; }
/** set the ShaderHint to tells shader generating cdoes version to create.
* By default also OSG_GLSL_VERSION and OSG_PRECISION_FLOAT values that can get use directly in shaders using $OSG_GLSL_VERSION and $OSG_PRECISION_FLOAT respectively.*/
void setShaderHint(ShaderHint hint, bool setShaderValues=true);
ShaderHint getShaderHint() const { return _shaderHint; }
/** Set the TextShaderTechnique that is used in the Text default constructor to choose which osgText::ShaderTechnique to use.*/
void setTextShaderTechnique(const std::string& str) { _textShaderTechnique = str; }
const std::string& getTextShaderTechnique() const { return _textShaderTechnique; }
void setKeystoneHint(bool enabled) { _keystoneHint = enabled; }
bool getKeystoneHint() const { return _keystoneHint; }
@@ -358,6 +365,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
/** helper function for computing the right eye view matrix.*/
virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale=1.0) const;
void setValue(const std::string& name, const std::string& value);
bool getValue(const std::string& name, std::string& value, bool use_getenv_fallback=true) const;
protected:
virtual ~DisplaySettings();
@@ -415,6 +427,7 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
VertexBufferHint _vertexBufferHint;
ShaderHint _shaderHint;
std::string _textShaderTechnique;
bool _keystoneHint;
FileNames _keystoneFileNames;
@@ -422,6 +435,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
OSXMenubarBehavior _OSXMenubarBehavior;
typedef std::map<std::string, std::string> ValueMap;
mutable OpenThreads::Mutex _valueMapMutex;
mutable ValueMap _valueMap;
};
}

View File

@@ -823,9 +823,12 @@ class OSG_EXPORT State : public Referenced
* during rendering. */
inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; }
/** Get the DisplaySettings */
/** Get the const DisplaySettings */
inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
/** Get the const DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */
inline const DisplaySettings* getActiveDisplaySettings() const { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); }
/** Set flag for early termination of the draw traversal.*/

View File

@@ -27,6 +27,7 @@ namespace osgText {
// forward declare Font
class Font;
class TextBase;
#ifdef OSG_PROVIDE_READFILE
/** Read a font from specified file. The filename may contain a path.
@@ -84,13 +85,9 @@ public:
static osg::ref_ptr<Font>& getDefaultFont();
void setTexEnv(osg::TexEnv* texenv) { if (texenv) _texenv = texenv; }
inline osg::TexEnv* getTexEnv() { return _texenv.get(); }
inline const osg::TexEnv* getTexEnv() const { return _texenv.get(); }
void setStateSet(osg::StateSet* stateset) { _stateset = stateset; }
osg::StateSet* getStateSet() { return _stateset.get(); }
const osg::StateSet* getStateSet() const { return _stateset.get(); }
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSets;
StateSets& getCachedStateSets() { return _statesets; }
const StateSets& getCachedStateSets() const { return _statesets; }
/** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes and a font resolution.*/
@@ -110,19 +107,6 @@ public:
* return true on success, return false when not supported.*/
virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; }
/** Set the margin around each glyph,
* to ensure that texture filtering doesn't bleed adjacent glyph's into each other.
* Default margin is 1 texels.*/
void setGlyphImageMargin(unsigned int margin);
unsigned int getGlyphImageMargin() const;
/** Set the margin ratio around each glyph, relative to the glyph's size.
* to ensure that texture filtering doesn't bleed adjacent glyph's into each other.
* Default margin is 0.05.*/
void setGlyphImageMarginRatio(float margin);
float getGlyphImageMarginRatio() const;
/** Set the size of texture to create to store the glyph images when rendering.
* Note, this doesn't affect already created Texture Glhph's.*/
void setTextureSizeHint(unsigned int width,unsigned int height);
@@ -140,6 +124,9 @@ public:
void setMagFilterHint(osg::Texture::FilterMode mode);
osg::Texture::FilterMode getMagFilterHint() const;
void setMaxAnisotropy(float anis) { _maxAnisotropy = anis; }
float getMaxAnisotropy() const { return _maxAnisotropy; }
unsigned int getFontDepth() const { return _depth; }
void setNumberCurveSamples(unsigned int numSamples) { _numCurveSamples = numSamples; }
@@ -170,13 +157,14 @@ public:
typedef std::vector< osg::ref_ptr<GlyphTexture> > GlyphTextureList;
GlyphTextureList& getGlyphTextureList() { return _glyphTextureList; }
void assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique);
protected:
virtual ~Font();
void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph);
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetList;
typedef std::map< unsigned int, osg::ref_ptr<Glyph> > GlyphMap;
typedef std::map< unsigned int, osg::ref_ptr<Glyph3D> > Glyph3DMap;
@@ -185,8 +173,7 @@ protected:
mutable OpenThreads::Mutex _glyphMapMutex;
osg::ref_ptr<osg::TexEnv> _texenv;
osg::ref_ptr<osg::StateSet> _stateset;
StateSets _statesets;
FontSizeGlyphMap _sizeGlyphMap;
GlyphTextureList _glyphTextureList;
@@ -195,13 +182,12 @@ protected:
// current active size of font
FontResolution _fontSize;
unsigned int _margin;
float _marginRatio;
unsigned int _textureWidthHint;
unsigned int _textureHeightHint;
osg::Texture::FilterMode _minFilterHint;
osg::Texture::FilterMode _magFilterHint;
float _maxAnisotropy;
unsigned int _depth;
unsigned int _numCurveSamples;
@@ -247,8 +233,6 @@ public:
virtual bool getVerticalSize(float & /*ascender*/, float & /*descender*/) const { return false; }
};
};
}

View File

@@ -30,15 +30,6 @@
#include <OpenThreads/Mutex>
// GL_ALPHA is deprecated in GL3/GL4 core profile, use GL_RED and a shader in this case. See osgText example.
#if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE)
#define OSGTEXT_GLYPH_FORMAT GL_RED
#define OSGTEXT_GLYPH_INTERNALFORMAT GL_R8
#else
#define OSGTEXT_GLYPH_FORMAT GL_ALPHA
#define OSGTEXT_GLYPH_INTERNALFORMAT GL_ALPHA
#endif
namespace osgText {
class Font;
@@ -47,6 +38,14 @@ class Glyph3D;
class GlyphGeometry;
class GlyphTexture;
enum ShaderTechnique
{
NO_TEXT_SHADER = 0x0,
GREYSCALE = 0x1,
SIGNED_DISTANCE_FIELD = 0x2,
ALL_FEATURES = GREYSCALE | SIGNED_DISTANCE_FIELD
};
class OSGTEXT_EXPORT Glyph : public osg::Image
{
public:
@@ -58,6 +57,9 @@ public:
unsigned int getGlyphCode() const { return _glyphCode; }
void setFontResolution(const FontResolution& fontRes) { _fontResolution = fontRes; }
const FontResolution& getFontResolution() const { return _fontResolution; }
void setWidth(float width) { _width = width; }
float getWidth() const { return _width; }
@@ -76,21 +78,33 @@ public:
void setVerticalAdvance(float advance);
float getVerticalAdvance() const;
void setTexture(GlyphTexture* texture);
GlyphTexture* getTexture();
const GlyphTexture* getTexture() const;
struct TextureInfo : public osg::Referenced
{
TextureInfo():
texture(0),
texelMargin(0.0f) {}
void setTexturePosition(int posX,int posY);
int getTexturePositionX() const;
int getTexturePositionY() const;
TextureInfo(GlyphTexture* tex, int x, int y, const osg::Vec2& mintc, const osg::Vec2& maxtc, float margin):
texture(tex),
texturePositionX(x),
texturePositionY(y),
minTexCoord(mintc),
maxTexCoord(maxtc),
texelMargin(margin) {}
void setMinTexCoord(const osg::Vec2& coord);
const osg::Vec2& getMinTexCoord() const;
GlyphTexture* texture;
int texturePositionX;
int texturePositionY;
osg::Vec2 minTexCoord;
osg::Vec2 maxTexCoord;
float texelMargin;
};
void setMaxTexCoord(const osg::Vec2& coord);
const osg::Vec2& getMaxTexCoord() const;
void setTextureInfo(ShaderTechnique technique, TextureInfo* info);
void subload() const;
const TextureInfo* getTextureInfo(ShaderTechnique technique) const;
TextureInfo* getOrCreateTextureInfo(ShaderTechnique technique);
protected:
@@ -99,6 +113,8 @@ protected:
Font* _font;
unsigned int _glyphCode;
FontResolution _fontResolution;
float _width;
float _height;
@@ -108,15 +124,8 @@ protected:
osg::Vec2 _verticalBearing;
float _verticalAdvance;
GlyphTexture* _texture;
int _texturePosX;
int _texturePosY;
osg::Vec2 _minTexCoord;
osg::Vec2 _maxTexCoord;
typedef osg::buffered_value<GLuint> GLObjectList;
mutable GLObjectList _globjList;
typedef std::vector< osg::ref_ptr<TextureInfo> > TextureInfoList;
TextureInfoList _textureInfoList;
};
class OSGTEXT_EXPORT GlyphGeometry : public osg::Referenced
@@ -253,12 +262,13 @@ public:
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
virtual int compare(const osg::StateAttribute& rhs) const;
/** Set the margin around each glyph, to ensure that texture filtering doesn't bleed adjacent glyph's into each other.*/
void setGlyphImageMargin(unsigned int margin) { _margin = margin; }
unsigned int getGlyphImageMargin() const { return _margin; }
void setShaderTechnique(ShaderTechnique technique) { _shaderTechnique = technique; }
void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; }
float getGlyphImageMarginRatio() const { return _marginRatio; }
ShaderTechnique getShaderTechnique() const { return _shaderTechnique; }
int getEffectMargin(const Glyph* glyph);
int getTexelMargin(const Glyph* glyph);
bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY);
@@ -277,14 +287,13 @@ protected:
virtual ~GlyphTexture();
void copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info);
// parameter used to compute the size and position of empty space
// in the texture which could accommodate new glyphs.
int _margin;
float _marginRatio;
int _usedY;
int _partUsedX;
int _partUsedY;
ShaderTechnique _shaderTechnique;
int _usedY;
int _partUsedX;
int _partUsedY;
typedef std::vector< osg::ref_ptr<Glyph> > GlyphRefList;
typedef std::vector< const Glyph* > GlyphPtrList;

View File

@@ -36,15 +36,12 @@ public:
virtual const char* className() const { return "Text"; }
virtual const char* libraryName() const { return "osgText"; }
virtual void setFont(Font* font=0) { setFont(osg::ref_ptr<Font>(font)); };
/** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/
void setShaderTechnique(ShaderTechnique technique);
/** Set the Font to use to render the text.*/
virtual void setFont(osg::ref_ptr<Font> font);
/** Get the ShaderTechnique hint.*/
ShaderTechnique getShaderTechnique() { return _shaderTechnique; }
/** Set the font, loaded from the specified front file, to use to render the text,
* setFont("") sets the use of the default font.
* See the osgText::readFontFile function for how the font file will be located. */
virtual void setFont(const std::string& fontfile) { TextBase::setFont(fontfile); }
/**
* Turns off writing to the depth buffer when rendering text. This only affects text
@@ -70,31 +67,6 @@ public:
NONE
};
enum BackdropImplementation
{
/* No longer supported, naps to DELAYED_DEPTH_WRITES.*/
POLYGON_OFFSET = 0,
/* No longer supported, naps to DELAYED_DEPTH_WRITES.*/
NO_DEPTH_BUFFER,
/* No longer supported, naps to DELAYED_DEPTH_WRITES.*/
DEPTH_RANGE,
/* No longer supported, naps to DELAYED_DEPTH_WRITES.*/
STENCIL_BUFFER,
/* DELAYED_DEPTH_WRITES
* This mode renders all text with depth writes turned off, then
* again with depth writes on, but with the color buffer disabled.
* This should render text accurately for all graphics cards. The
* only downside is the additional pass to render to the depth
* buffer. But if you don't need the depth buffer updated for
* your, this extra pass can be disabled by calling
* enableDepthWrites(false).*/
DELAYED_DEPTH_WRITES
};
/**
* BackdropType gives you a background shadow text behind your regular
* text. This helps give text extra contrast which can be useful when
@@ -149,18 +121,6 @@ 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. See BackdropImplementation enum
* docs for details.*/
void setBackdropImplementation(BackdropImplementation implementation);
BackdropImplementation getBackdropImplementation() const { return _backdropImplementation; }
enum ColorGradientMode
{
SOLID = 0, // a.k.a. ColorGradients off
@@ -232,6 +192,20 @@ public:
public:
/** deprecated, value ignored.*/
enum BackdropImplementation
{
POLYGON_OFFSET = 0,
NO_DEPTH_BUFFER,
DEPTH_RANGE,
STENCIL_BUFFER,
DELAYED_DEPTH_WRITES
};
/** deprecated, value ignored.*/
void setBackdropImplementation(BackdropImplementation) {}
/** deprecated, value should be ignored.*/
BackdropImplementation getBackdropImplementation() const { return DELAYED_DEPTH_WRITES; }
// internal structures, variable and methods used for rendering of characters.
struct OSGTEXT_EXPORT GlyphQuads
@@ -239,7 +213,7 @@ public:
typedef std::vector<Glyph*> Glyphs;
Glyphs _glyphs;
Primitives _primitives;
osg::ref_ptr<osg::DrawElements> _primitives;
GlyphQuads();
GlyphQuads(const GlyphQuads& gq);
@@ -284,6 +258,8 @@ protected:
virtual ~Text();
virtual osg::StateSet* createStateSet();
Font* getActiveFont();
const Font* getActiveFont() const;
@@ -302,7 +278,6 @@ protected:
virtual void computePositionsImplementation();
void computeBackdropPositions();
void computeBackdropBoundingBox();
void computeBoundingBoxMargin();
@@ -314,10 +289,10 @@ protected:
void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const;
ShaderTechnique _shaderTechnique;
bool _enableDepthWrites;
BackdropType _backdropType;
BackdropImplementation _backdropImplementation;
float _backdropHorizontalOffset;
float _backdropVerticalOffset;

View File

@@ -53,6 +53,9 @@ public:
virtual void setFont(const std::string& fontfile);
/** Get the font. Return 0 if default is being used.*/
Font* getFont() { return _font.get(); }
/** Get the const font. Return 0 if default is being used.*/
const Font* getFont() const { return _font.get(); }
@@ -284,6 +287,10 @@ protected:
virtual ~TextBase();
virtual osg::StateSet* createStateSet();
virtual void assignStateSet();
void initArraysAndBuffers();
osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const;

View File

@@ -97,6 +97,9 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor
void apply(osg::Drawable& drawable);
void apply(osg::StateSet& stateset);
/** Do a compile traversal and then reset any state,*/
void compile(osg::Node& node);
protected:
typedef std::set<osg::Drawable*> DrawableAppliedSet;