openscenegraph
Text
Go to the documentation of this file.
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
14#ifndef OSGTEXT_TEXT
15#define OSGTEXT_TEXT 1
16
17
18#include <osg/Drawable>
19#include <osg/Quat>
20
21#include <osgText/TextBase>
22#include <osgText/Font>
23
24namespace osgText {
25
26class OSGTEXT_EXPORT Text : public osgText::TextBase
27{
28public:
29
30 Text();
31 Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
32
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"; }
38
39 /** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/
40 void setShaderTechnique(ShaderTechnique technique);
41
42 /** Get the ShaderTechnique hint.*/
43 ShaderTechnique getShaderTechnique() { return _shaderTechnique; }
44
45
46 /**
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.
51 */
52 void setEnableDepthWrites(bool enable) { _enableDepthWrites = enable; }
53 bool getEnableDepthWrites() const { return _enableDepthWrites; }
54
55
56 enum BackdropType
57 {
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,
65 DROP_SHADOW_TOP_LEFT,
66 OUTLINE,
67 NONE
68 };
69
70 /**
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.
84 */
85 void setBackdropType(BackdropType type);
86
87 BackdropType getBackdropType() const { return _backdropType; }
88
89 /**
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).
104 */
105 void setBackdropOffset(float offset = 0.07f);
106 /**
107 * This overloaded version lets you specify the offset for the horizontal
108 * and vertical components separately.
109 */
110 void setBackdropOffset(float horizontal, float vertical);
111
112 float getBackdropHorizontalOffset() const { return _backdropHorizontalOffset; }
113
114 float getBackdropVerticalOffset() const { return _backdropVerticalOffset; }
115
116 /**
117 * This specifies the color of the backdrop text.
118 * The default is black.
119 */
120 void setBackdropColor(const osg::Vec4& color);
121
122 const osg::Vec4& getBackdropColor() const { return _backdropColor; }
123
124 enum ColorGradientMode
125 {
126 SOLID = 0, // a.k.a. ColorGradients off
127 PER_CHARACTER,
128 OVERALL
129 };
130
131 /**
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).
147 */
148 void setColorGradientMode(ColorGradientMode mode);
149
150 ColorGradientMode getColorGradientMode() const { return _colorGradientMode; }
151
152 /**
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.
156 */
157 void setColorGradientCorners(const osg::Vec4& topLeft, const osg::Vec4& bottomLeft, const osg::Vec4& bottomRight, const osg::Vec4& topRight);
158
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; }
163
164
165
166 /** Draw the text.*/
167 virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
168
169 /** return false, osgText::Text does not support accept(AttributeFunctor&).*/
170 virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; }
171
172 /** return true, osgText::Text does support accept(ConstAttributeFunctor&).*/
173 virtual bool supports(const osg::Drawable::ConstAttributeFunctor&) const { return true; }
174
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;
177
178 /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/
179 virtual bool supports(const osg::PrimitiveFunctor&) const { return true; }
180
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;
183
184
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;
187
188 /** Resize any per context GLObject buffers to specified size. */
189 virtual void resizeGLObjectBuffers(unsigned int maxSize);
190
191
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;
196
197public:
198
199 /** deprecated, value ignored.*/
200 enum BackdropImplementation
201 {
202 POLYGON_OFFSET = 0,
203 NO_DEPTH_BUFFER,
204 DEPTH_RANGE,
205 STENCIL_BUFFER,
206 DELAYED_DEPTH_WRITES
207 };
208
209 /** deprecated, value ignored.*/
210 void setBackdropImplementation(BackdropImplementation) {}
211 /** deprecated, value should be ignored.*/
212 BackdropImplementation getBackdropImplementation() const { return DELAYED_DEPTH_WRITES; }
213
214 // internal structures, variable and methods used for rendering of characters.
215 struct OSGTEXT_EXPORT GlyphQuads
216 {
217 typedef std::vector<Glyph*> Glyphs;
218
219 Glyphs _glyphs;
220 osg::ref_ptr<osg::DrawElements> _primitives;
221
222 GlyphQuads();
223 GlyphQuads(const GlyphQuads& gq);
224
225 void setupPrimitives(Text::BackdropType backdropType);
226
227 Glyphs& getGlyphs() { return _glyphs; }
228 const Glyphs& getGlyphs() const { return _glyphs; }
229
230 /** Resize any per context GLObject buffers to specified size. */
231 void resizeGLObjectBuffers(unsigned int maxSize);
232
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;
237
238 private:
239
240 GlyphQuads& operator = (const GlyphQuads&) { return *this; }
241 };
242
243 typedef std::map<osg::ref_ptr<GlyphTexture>,GlyphQuads> TextureGlyphQuadMap;
244
245 /** Direct Access to GlyphQuads */
246 const GlyphQuads* getGlyphQuads(GlyphTexture* texture) const
247 {
248 TextureGlyphQuadMap::const_iterator itGlyphQuad = _textureGlyphQuadMap.find(texture);
249 if (itGlyphQuad == _textureGlyphQuadMap.end()) return NULL;
250
251 return &itGlyphQuad->second;
252 }
253
254 const TextureGlyphQuadMap& getTextureGlyphQuadMap() const
255 {
256 return _textureGlyphQuadMap;
257 }
258
259 void addGlyphQuad(Glyph* glyph, const osg::Vec2& minc, const osg::Vec2& maxc, const osg::Vec2& mintc, const osg::Vec2& maxtc);
260
261protected:
262
263 virtual ~Text();
264
265 virtual osg::StateSet* createStateSet();
266
267 Font* getActiveFont();
268
269 String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last);
270
271 // members which have public access.
272
273 // iternal map used for rendering. Set up by the computeGlyphRepresentation() method.
274 TextureGlyphQuadMap _textureGlyphQuadMap;
275
276 void computeGlyphRepresentation();
277
278 // internal caches of the positioning of the text.
279
280 bool computeAverageGlyphWidthAndHeight(float& avg_width, float& avg_height) const;
281
282 virtual void computePositionsImplementation();
283
284 void computeColorGradients();
285 void computeColorGradientsOverall();
286 void computeColorGradientsPerCharacter();
287
288 void drawImplementation(osg::State& state, const osg::Vec4& colorMultiplier) const;
289
290 void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const;
291
292 ShaderTechnique _shaderTechnique;
293 bool _enableDepthWrites;
294
295 BackdropType _backdropType;
296
297 float _backdropHorizontalOffset;
298 float _backdropVerticalOffset;
299 osg::Vec4 _backdropColor;
300
301 ColorGradientMode _colorGradientMode;
302 osg::Vec4 _colorGradientTopLeft;
303 osg::Vec4 _colorGradientBottomLeft;
304 osg::Vec4 _colorGradientBottomRight;
305 osg::Vec4 _colorGradientTopRight;
306
307
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;
310};
311
312}
313
314
315#endif