2012-03-22 01:36:20 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2003-01-22 00:45:36 +08:00
*
2012-03-22 01:36:20 +08:00
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
2003-01-22 00:45:36 +08:00
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
2012-03-22 01:36:20 +08:00
*
2003-01-22 00:45:36 +08:00
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2012-03-22 01:36:20 +08:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2003-01-22 00:45:36 +08:00
* OpenSceneGraph Public License for more details.
*/
2001-10-24 03:51:39 +08:00
#ifndef OSGTEXT_TEXT
2003-03-03 05:05:05 +08:00
#define OSGTEXT_TEXT 1
2001-10-24 03:51:39 +08:00
2007-12-10 23:15:56 +08:00
2001-10-24 03:51:39 +08:00
#include <osg/Drawable>
2003-03-03 05:05:05 +08:00
#include <osg/Quat>
2001-10-24 03:51:39 +08:00
2007-12-10 23:15:56 +08:00
#include <osgText/TextBase>
2001-11-09 23:06:01 +08:00
#include <osgText/Font>
2001-10-24 03:51:39 +08:00
namespace osgText {
2007-12-10 23:15:56 +08:00
class OSGTEXT_EXPORT Text : public osgText::TextBase
2001-10-24 03:51:39 +08:00
{
2003-03-03 05:05:05 +08:00
public:
Text();
Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
virtual osg::Object* cloneType() const { return new Text(); }
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Text(*this,copyop); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Text*>(obj)!=NULL; }
virtual const char* className() const { return "Text"; }
virtual const char* libraryName() const { return "osgText"; }
2017-10-21 17:08:41 +08:00
/** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/
void setShaderTechnique(ShaderTechnique technique);
/** Get the ShaderTechnique hint.*/
ShaderTechnique getShaderTechnique() { return _shaderTechnique; }
2010-09-16 17:09:43 +08:00
/**
* Turns off writing to the depth buffer when rendering text. This only affects text
* with no backdrop or text using the DELAYED_DEPTH_WRITES implementation, since
* the other backdrop implementations are really only useful for backwards
* compatibility and are not worth updating to utilize this flag.
*/
void setEnableDepthWrites(bool enable) { _enableDepthWrites = enable; }
2010-10-27 21:49:16 +08:00
bool getEnableDepthWrites() const { return _enableDepthWrites; }
2010-09-16 17:09:43 +08:00
2006-06-27 21:09:00 +08:00
enum BackdropType
{
DROP_SHADOW_BOTTOM_RIGHT = 0, // usually the type of shadow you see
DROP_SHADOW_CENTER_RIGHT,
DROP_SHADOW_TOP_RIGHT,
DROP_SHADOW_BOTTOM_CENTER,
DROP_SHADOW_TOP_CENTER,
DROP_SHADOW_BOTTOM_LEFT,
DROP_SHADOW_CENTER_LEFT,
DROP_SHADOW_TOP_LEFT,
OUTLINE,
NONE
};
/**
2012-03-22 01:36:20 +08:00
* BackdropType gives you a background shadow text behind your regular
* text. This helps give text extra contrast which can be useful when
* placing text against noisy backgrounds.
2006-06-27 21:09:00 +08:00
* The color of the background shadow text is specified by setBackdropColor().
2012-03-22 01:36:20 +08:00
* DROP_SHADOW_BOTTOM_RIGHT will draw backdrop text to the right and down of
2018-04-21 03:16:46 +08:00
* the normal text. Other DROP_SHADOW_* modes do the same for their respective directions.
2006-06-27 21:09:00 +08:00
* OUTLINE will draw backdrop text so that it appears the text has an outline
* or border around the normal text. This mode is particularly useful against
2012-03-22 01:36:20 +08:00
* really noisy backgrounds that may put text on top of things that have
* all types of colors which you don't have control over.
* Some real world examples of this general technique in use that I know of
2006-06-27 21:09:00 +08:00
* are Google Earth, Sid Meier's Pirates (2004 Remake), and Star Control 2 (PC 1993).
* The default is NONE.
*/
void setBackdropType(BackdropType type);
BackdropType getBackdropType() const { return _backdropType; }
2012-03-22 01:36:20 +08:00
/**
* Sets the amount text is offset to create the backdrop/shadow effect.
2006-06-27 21:09:00 +08:00
* Set the value too high and for example, in OUTLINE mode you will get a "Brady Bunch"
* effect where you see duplicates of the text in a 3x3 grid.
* Set the value too small and you won't see anything.
* The values represent percentages. 1.0 means 100% so a value of 1.0
* in DROW_SHADOW_LEFT_CENTER mode would cause each glyph to be echoed
* next to it self. So the letter 'e' might look like 'ee'.
* Good values tend to be in the 0.03 to 0.10 range (but will be subject
* to your specific font and display characteristics).
* Note that the text bounding boxes are updated to include backdrop offsets.
* However, other metric information such as getCharacterHeight() are unaffected
2012-03-22 01:36:20 +08:00
* by this. This means that individual glyph spacing (kerning?) are unchanged
2006-06-27 21:09:00 +08:00
* even when this mode is used.
* The default is 0.07 (7% offset).
*/
void setBackdropOffset(float offset = 0.07f);
/**
* This overloaded version lets you specify the offset for the horizontal
* and vertical components separately.
*/
void setBackdropOffset(float horizontal, float vertical);
2006-11-08 19:49:35 +08:00
float getBackdropHorizontalOffset() const { return _backdropHorizontalOffset; }
2006-06-27 21:09:00 +08:00
float getBackdropVerticalOffset() const { return _backdropVerticalOffset; }
/**
* This specifies the color of the backdrop text.
* The default is black.
*/
void setBackdropColor(const osg::Vec4& color);
const osg::Vec4& getBackdropColor() const { return _backdropColor; }
enum ColorGradientMode
{
SOLID = 0, // a.k.a. ColorGradients off
PER_CHARACTER,
OVERALL
};
/**
* This sets different types of text coloring modes.
2012-03-22 01:36:20 +08:00
* When the coloring mode is not set to SOLID, the
2006-06-27 21:09:00 +08:00
* colors specified in setColorGradientCorners() determine
* the colors for the text.
* When the gradient mode is OVERALL, the coloring scheme
* attempts to approximate the effect as if the entire text box/region
* were a single polygon and you had applied colors to each of the four
* corners with GL_SMOOTH enabled. In this mode, OpenGL interpolates
2012-03-22 01:36:20 +08:00
* the colors across the polygon, and this is what OVERALL tries to
* emulate. This can be used to give nice embellishments on things
2006-06-27 21:09:00 +08:00
* like logos and names.
2012-03-22 01:36:20 +08:00
* PER_CHARACTER is similar to OVERALL except that it applies the
2006-06-27 21:09:00 +08:00
* color interpolation to the four corners of each character instead
* of across the overall text box.
* The default is SOLID (a.k.a. off).
*/
void setColorGradientMode(ColorGradientMode mode);
ColorGradientMode getColorGradientMode() const { return _colorGradientMode; }
/**
* Used only for gradient mode, let's you specify the colors of the 4 corners.
2012-03-22 01:36:20 +08:00
* If ColorGradients are off, these values are ignored (and the value from setColor()
2006-06-27 21:09:00 +08:00
* is the only one that is relevant.
*/
void setColorGradientCorners(const osg::Vec4& topLeft, const osg::Vec4& bottomLeft, const osg::Vec4& bottomRight, const osg::Vec4& topRight);
const osg::Vec4& getColorGradientTopLeft() const { return _colorGradientTopLeft; }
const osg::Vec4& getColorGradientBottomLeft() const { return _colorGradientBottomLeft; }
const osg::Vec4& getColorGradientBottomRight() const { return _colorGradientBottomRight; }
const osg::Vec4& getColorGradientTopRight() const { return _colorGradientTopRight; }
2012-03-22 01:36:20 +08:00
2003-03-03 05:05:05 +08:00
/** Draw the text.*/
2006-09-19 04:54:48 +08:00
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
2003-03-03 05:05:05 +08:00
2003-03-11 00:40:26 +08:00
/** return false, osgText::Text does not support accept(AttributeFunctor&).*/
2005-03-18 10:42:59 +08:00
virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; }
2003-03-11 00:40:26 +08:00
/** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/
2005-03-18 10:42:59 +08:00
virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return true; }
2003-03-11 00:40:26 +08:00
2007-12-11 01:30:18 +08:00
/** accept an ConstAttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has.*/
2003-03-11 00:40:26 +08:00
virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
/** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/
2005-03-18 10:42:59 +08:00
virtual bool supports(const osg::PrimitiveFunctor&) const { return true; }
2003-03-11 00:40:26 +08:00
2007-12-11 01:30:18 +08:00
/** accept a PrimtiveFunctor and call its methods to tell it about the internal primitives that this Drawable has.*/
2005-02-09 18:39:45 +08:00
virtual void accept(osg::PrimitiveFunctor& pf) const;
2003-03-11 00:40:26 +08:00
2007-01-09 04:40:29 +08:00
2017-11-21 21:41:57 +08:00
/** Get the coordinates of the character corners in local coordinates. Use Text::getMatrix() or Text::computeMatrix(..) to get the transform into model coordinates (see TextBase header.) */
2017-11-21 21:59:51 +08:00
bool getCharacterCorners(unsigned int index, osg::Vec3& bottomLeft, osg::Vec3& bottomRight, osg::Vec3& topLeft, osg::Vec3& topRight) const;
2017-11-21 21:41:57 +08:00
2007-01-09 04:40:29 +08:00
/** Resize any per context GLObject buffers to specified size. */
virtual void resizeGLObjectBuffers(unsigned int maxSize);
2017-11-21 21:41:57 +08:00
2005-05-08 04:47:09 +08:00
/** If State is non-zero, this function releases OpenGL objects for
* the specified graphics context. Otherwise, releases OpenGL objexts
* for all graphics contexts. */
virtual void releaseGLObjects(osg::State* state=0) const;
2003-03-11 00:40:26 +08:00
2003-04-27 18:58:39 +08:00
public:
2017-10-13 18:42:25 +08:00
/** 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; }
2017-03-01 01:02:02 +08:00
2003-03-03 05:05:05 +08:00
// internal structures, variable and methods used for rendering of characters.
2003-04-27 18:58:39 +08:00
struct OSGTEXT_EXPORT GlyphQuads
2003-03-03 05:05:05 +08:00
{
2010-09-03 16:26:46 +08:00
typedef std::vector<Glyph*> Glyphs;
2003-03-03 05:05:05 +08:00
2017-02-22 20:07:43 +08:00
Glyphs _glyphs;
2017-10-13 15:40:58 +08:00
osg::ref_ptr<osg::DrawElements> _primitives;
2006-06-27 21:09:00 +08:00
2015-02-26 02:56:29 +08:00
GlyphQuads();
2015-07-14 00:09:45 +08:00
GlyphQuads(const GlyphQuads& gq);
2015-02-26 02:56:29 +08:00
2017-02-25 02:25:16 +08:00
void setupPrimitives(Text::BackdropType backdropType);
2015-07-14 00:09:45 +08:00
Glyphs& getGlyphs() { return _glyphs; }
const Glyphs& getGlyphs() const { return _glyphs; }
2003-05-02 05:06:18 +08:00
2015-07-14 00:09:45 +08:00
/** Resize any per context GLObject buffers to specified size. */
2015-07-31 18:59:11 +08:00
void resizeGLObjectBuffers(unsigned int maxSize);
2015-07-14 00:09:45 +08:00
/** If State is non-zero, this function releases OpenGL objects for
* the specified graphics context. Otherwise, releases OpenGL objexts
* for all graphics contexts. */
2015-07-31 18:59:11 +08:00
void releaseGLObjects(osg::State* state=0) const;
2016-03-01 18:21:14 +08:00
2015-07-14 00:09:45 +08:00
private:
2016-03-01 18:21:14 +08:00
2015-07-14 00:09:45 +08:00
GlyphQuads& operator = (const GlyphQuads&) { return *this; }
2003-03-03 05:05:05 +08:00
};
2006-06-27 21:09:00 +08:00
2010-09-03 16:26:46 +08:00
typedef std::map<osg::ref_ptr<GlyphTexture>,GlyphQuads> TextureGlyphQuadMap;
2003-03-03 05:05:05 +08:00
2003-04-27 18:58:39 +08:00
/** Direct Access to GlyphQuads */
2010-09-03 16:26:46 +08:00
const GlyphQuads* getGlyphQuads(GlyphTexture* texture) const
2003-04-27 18:58:39 +08:00
{
2017-03-03 01:05:24 +08:00
TextureGlyphQuadMap::const_iterator itGlyphQuad = _textureGlyphQuadMap.find(texture);
2003-06-27 00:21:49 +08:00
if (itGlyphQuad == _textureGlyphQuadMap.end()) return NULL;
2003-04-27 18:58:39 +08:00
2003-06-27 00:21:49 +08:00
return &itGlyphQuad->second;
2003-04-27 18:58:39 +08:00
}
2012-03-22 01:36:20 +08:00
const TextureGlyphQuadMap& getTextureGlyphQuadMap() const
2003-11-04 21:40:24 +08:00
{
return _textureGlyphQuadMap;
}
2017-02-25 01:08:48 +08:00
void addGlyphQuad(Glyph* glyph, const osg::Vec2& minc, const osg::Vec2& maxc, const osg::Vec2& mintc, const osg::Vec2& maxtc);
2005-05-12 22:03:22 +08:00
2003-04-27 18:58:39 +08:00
protected:
2003-04-30 19:40:17 +08:00
virtual ~Text();
2017-09-12 18:50:47 +08:00
virtual osg::StateSet* createStateSet();
2003-04-30 19:40:17 +08:00
Font* getActiveFont();
2005-07-16 00:22:53 +08:00
String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last);
2012-03-22 01:36:20 +08:00
2003-04-30 19:40:17 +08:00
// members which have public access.
2003-03-03 05:05:05 +08:00
// iternal map used for rendering. Set up by the computeGlyphRepresentation() method.
2017-03-03 01:05:24 +08:00
TextureGlyphQuadMap _textureGlyphQuadMap;
2012-03-22 01:36:20 +08:00
2003-03-03 05:05:05 +08:00
void computeGlyphRepresentation();
2003-03-03 17:37:02 +08:00
// internal caches of the positioning of the text.
2012-03-22 01:36:20 +08:00
2007-06-28 04:36:16 +08:00
bool computeAverageGlyphWidthAndHeight(float& avg_width, float& avg_height) const;
2012-03-22 01:36:20 +08:00
2017-02-23 23:45:43 +08:00
virtual void computePositionsImplementation();
2012-03-22 01:36:20 +08:00
2017-02-23 23:45:43 +08:00
void computeColorGradients();
void computeColorGradientsOverall();
void computeColorGradientsPerCharacter();
2006-06-27 21:09:00 +08:00
2006-09-19 04:54:48 +08:00
void drawImplementation(osg::State& state, const osg::Vec4& colorMultiplier) const;
2017-03-17 20:50:15 +08:00
void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const;
2017-10-21 17:08:41 +08:00
ShaderTechnique _shaderTechnique;
2010-09-16 17:09:43 +08:00
bool _enableDepthWrites;
2006-06-27 21:09:00 +08:00
BackdropType _backdropType;
2006-07-18 20:24:04 +08:00
2006-06-27 21:09:00 +08:00
float _backdropHorizontalOffset;
float _backdropVerticalOffset;
osg::Vec4 _backdropColor;
ColorGradientMode _colorGradientMode;
osg::Vec4 _colorGradientTopLeft;
osg::Vec4 _colorGradientBottomLeft;
osg::Vec4 _colorGradientBottomRight;
osg::Vec4 _colorGradientTopRight;
2016-09-03 00:01:25 +08:00
2009-11-24 22:12:54 +08:00
// Helper function for color interpolation
2006-06-27 21:09:00 +08:00
float bilinearInterpolate(float x1, float x2, float y1, float y2, float x, float y, float q11, float q12, float q21, float q22) const;
2001-10-24 03:51:39 +08:00
};
2002-02-03 20:33:41 +08:00
}
2001-10-24 03:51:39 +08:00
2003-03-03 05:05:05 +08:00
#endif