Text 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSGTEXT_TEXT
  14. #define OSGTEXT_TEXT 1
  15. #include <osg/Drawable>
  16. #include <osg/Quat>
  17. #include <osgText/TextBase>
  18. #include <osgText/Font>
  19. namespace osgText {
  20. class OSGTEXT_EXPORT Text : public osgText::TextBase
  21. {
  22. public:
  23. Text();
  24. Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
  25. virtual osg::Object* cloneType() const { return new Text(); }
  26. virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Text(*this,copyop); }
  27. virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Text*>(obj)!=NULL; }
  28. virtual const char* className() const { return "Text"; }
  29. virtual const char* libraryName() const { return "osgText"; }
  30. /** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/
  31. void setShaderTechnique(ShaderTechnique technique);
  32. /** Get the ShaderTechnique hint.*/
  33. ShaderTechnique getShaderTechnique() { return _shaderTechnique; }
  34. /**
  35. * Turns off writing to the depth buffer when rendering text. This only affects text
  36. * with no backdrop or text using the DELAYED_DEPTH_WRITES implementation, since
  37. * the other backdrop implementations are really only useful for backwards
  38. * compatibility and are not worth updating to utilize this flag.
  39. */
  40. void setEnableDepthWrites(bool enable) { _enableDepthWrites = enable; }
  41. bool getEnableDepthWrites() const { return _enableDepthWrites; }
  42. enum BackdropType
  43. {
  44. DROP_SHADOW_BOTTOM_RIGHT = 0, // usually the type of shadow you see
  45. DROP_SHADOW_CENTER_RIGHT,
  46. DROP_SHADOW_TOP_RIGHT,
  47. DROP_SHADOW_BOTTOM_CENTER,
  48. DROP_SHADOW_TOP_CENTER,
  49. DROP_SHADOW_BOTTOM_LEFT,
  50. DROP_SHADOW_CENTER_LEFT,
  51. DROP_SHADOW_TOP_LEFT,
  52. OUTLINE,
  53. NONE
  54. };
  55. /**
  56. * BackdropType gives you a background shadow text behind your regular
  57. * text. This helps give text extra contrast which can be useful when
  58. * placing text against noisy backgrounds.
  59. * The color of the background shadow text is specified by setBackdropColor().
  60. * DROP_SHADOW_BOTTOM_RIGHT will draw backdrop text to the right and down of
  61. * the normal text. Other DROP_SHADOW_* modes do the same for their respective directions.
  62. * OUTLINE will draw backdrop text so that it appears the text has an outline
  63. * or border around the normal text. This mode is particularly useful against
  64. * really noisy backgrounds that may put text on top of things that have
  65. * all types of colors which you don't have control over.
  66. * Some real world examples of this general technique in use that I know of
  67. * are Google Earth, Sid Meier's Pirates (2004 Remake), and Star Control 2 (PC 1993).
  68. * The default is NONE.
  69. */
  70. void setBackdropType(BackdropType type);
  71. BackdropType getBackdropType() const { return _backdropType; }
  72. /**
  73. * Sets the amount text is offset to create the backdrop/shadow effect.
  74. * Set the value too high and for example, in OUTLINE mode you will get a "Brady Bunch"
  75. * effect where you see duplicates of the text in a 3x3 grid.
  76. * Set the value too small and you won't see anything.
  77. * The values represent percentages. 1.0 means 100% so a value of 1.0
  78. * in DROW_SHADOW_LEFT_CENTER mode would cause each glyph to be echoed
  79. * next to it self. So the letter 'e' might look like 'ee'.
  80. * Good values tend to be in the 0.03 to 0.10 range (but will be subject
  81. * to your specific font and display characteristics).
  82. * Note that the text bounding boxes are updated to include backdrop offsets.
  83. * However, other metric information such as getCharacterHeight() are unaffected
  84. * by this. This means that individual glyph spacing (kerning?) are unchanged
  85. * even when this mode is used.
  86. * The default is 0.07 (7% offset).
  87. */
  88. void setBackdropOffset(float offset = 0.07f);
  89. /**
  90. * This overloaded version lets you specify the offset for the horizontal
  91. * and vertical components separately.
  92. */
  93. void setBackdropOffset(float horizontal, float vertical);
  94. float getBackdropHorizontalOffset() const { return _backdropHorizontalOffset; }
  95. float getBackdropVerticalOffset() const { return _backdropVerticalOffset; }
  96. /**
  97. * This specifies the color of the backdrop text.
  98. * The default is black.
  99. */
  100. void setBackdropColor(const osg::Vec4& color);
  101. const osg::Vec4& getBackdropColor() const { return _backdropColor; }
  102. enum ColorGradientMode
  103. {
  104. SOLID = 0, // a.k.a. ColorGradients off
  105. PER_CHARACTER,
  106. OVERALL
  107. };
  108. /**
  109. * This sets different types of text coloring modes.
  110. * When the coloring mode is not set to SOLID, the
  111. * colors specified in setColorGradientCorners() determine
  112. * the colors for the text.
  113. * When the gradient mode is OVERALL, the coloring scheme
  114. * attempts to approximate the effect as if the entire text box/region
  115. * were a single polygon and you had applied colors to each of the four
  116. * corners with GL_SMOOTH enabled. In this mode, OpenGL interpolates
  117. * the colors across the polygon, and this is what OVERALL tries to
  118. * emulate. This can be used to give nice embellishments on things
  119. * like logos and names.
  120. * PER_CHARACTER is similar to OVERALL except that it applies the
  121. * color interpolation to the four corners of each character instead
  122. * of across the overall text box.
  123. * The default is SOLID (a.k.a. off).
  124. */
  125. void setColorGradientMode(ColorGradientMode mode);
  126. ColorGradientMode getColorGradientMode() const { return _colorGradientMode; }
  127. /**
  128. * Used only for gradient mode, let's you specify the colors of the 4 corners.
  129. * If ColorGradients are off, these values are ignored (and the value from setColor()
  130. * is the only one that is relevant.
  131. */
  132. void setColorGradientCorners(const osg::Vec4& topLeft, const osg::Vec4& bottomLeft, const osg::Vec4& bottomRight, const osg::Vec4& topRight);
  133. const osg::Vec4& getColorGradientTopLeft() const { return _colorGradientTopLeft; }
  134. const osg::Vec4& getColorGradientBottomLeft() const { return _colorGradientBottomLeft; }
  135. const osg::Vec4& getColorGradientBottomRight() const { return _colorGradientBottomRight; }
  136. const osg::Vec4& getColorGradientTopRight() const { return _colorGradientTopRight; }
  137. /** Draw the text.*/
  138. virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
  139. /** return false, osgText::Text does not support accept(AttributeFunctor&).*/
  140. virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; }
  141. /** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/
  142. virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return true; }
  143. /** accept an ConstAttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has.*/
  144. virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
  145. /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/
  146. virtual bool supports(const osg::PrimitiveFunctor&) const { return true; }
  147. /** accept a PrimtiveFunctor and call its methods to tell it about the internal primitives that this Drawable has.*/
  148. virtual void accept(osg::PrimitiveFunctor& pf) const;
  149. /** 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.) */
  150. bool getCharacterCorners(unsigned int index, osg::Vec3& bottomLeft, osg::Vec3& bottomRight, osg::Vec3& topLeft, osg::Vec3& topRight) const;
  151. /** Resize any per context GLObject buffers to specified size. */
  152. virtual void resizeGLObjectBuffers(unsigned int maxSize);
  153. /** If State is non-zero, this function releases OpenGL objects for
  154. * the specified graphics context. Otherwise, releases OpenGL objexts
  155. * for all graphics contexts. */
  156. virtual void releaseGLObjects(osg::State* state=0) const;
  157. public:
  158. /** deprecated, value ignored.*/
  159. enum BackdropImplementation
  160. {
  161. POLYGON_OFFSET = 0,
  162. NO_DEPTH_BUFFER,
  163. DEPTH_RANGE,
  164. STENCIL_BUFFER,
  165. DELAYED_DEPTH_WRITES
  166. };
  167. /** deprecated, value ignored.*/
  168. void setBackdropImplementation(BackdropImplementation) {}
  169. /** deprecated, value should be ignored.*/
  170. BackdropImplementation getBackdropImplementation() const { return DELAYED_DEPTH_WRITES; }
  171. // internal structures, variable and methods used for rendering of characters.
  172. struct OSGTEXT_EXPORT GlyphQuads
  173. {
  174. typedef std::vector<Glyph*> Glyphs;
  175. Glyphs _glyphs;
  176. osg::ref_ptr<osg::DrawElements> _primitives;
  177. GlyphQuads();
  178. GlyphQuads(const GlyphQuads& gq);
  179. void setupPrimitives(Text::BackdropType backdropType);
  180. Glyphs& getGlyphs() { return _glyphs; }
  181. const Glyphs& getGlyphs() const { return _glyphs; }
  182. /** Resize any per context GLObject buffers to specified size. */
  183. void resizeGLObjectBuffers(unsigned int maxSize);
  184. /** If State is non-zero, this function releases OpenGL objects for
  185. * the specified graphics context. Otherwise, releases OpenGL objexts
  186. * for all graphics contexts. */
  187. void releaseGLObjects(osg::State* state=0) const;
  188. private:
  189. GlyphQuads& operator = (const GlyphQuads&) { return *this; }
  190. };
  191. typedef std::map<osg::ref_ptr<GlyphTexture>,GlyphQuads> TextureGlyphQuadMap;
  192. /** Direct Access to GlyphQuads */
  193. const GlyphQuads* getGlyphQuads(GlyphTexture* texture) const
  194. {
  195. TextureGlyphQuadMap::const_iterator itGlyphQuad = _textureGlyphQuadMap.find(texture);
  196. if (itGlyphQuad == _textureGlyphQuadMap.end()) return NULL;
  197. return &itGlyphQuad->second;
  198. }
  199. const TextureGlyphQuadMap& getTextureGlyphQuadMap() const
  200. {
  201. return _textureGlyphQuadMap;
  202. }
  203. void addGlyphQuad(Glyph* glyph, const osg::Vec2& minc, const osg::Vec2& maxc, const osg::Vec2& mintc, const osg::Vec2& maxtc);
  204. protected:
  205. virtual ~Text();
  206. virtual osg::StateSet* createStateSet();
  207. Font* getActiveFont();
  208. String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last);
  209. // members which have public access.
  210. // iternal map used for rendering. Set up by the computeGlyphRepresentation() method.
  211. TextureGlyphQuadMap _textureGlyphQuadMap;
  212. void computeGlyphRepresentation();
  213. // internal caches of the positioning of the text.
  214. bool computeAverageGlyphWidthAndHeight(float& avg_width, float& avg_height) const;
  215. virtual void computePositionsImplementation();
  216. void computeColorGradients();
  217. void computeColorGradientsOverall();
  218. void computeColorGradientsPerCharacter();
  219. void drawImplementation(osg::State& state, const osg::Vec4& colorMultiplier) const;
  220. void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const;
  221. ShaderTechnique _shaderTechnique;
  222. bool _enableDepthWrites;
  223. BackdropType _backdropType;
  224. float _backdropHorizontalOffset;
  225. float _backdropVerticalOffset;
  226. osg::Vec4 _backdropColor;
  227. ColorGradientMode _colorGradientMode;
  228. osg::Vec4 _colorGradientTopLeft;
  229. osg::Vec4 _colorGradientBottomLeft;
  230. osg::Vec4 _colorGradientBottomRight;
  231. osg::Vec4 _colorGradientTopRight;
  232. // Helper function for color interpolation
  233. float bilinearInterpolate(float x1, float x2, float y1, float y2, float x, float y, float q11, float q12, float q21, float q22) const;
  234. };
  235. }
  236. #endif