1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
18#include <osg/Drawable>
21#include <osgText/TextBase>
22#include <osgText/Font>
26class OSGTEXT_EXPORT Text : public osgText::TextBase
31 Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
33 virtual osg::Object* cloneType() const { return new Text(); }
34 virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Text(*this,copyop); }
35 virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Text*>(obj)!=NULL; }
36 virtual const char* className() const { return "Text"; }
37 virtual const char* libraryName() const { return "osgText"; }
39 /** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/
40 void setShaderTechnique(ShaderTechnique technique);
42 /** Get the ShaderTechnique hint.*/
43 ShaderTechnique getShaderTechnique() { return _shaderTechnique; }
47 * Turns off writing to the depth buffer when rendering text. This only affects text
48 * with no backdrop or text using the DELAYED_DEPTH_WRITES implementation, since
49 * the other backdrop implementations are really only useful for backwards
50 * compatibility and are not worth updating to utilize this flag.
52 void setEnableDepthWrites(bool enable) { _enableDepthWrites = enable; }
53 bool getEnableDepthWrites() const { return _enableDepthWrites; }
58 DROP_SHADOW_BOTTOM_RIGHT = 0, // usually the type of shadow you see
59 DROP_SHADOW_CENTER_RIGHT,
60 DROP_SHADOW_TOP_RIGHT,
61 DROP_SHADOW_BOTTOM_CENTER,
62 DROP_SHADOW_TOP_CENTER,
63 DROP_SHADOW_BOTTOM_LEFT,
64 DROP_SHADOW_CENTER_LEFT,
71 * BackdropType gives you a background shadow text behind your regular
72 * text. This helps give text extra contrast which can be useful when
73 * placing text against noisy backgrounds.
74 * The color of the background shadow text is specified by setBackdropColor().
75 * DROP_SHADOW_BOTTOM_RIGHT will draw backdrop text to the right and down of
76 * the normal text. Other DROP_SHADOW_* modes do the same for their respective directions.
77 * OUTLINE will draw backdrop text so that it appears the text has an outline
78 * or border around the normal text. This mode is particularly useful against
79 * really noisy backgrounds that may put text on top of things that have
80 * all types of colors which you don't have control over.
81 * Some real world examples of this general technique in use that I know of
82 * are Google Earth, Sid Meier's Pirates (2004 Remake), and Star Control 2 (PC 1993).
83 * The default is NONE.
85 void setBackdropType(BackdropType type);
87 BackdropType getBackdropType() const { return _backdropType; }
90 * Sets the amount text is offset to create the backdrop/shadow effect.
91 * Set the value too high and for example, in OUTLINE mode you will get a "Brady Bunch"
92 * effect where you see duplicates of the text in a 3x3 grid.
93 * Set the value too small and you won't see anything.
94 * The values represent percentages. 1.0 means 100% so a value of 1.0
95 * in DROW_SHADOW_LEFT_CENTER mode would cause each glyph to be echoed
96 * next to it self. So the letter 'e' might look like 'ee'.
97 * Good values tend to be in the 0.03 to 0.10 range (but will be subject
98 * to your specific font and display characteristics).
99 * Note that the text bounding boxes are updated to include backdrop offsets.
100 * However, other metric information such as getCharacterHeight() are unaffected
101 * by this. This means that individual glyph spacing (kerning?) are unchanged
102 * even when this mode is used.
103 * The default is 0.07 (7% offset).
105 void setBackdropOffset(float offset = 0.07f);
107 * This overloaded version lets you specify the offset for the horizontal
108 * and vertical components separately.
110 void setBackdropOffset(float horizontal, float vertical);
112 float getBackdropHorizontalOffset() const { return _backdropHorizontalOffset; }
114 float getBackdropVerticalOffset() const { return _backdropVerticalOffset; }
117 * This specifies the color of the backdrop text.
118 * The default is black.
120 void setBackdropColor(const osg::Vec4& color);
122 const osg::Vec4& getBackdropColor() const { return _backdropColor; }
124 enum ColorGradientMode
126 SOLID = 0, // a.k.a. ColorGradients off
132 * This sets different types of text coloring modes.
133 * When the coloring mode is not set to SOLID, the
134 * colors specified in setColorGradientCorners() determine
135 * the colors for the text.
136 * When the gradient mode is OVERALL, the coloring scheme
137 * attempts to approximate the effect as if the entire text box/region
138 * were a single polygon and you had applied colors to each of the four
139 * corners with GL_SMOOTH enabled. In this mode, OpenGL interpolates
140 * the colors across the polygon, and this is what OVERALL tries to
141 * emulate. This can be used to give nice embellishments on things
142 * like logos and names.
143 * PER_CHARACTER is similar to OVERALL except that it applies the
144 * color interpolation to the four corners of each character instead
145 * of across the overall text box.
146 * The default is SOLID (a.k.a. off).
148 void setColorGradientMode(ColorGradientMode mode);
150 ColorGradientMode getColorGradientMode() const { return _colorGradientMode; }
153 * Used only for gradient mode, let's you specify the colors of the 4 corners.
154 * If ColorGradients are off, these values are ignored (and the value from setColor()
155 * is the only one that is relevant.
157 void setColorGradientCorners(const osg::Vec4& topLeft, const osg::Vec4& bottomLeft, const osg::Vec4& bottomRight, const osg::Vec4& topRight);
159 const osg::Vec4& getColorGradientTopLeft() const { return _colorGradientTopLeft; }
160 const osg::Vec4& getColorGradientBottomLeft() const { return _colorGradientBottomLeft; }
161 const osg::Vec4& getColorGradientBottomRight() const { return _colorGradientBottomRight; }
162 const osg::Vec4& getColorGradientTopRight() const { return _colorGradientTopRight; }
167 virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
169 /** return false, osgText::Text does not support accept(AttributeFunctor&).*/
170 virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; }
172 /** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/
173 virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return true; }
175 /** accept an ConstAttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has.*/
176 virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
178 /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/
179 virtual bool supports(const osg::PrimitiveFunctor&) const { return true; }
181 /** accept a PrimtiveFunctor and call its methods to tell it about the internal primitives that this Drawable has.*/
182 virtual void accept(osg::PrimitiveFunctor& pf) const;
185 /** 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.) */
186 bool getCharacterCorners(unsigned int index, osg::Vec3& bottomLeft, osg::Vec3& bottomRight, osg::Vec3& topLeft, osg::Vec3& topRight) const;
188 /** Resize any per context GLObject buffers to specified size. */
189 virtual void resizeGLObjectBuffers(unsigned int maxSize);
192 /** If State is non-zero, this function releases OpenGL objects for
193 * the specified graphics context. Otherwise, releases OpenGL objexts
194 * for all graphics contexts. */
195 virtual void releaseGLObjects(osg::State* state=0) const;
199 /** deprecated, value ignored.*/
200 enum BackdropImplementation
209 /** deprecated, value ignored.*/
210 void setBackdropImplementation(BackdropImplementation) {}
211 /** deprecated, value should be ignored.*/
212 BackdropImplementation getBackdropImplementation() const { return DELAYED_DEPTH_WRITES; }
214 // internal structures, variable and methods used for rendering of characters.
215 struct OSGTEXT_EXPORT GlyphQuads
217 typedef std::vector<Glyph*> Glyphs;
220 osg::ref_ptr<osg::DrawElements> _primitives;
223 GlyphQuads(const GlyphQuads& gq);
225 void setupPrimitives(Text::BackdropType backdropType);
227 Glyphs& getGlyphs() { return _glyphs; }
228 const Glyphs& getGlyphs() const { return _glyphs; }
230 /** Resize any per context GLObject buffers to specified size. */
231 void resizeGLObjectBuffers(unsigned int maxSize);
233 /** If State is non-zero, this function releases OpenGL objects for
234 * the specified graphics context. Otherwise, releases OpenGL objexts
235 * for all graphics contexts. */
236 void releaseGLObjects(osg::State* state=0) const;
240 GlyphQuads& operator = (const GlyphQuads&) { return *this; }
243 typedef std::map<osg::ref_ptr<GlyphTexture>,GlyphQuads> TextureGlyphQuadMap;
245 /** Direct Access to GlyphQuads */
246 const GlyphQuads* getGlyphQuads(GlyphTexture* texture) const
248 TextureGlyphQuadMap::const_iterator itGlyphQuad = _textureGlyphQuadMap.find(texture);
249 if (itGlyphQuad == _textureGlyphQuadMap.end()) return NULL;
251 return &itGlyphQuad->second;
254 const TextureGlyphQuadMap& getTextureGlyphQuadMap() const
256 return _textureGlyphQuadMap;
259 void addGlyphQuad(Glyph* glyph, const osg::Vec2& minc, const osg::Vec2& maxc, const osg::Vec2& mintc, const osg::Vec2& maxtc);
265 virtual osg::StateSet* createStateSet();
267 Font* getActiveFont();
269 String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last);
271 // members which have public access.
273 // iternal map used for rendering. Set up by the computeGlyphRepresentation() method.
274 TextureGlyphQuadMap _textureGlyphQuadMap;
276 void computeGlyphRepresentation();
278 // internal caches of the positioning of the text.
280 bool computeAverageGlyphWidthAndHeight(float& avg_width, float& avg_height) const;
282 virtual void computePositionsImplementation();
284 void computeColorGradients();
285 void computeColorGradientsOverall();
286 void computeColorGradientsPerCharacter();
288 void drawImplementation(osg::State& state, const osg::Vec4& colorMultiplier) const;
290 void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const;
292 ShaderTechnique _shaderTechnique;
293 bool _enableDepthWrites;
295 BackdropType _backdropType;
297 float _backdropHorizontalOffset;
298 float _backdropVerticalOffset;
299 osg::Vec4 _backdropColor;
301 ColorGradientMode _colorGradientMode;
302 osg::Vec4 _colorGradientTopLeft;
303 osg::Vec4 _colorGradientBottomLeft;
304 osg::Vec4 _colorGradientBottomRight;
305 osg::Vec4 _colorGradientTopRight;
308 // Helper function for color interpolation
309 float bilinearInterpolate(float x1, float x2, float y1, float y2, float x, float y, float q11, float q12, float q21, float q22) const;