3 #include "OSGSimpleGeometry.h"
4 #include "OSGGLUTWindow.h"
5 #include "OSGSimpleSceneManager.h"
6 #include "OSGBaseFunctions.h"
7 #include "OSGTransform.h"
10 #include "OSGMaterialChunk.h"
11 #include "OSGTextureTransformChunk.h"
12 #include "OSGSimpleStatisticsForeground.h"
13 #include "OSGSolidBackground.h"
14 #include "OSGGeometry.h"
15 #include "OSGTypedGeoIntegralProperty.h"
17 #include "OSGTextPixmapFace.h"
18 #include "OSGTextPixmapGlyph.h"
19 #include "OSGTextLayoutParam.h"
20 #include "OSGTextLayoutResult.h"
21 #include "OSGTextFaceFactory.h"
23 // Activate the OpenSG namespace
26 // The SimpleSceneManager to manage simple applications
27 OSG::SimpleSceneManagerRefPtr mgr
;
29 OSG::NodeRecPtr scene
;
31 OSG::SimpleStatisticsForegroundRecPtr statfg
;
32 OSG::StatElemDesc
<OSG::StatStringElem
> familyDesc("family", "The font family");
33 OSG::StatElemDesc
<OSG::StatStringElem
> styleDesc("style", "The font style");
34 OSG::StatElemDesc
<OSG::StatStringElem
> majorAlignDesc("majorAlignment", "The major alignment");
35 OSG::StatElemDesc
<OSG::StatStringElem
> minorAlignDesc("minorAlignment", "The minor alignment");
36 OSG::StatElemDesc
<OSG::StatStringElem
> dirDesc("direction", "The direction (horizontal or vertical)");
37 OSG::StatElemDesc
<OSG::StatStringElem
> horiDirDesc("horizontal direction", "The horizontal direction (left-to-right or right-to-left)");
38 OSG::StatElemDesc
<OSG::StatStringElem
> vertDirDesc("vertical direction", "The vertical direction (top-to-bottom or bottom-to-top)");
40 OSG::TextPixmapFaceRefPtr face
;
41 string family
= "SANS";
42 vector
<string
> families
;
43 OSG::TextFace::Style style
= OSG::TextFace::STYLE_PLAIN
;
44 OSG::TextLayoutParam layoutParam
;
49 // forward declaration so we can have the interesting stuff upfront
50 int setupGLUT( int *argc
, char *argv
[] );
52 // Create the coordinate cross
53 OSG::NodeTransitPtr
createCoordinateCross()
55 OSG::GeometryUnrecPtr geoPtr
= OSG::Geometry::create();
57 OSG::GeoUInt8PropertyUnrecPtr typesPtr
= OSG::GeoUInt8Property::create();
58 typesPtr
->push_back(GL_LINES
);
59 geoPtr
->setTypes(typesPtr
);
61 OSG::GeoUInt32PropertyUnrecPtr lensPtr
= OSG::GeoUInt32Property::create();
62 lensPtr
->push_back(6);
63 geoPtr
->setLengths(lensPtr
);
65 OSG::GeoPnt3fPropertyUnrecPtr posPtr
= OSG::GeoPnt3fProperty::create();
66 posPtr
->push_back(OSG::Vec3f(-0.1f
, 0.f
, 0.f
));
67 posPtr
->push_back(OSG::Vec3f(1.f
, 0.f
, 0.f
));
68 posPtr
->push_back(OSG::Vec3f(0.f
, -0.1f
, 0.f
));
69 posPtr
->push_back(OSG::Vec3f(0.f
, 1.f
, 0.f
));
70 posPtr
->push_back(OSG::Vec3f(0.f
, 0.f
, -0.1f
));
71 posPtr
->push_back(OSG::Vec3f(0.f
, 0.f
, 1.f
));
72 geoPtr
->setPositions(posPtr
);
74 OSG::GeoColor3fPropertyUnrecPtr colorsPtr
= OSG::GeoColor3fProperty::create();
75 colorsPtr
->push_back(OSG::Color3f(1.f
, 0.f
, 0.f
));
76 colorsPtr
->push_back(OSG::Color3f(0.f
, 1.f
, 0.f
));
77 colorsPtr
->push_back(OSG::Color3f(0.f
, 0.f
, 1.f
));
78 geoPtr
->setColors(colorsPtr
);
80 OSG::GeoUInt32PropertyUnrecPtr posIndicesPtr
= OSG::GeoUInt32Property::create();
81 OSG::GeoUInt32PropertyUnrecPtr colIndicesPtr
= OSG::GeoUInt32Property::create();
83 posIndicesPtr
->push_back(0);
84 colIndicesPtr
->push_back(0);
85 posIndicesPtr
->push_back(1);
86 colIndicesPtr
->push_back(0);
88 posIndicesPtr
->push_back(2);
89 colIndicesPtr
->push_back(1);
90 posIndicesPtr
->push_back(3);
91 colIndicesPtr
->push_back(1);
93 posIndicesPtr
->push_back(4);
94 colIndicesPtr
->push_back(2);
95 posIndicesPtr
->push_back(5);
96 colIndicesPtr
->push_back(2);
97 geoPtr
->setIndex(posIndicesPtr
, OSG::Geometry::PositionsIndex
);
98 geoPtr
->setIndex(colIndicesPtr
, OSG::Geometry::ColorsIndex
);
100 OSG::SimpleMaterialUnrecPtr matPtr
= OSG::SimpleMaterial::create();
101 geoPtr
->setMaterial(matPtr
);
103 OSG::NodeTransitPtr nodePtr
= OSG::Node::create();
104 nodePtr
->setCore(geoPtr
);
109 // Create the metrics
110 OSG::NodeTransitPtr
createMetrics(OSG::TextFace
*face
, OSG::Real32 scale
, const OSG::TextLayoutParam
&layoutParam
,
111 const OSG::TextLayoutResult
&layoutResult
)
113 OSG::GeometryUnrecPtr geoPtr
= OSG::Geometry::create();
115 OSG::GeoUInt8PropertyUnrecPtr typesPtr
= OSG::GeoUInt8Property::create();
116 geoPtr
->setTypes(typesPtr
);
118 OSG::GeoUInt32PropertyUnrecPtr lensPtr
= OSG::GeoUInt32Property::create();
119 geoPtr
->setLengths(lensPtr
);
121 OSG::GeoPnt3fPropertyUnrecPtr posPtr
= OSG::GeoPnt3fProperty::create();
122 geoPtr
->setPositions(posPtr
);
124 OSG::GeoColor3fPropertyUnrecPtr colorsPtr
= OSG::GeoColor3fProperty::create();
125 colorsPtr
->push_back(OSG::Color3f(0.f
, 0.f
, 1.f
));
126 colorsPtr
->push_back(OSG::Color3f(1.f
, 0.f
, 0.f
));
127 colorsPtr
->push_back(OSG::Color3f(0.f
, 1.f
, 0.f
));
128 colorsPtr
->push_back(OSG::Color3f(1.f
, 1.f
, 0.f
));
129 geoPtr
->setColors(colorsPtr
);
131 OSG::GeoUInt32PropertyUnrecPtr posIndicesPtr
= OSG::GeoUInt32Property::create();
132 geoPtr
->setIndex(posIndicesPtr
, OSG::Geometry::PositionsIndex
);
133 OSG::GeoUInt32PropertyUnrecPtr colIndicesPtr
= OSG::GeoUInt32Property::create();
134 geoPtr
->setIndex(colIndicesPtr
, OSG::Geometry::ColorsIndex
);
136 OSG::UInt32 i
, numGlyphs
= layoutResult
.getNumGlyphs();
137 for (i
= 0; i
< numGlyphs
; ++i
)
139 const OSG::TextGlyph
&glyph
= face
->getGlyph(layoutResult
.indices
[i
]);
140 typesPtr
->push_back(GL_LINE_LOOP
);
141 lensPtr
->push_back(4);
142 const OSG::Vec2f
&pos
= layoutResult
.positions
[i
];
143 OSG::Real32 left
= pos
.x() * scale
;
144 OSG::Real32 right
= (pos
.x() + glyph
.getWidth()) * scale
;
145 OSG::Real32 top
= pos
.y() * scale
;
146 OSG::Real32 bottom
= (pos
.y() - glyph
.getHeight()) * scale
;
147 OSG::UInt32 posOffset
= posPtr
->size();
148 posPtr
->push_back(OSG::Vec3f(left
, bottom
, 0.f
));
149 posPtr
->push_back(OSG::Vec3f(right
, bottom
, 0.f
));
150 posPtr
->push_back(OSG::Vec3f(right
, top
, 0.f
));
151 posPtr
->push_back(OSG::Vec3f(left
, top
, 0.f
));
152 posIndicesPtr
->push_back(posOffset
);
153 colIndicesPtr
->push_back(0);
154 posIndicesPtr
->push_back(posOffset
+ 1);
155 colIndicesPtr
->push_back(0);
156 posIndicesPtr
->push_back(posOffset
+ 2);
157 colIndicesPtr
->push_back(0);
158 posIndicesPtr
->push_back(posOffset
+ 3);
159 colIndicesPtr
->push_back(0);
163 OSG::Vec2f lowerLeft
, upperRight
;
164 face
->calculateBoundingBox(layoutResult
, lowerLeft
, upperRight
);
165 typesPtr
->push_back(GL_LINE_LOOP
);
166 lensPtr
->push_back(4);
167 OSG::Real32 left
= lowerLeft
.x() * scale
;
168 OSG::Real32 right
= upperRight
.x() * scale
;
169 OSG::Real32 top
= upperRight
.y() * scale
;
170 OSG::Real32 bottom
= lowerLeft
.y() * scale
;
171 OSG::UInt32 posOffset
= posPtr
->size();
172 posPtr
->push_back(OSG::Vec3f(left
, bottom
, 0.f
));
173 posPtr
->push_back(OSG::Vec3f(right
, bottom
, 0.f
));
174 posPtr
->push_back(OSG::Vec3f(right
, top
, 0.f
));
175 posPtr
->push_back(OSG::Vec3f(left
, top
, 0.f
));
176 posIndicesPtr
->push_back(posOffset
);
177 colIndicesPtr
->push_back(1);
178 posIndicesPtr
->push_back(posOffset
+ 1);
179 colIndicesPtr
->push_back(1);
180 posIndicesPtr
->push_back(posOffset
+ 2);
181 colIndicesPtr
->push_back(1);
182 posIndicesPtr
->push_back(posOffset
+ 3);
183 colIndicesPtr
->push_back(1);
185 // Text bounds & Line bounds
186 OSG::Vec2f pos
, textPos
, offset
;
187 if (layoutParam
.horizontal
== true)
189 OSG::Real32 lineHeight
= face
->getHoriAscent() - face
->getHoriDescent();
190 OSG::Real32 spacing
= layoutParam
.spacing
* lineHeight
;
191 if (layoutParam
.topToBottom
== true)
193 switch (layoutParam
.minorAlignment
)
195 case OSG::TextLayoutParam::ALIGN_BEGIN
:
197 case OSG::TextLayoutParam::ALIGN_FIRST
:
198 pos
[1] = textPos
[1] = face
->getHoriAscent();
200 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
201 pos
[1] = textPos
[1] = (spacing
* (layoutResult
.lineBounds
.size() - 1) + lineHeight
) / 2.f
;
203 case OSG::TextLayoutParam::ALIGN_END
:
204 pos
[1] = textPos
[1] = spacing
* (layoutResult
.lineBounds
.size() - 1) + lineHeight
;
207 offset
.setValues(0.f
, -spacing
);
211 switch (layoutParam
.minorAlignment
)
213 case OSG::TextLayoutParam::ALIGN_BEGIN
:
215 textPos
[1] = spacing
* (layoutResult
.lineBounds
.size() - 1) + lineHeight
;
217 case OSG::TextLayoutParam::ALIGN_FIRST
:
218 pos
[1] = face
->getHoriAscent();
219 textPos
[1] = spacing
* (layoutResult
.lineBounds
.size() - 1) + face
->getHoriAscent();
221 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
222 pos
[1] = -(spacing
* (layoutResult
.lineBounds
.size() - 1) + lineHeight
) / 2.f
+ lineHeight
;
223 textPos
[1] = (spacing
* (layoutResult
.lineBounds
.size() - 1) + lineHeight
) / 2.f
;
225 case OSG::TextLayoutParam::ALIGN_END
:
226 pos
[1] = -spacing
* (layoutResult
.lineBounds
.size() - 1);
229 offset
.setValues(0.f
, spacing
);
234 OSG::Real32 lineHeight
= face
->getVertDescent() - face
->getVertAscent();
235 OSG::Real32 spacing
= layoutParam
.spacing
* lineHeight
;
236 if (layoutParam
.leftToRight
== true)
238 switch (layoutParam
.minorAlignment
)
240 case OSG::TextLayoutParam::ALIGN_BEGIN
:
242 case OSG::TextLayoutParam::ALIGN_FIRST
:
243 pos
[0] = textPos
[0] = face
->getVertAscent();
245 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
246 pos
[0] = textPos
[0] = -(spacing
* (layoutResult
.lineBounds
.size() - 1) + lineHeight
) / 2.f
;
248 case OSG::TextLayoutParam::ALIGN_END
:
249 pos
[0] = textPos
[0] = -spacing
* (layoutResult
.lineBounds
.size() - 1) - lineHeight
;
252 offset
.setValues(spacing
, 0.f
);
256 switch (layoutParam
.minorAlignment
)
258 case OSG::TextLayoutParam::ALIGN_BEGIN
:
259 pos
[0] = -lineHeight
;
260 textPos
[0] = -spacing
* (layoutResult
.lineBounds
.size() - 1) - lineHeight
;
262 case OSG::TextLayoutParam::ALIGN_FIRST
:
263 pos
[0] = -face
->getVertDescent();
264 textPos
[0] = -spacing
* (layoutResult
.lineBounds
.size() - 1) -face
->getVertDescent();
266 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
267 pos
[0] = (spacing
* (layoutResult
.lineBounds
.size() - 1) + lineHeight
) / 2.f
- lineHeight
;
268 textPos
[0] = -(spacing
* (layoutResult
.lineBounds
.size() - 1) + lineHeight
) / 2.f
;
270 case OSG::TextLayoutParam::ALIGN_END
:
271 pos
[0] = spacing
* (layoutResult
.lineBounds
.size() - 1);
274 offset
.setValues(-spacing
, 0.f
);
278 typesPtr
->push_back(GL_LINE_LOOP
);
279 lensPtr
->push_back(4);
282 if (layoutParam
.horizontal
== true)
283 if (layoutParam
.leftToRight
== true)
284 switch (layoutParam
.majorAlignment
)
286 case OSG::TextLayoutParam::ALIGN_BEGIN
:
287 case OSG::TextLayoutParam::ALIGN_FIRST
:
289 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
290 left
-= layoutResult
.textBounds
.x() / 2.f
;
292 case OSG::TextLayoutParam::ALIGN_END
:
293 left
-= layoutResult
.textBounds
.x();
297 switch (layoutParam
.majorAlignment
)
299 case OSG::TextLayoutParam::ALIGN_BEGIN
:
300 case OSG::TextLayoutParam::ALIGN_FIRST
:
301 left
-= layoutResult
.textBounds
.x();
303 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
304 left
-= layoutResult
.textBounds
.x() / 2.f
;
306 case OSG::TextLayoutParam::ALIGN_END
:
310 if (layoutParam
.topToBottom
== true)
311 switch (layoutParam
.majorAlignment
)
313 case OSG::TextLayoutParam::ALIGN_BEGIN
:
314 case OSG::TextLayoutParam::ALIGN_FIRST
:
316 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
317 top
+= layoutResult
.textBounds
.y() / 2.f
;
319 case OSG::TextLayoutParam::ALIGN_END
:
320 top
+= layoutResult
.textBounds
.y();
324 switch (layoutParam
.majorAlignment
)
326 case OSG::TextLayoutParam::ALIGN_BEGIN
:
327 case OSG::TextLayoutParam::ALIGN_FIRST
:
328 top
+= layoutResult
.textBounds
.y();
330 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
331 top
+= layoutResult
.textBounds
.y() / 2.f
;
333 case OSG::TextLayoutParam::ALIGN_END
:
337 right
= left
+ layoutResult
.textBounds
.x() * scale
;
339 bottom
= top
- layoutResult
.textBounds
.y() * scale
;
340 posOffset
= posPtr
->size();
341 posPtr
->push_back(OSG::Vec3f(left
, bottom
, 0.f
));
342 posPtr
->push_back(OSG::Vec3f(right
, bottom
, 0.f
));
343 posPtr
->push_back(OSG::Vec3f(right
, top
, 0.f
));
344 posPtr
->push_back(OSG::Vec3f(left
, top
, 0.f
));
345 posIndicesPtr
->push_back(posOffset
);
346 colIndicesPtr
->push_back(3);
347 posIndicesPtr
->push_back(posOffset
+ 1);
348 colIndicesPtr
->push_back(3);
349 posIndicesPtr
->push_back(posOffset
+ 2);
350 colIndicesPtr
->push_back(3);
351 posIndicesPtr
->push_back(posOffset
+ 3);
352 colIndicesPtr
->push_back(3);
354 vector
<OSG::Vec2f
>::const_iterator lbIt
;
355 for (lbIt
= layoutResult
.lineBounds
.begin(); lbIt
!= layoutResult
.lineBounds
.end(); ++lbIt
)
357 typesPtr
->push_back(GL_LINE_LOOP
);
358 lensPtr
->push_back(4);
359 OSG::Real32 left
= pos
.x();
360 OSG::Real32 top
= pos
.y();
361 if (layoutParam
.horizontal
== true)
362 if (layoutParam
.leftToRight
== true)
363 switch (layoutParam
.majorAlignment
)
365 case OSG::TextLayoutParam::ALIGN_BEGIN
:
366 case OSG::TextLayoutParam::ALIGN_FIRST
:
368 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
369 left
-= lbIt
->x() / 2.f
;
371 case OSG::TextLayoutParam::ALIGN_END
:
376 switch (layoutParam
.majorAlignment
)
378 case OSG::TextLayoutParam::ALIGN_BEGIN
:
379 case OSG::TextLayoutParam::ALIGN_FIRST
:
382 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
383 left
-= lbIt
->x() / 2.f
;
385 case OSG::TextLayoutParam::ALIGN_END
:
389 if (layoutParam
.topToBottom
== true)
390 switch (layoutParam
.majorAlignment
)
392 case OSG::TextLayoutParam::ALIGN_BEGIN
:
393 case OSG::TextLayoutParam::ALIGN_FIRST
:
395 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
396 top
+= lbIt
->y() / 2.f
;
398 case OSG::TextLayoutParam::ALIGN_END
:
403 switch (layoutParam
.majorAlignment
)
405 case OSG::TextLayoutParam::ALIGN_BEGIN
:
406 case OSG::TextLayoutParam::ALIGN_FIRST
:
409 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
410 top
+= lbIt
->y() / 2.f
;
412 case OSG::TextLayoutParam::ALIGN_END
:
416 OSG::Real32 right
= left
+ lbIt
->x() * scale
;
418 OSG::Real32 bottom
= top
- lbIt
->y() * scale
;
419 OSG::UInt32 posOffset
= posPtr
->size();
420 posPtr
->push_back(OSG::Vec3f(left
, bottom
, 0.f
));
421 posPtr
->push_back(OSG::Vec3f(right
, bottom
, 0.f
));
422 posPtr
->push_back(OSG::Vec3f(right
, top
, 0.f
));
423 posPtr
->push_back(OSG::Vec3f(left
, top
, 0.f
));
424 posIndicesPtr
->push_back(posOffset
);
425 colIndicesPtr
->push_back(2);
426 posIndicesPtr
->push_back(posOffset
+ 1);
427 colIndicesPtr
->push_back(2);
428 posIndicesPtr
->push_back(posOffset
+ 2);
429 colIndicesPtr
->push_back(2);
430 posIndicesPtr
->push_back(posOffset
+ 3);
431 colIndicesPtr
->push_back(2);
433 typesPtr
->push_back(GL_LINE_STRIP
);
434 lensPtr
->push_back(2);
435 posOffset
= posPtr
->size();
436 if (layoutParam
.horizontal
== true)
438 OSG::Real32 base
= top
- face
->getHoriAscent() * scale
;
439 posPtr
->push_back(OSG::Vec3f(left
, base
, 0.f
));
440 posPtr
->push_back(OSG::Vec3f(right
, base
, 0.f
));
444 OSG::Real32 base
= left
- face
->getVertAscent() * scale
;
445 posPtr
->push_back(OSG::Vec3f(base
, top
, 0.f
));
446 posPtr
->push_back(OSG::Vec3f(base
, bottom
, 0.f
));
448 posIndicesPtr
->push_back(posOffset
);
449 colIndicesPtr
->push_back(2);
450 posIndicesPtr
->push_back(posOffset
+ 1);
451 colIndicesPtr
->push_back(2);
455 OSG::SimpleMaterialUnrecPtr matPtr
= OSG::SimpleMaterial::create();
456 geoPtr
->setMaterial(matPtr
);
458 OSG::NodeTransitPtr nodePtr
= OSG::Node::create();
459 nodePtr
->setCore(geoPtr
);
464 void updateFace(void)
466 // Try to create new face
467 OSG::TextPixmapFaceRefPtr newFace
= OSG::TextPixmapFace::create(family
, style
, 78);
472 // Update information on the screen
473 family
= face
->getFamily();
475 if(statfg
->getCollector() != NULL
)
477 statfg
->getCollector()->getElem(familyDesc
)->set(family
);
478 style
= face
->getStyle();
479 OSG::StatStringElem
*statElem
= statfg
->getCollector()->getElem(styleDesc
);
482 case OSG::TextFace::STYLE_PLAIN
:
483 statElem
->set("Plain");
485 case OSG::TextFace::STYLE_BOLD
:
486 statElem
->set("Bold");
488 case OSG::TextFace::STYLE_ITALIC
:
489 statElem
->set("Italic");
491 case OSG::TextFace::STYLE_BOLDITALIC
:
492 statElem
->set("Bold & Italic");
498 const char *alignmentToString(OSG::TextLayoutParam::Alignment alignment
)
502 case OSG::TextLayoutParam::ALIGN_FIRST
:
504 case OSG::TextLayoutParam::ALIGN_BEGIN
:
506 case OSG::TextLayoutParam::ALIGN_MIDDLE
:
508 case OSG::TextLayoutParam::ALIGN_END
:
515 void updateScene(void)
517 if(statfg
->getCollector() != NULL
)
519 statfg
->getCollector()->getElem(majorAlignDesc
)->set(alignmentToString(layoutParam
.majorAlignment
));
520 statfg
->getCollector()->getElem(minorAlignDesc
)->set(alignmentToString(layoutParam
.minorAlignment
));
521 statfg
->getCollector()->getElem(dirDesc
)->set(layoutParam
.horizontal
? "Horizontal" : "Vertical");
522 statfg
->getCollector()->getElem(horiDirDesc
)->set(layoutParam
.leftToRight
? "Left to right" : "Right to left");
523 statfg
->getCollector()->getElem(vertDirDesc
)->set(layoutParam
.topToBottom
? "Top to bottom" : "Bottom to top");
529 OSG::TextLayoutResult layoutResult
;
530 face
->layout(lines
, layoutParam
, layoutResult
);
532 OSG::ImageUnrecPtr imagePtr
= face
->makeImage(layoutResult
, offset
);
533 OSG::Real32 width
= imagePtr
->getWidth();
534 OSG::Real32 height
= imagePtr
->getHeight();
535 OSG::Real32 scale
= 2.f
/ (face
->getHoriAscent() - face
->getHoriDescent());
537 // Put it all together into a Geometry NodeCore.
538 OSG::GeometryUnrecPtr geo
= OSG::makePlaneGeo(width
* scale
, height
* scale
, 1, 1);
539 OSG::NodeUnrecPtr textNode
= OSG::Node::create();
540 textNode
->setCore(geo
);
541 OSG::NodeUnrecPtr transNodePtr
= OSG::Node::create();
542 OSG::TransformUnrecPtr transPtr
= OSG::Transform::create();
543 OSG::Matrix transMatrix
;
544 transMatrix
.setTranslate((offset
.x() + width
/ 2.f
) * scale
, (offset
.y() - height
/ 2.f
) * scale
, -0.03f
);
545 transPtr
->setMatrix(transMatrix
);
546 transNodePtr
->setCore(transPtr
);
547 transNodePtr
->addChild(textNode
);
549 OSG::TextureObjChunkUnrecPtr texObjChunk
= OSG::TextureObjChunk::create();
550 texObjChunk
->setImage(imagePtr
);
551 texObjChunk
->setScale(false);
552 texObjChunk
->setWrapS(GL_CLAMP
);
553 texObjChunk
->setWrapT(GL_CLAMP
);
554 texObjChunk
->setMagFilter(GL_NEAREST
);
555 texObjChunk
->setMinFilter(GL_NEAREST
);
557 OSG::TextureEnvChunkUnrecPtr texEnvChunk
= OSG::TextureEnvChunk::create();
558 texEnvChunk
->setEnvMode(GL_MODULATE
);
560 OSG::TextureTransformChunkUnrecPtr texTransChunk
= OSG::TextureTransformChunk::create();
561 OSG::Real32 textureWidth
= OSG::osgNextPower2(static_cast<OSG::UInt32
>(width
));
562 OSG::Real32 textureHeight
= OSG::osgNextPower2(static_cast<OSG::UInt32
>(height
));
564 matrix
.setScale(width
/ textureWidth
, height
/ textureHeight
, 1.f
);
565 texTransChunk
->setMatrix(matrix
);
567 OSG::MaterialChunkUnrecPtr matChunk
= OSG::MaterialChunk::create();
568 matChunk
->setAmbient(OSG::Color4f(1.f
, 1.f
, 1.f
, 1.f
));
569 matChunk
->setDiffuse(OSG::Color4f(1.f
, 1.f
, 1.f
, 1.f
));
570 matChunk
->setEmission(OSG::Color4f(0.f
, 0.f
, 0.f
, 1.f
));
571 matChunk
->setSpecular(OSG::Color4f(0.f
, 0.f
, 0.f
, 1.f
));
572 matChunk
->setShininess(0);
574 OSG::BlendChunkUnrecPtr blendChunk
= OSG::BlendChunk::create();
575 blendChunk
->setSrcFactor(GL_SRC_ALPHA
);
576 blendChunk
->setDestFactor(GL_ONE_MINUS_SRC_ALPHA
);
578 OSG::ChunkMaterialUnrecPtr m
= OSG::ChunkMaterial::create();
579 m
->addChunk(texObjChunk
);
580 m
->addChunk(texEnvChunk
);
581 m
->addChunk(texTransChunk
);
582 m
->addChunk(matChunk
);
583 m
->addChunk(blendChunk
);
587 scene
->clearChildren();
588 scene
->addChild(createCoordinateCross());
589 scene
->addChild(createMetrics(face
, scale
, layoutParam
, layoutResult
));
590 scene
->addChild(transNodePtr
);
593 // Initialize GLUT & OpenSG and set up the scene
594 int main(int argc
, char **argv
)
597 OSG::osgInit(argc
,argv
);
600 int winid
= setupGLUT(&argc
, argv
);
603 // the connection between GLUT and OpenSG
604 OSG::GLUTWindowUnrecPtr gwin
= OSG::GLUTWindow::create();
605 gwin
->setGlutId(winid
);
608 lines
.push_back(argc
>= 2 ? argv
[1] : "Hello World!");
609 lines
.push_back("Powered by OpenSG");
610 lines
.push_back("3rd line");
611 layoutParam
.spacing
= 1.5f
;
612 //layoutParam.length.push_back(10.f * 78.f);
613 //layoutParam.length.push_back(7.f * 78.f);
614 //layoutParam.length.push_back(-1.f * 78.f);
616 // put the geometry core into a node
617 scene
= OSG::Node::create();
618 OSG::GroupUnrecPtr groupPtr
= OSG::Group::create();
619 scene
->setCore(groupPtr
);
621 statfg
= OSG::SimpleStatisticsForeground::create();
623 statfg
->setColor(OSG::Color4f(0,1,0,0.9f
));
624 statfg
->addElement(familyDesc
, "Family: %s");
625 statfg
->addElement(styleDesc
, "Style: %s");
626 statfg
->addElement(majorAlignDesc
, "Major Alignment: %s");
627 statfg
->addElement(minorAlignDesc
, "Minor Alignment: %s");
628 statfg
->addElement(dirDesc
, "%s");
629 statfg
->addElement(horiDirDesc
, "%s");
630 statfg
->addElement(vertDirDesc
, "%s");
632 // Create the background
633 OSG::SolidBackgroundUnrecPtr bg
= OSG::SolidBackground::create();
634 bg
->setColor(OSG::Color3f(0.1f
, 0.1f
, 0.5f
));
639 // create the SimpleSceneManager helper
640 mgr
= OSG::SimpleSceneManager::create();
642 // tell the manager what to manage
643 mgr
->setWindow(gwin
);
644 mgr
->setRoot (scene
);
646 // show the whole scene
649 // add the statistics forground and the background
650 gwin
->getPort(0)->addForeground(statfg
);
651 gwin
->getPort(0)->setBackground(bg
);
661 // GLUT callback functions
670 // react to size changes
671 void reshape(int w
, int h
)
677 // react to mouse button presses
678 void mouse(int button
, int state
, int x
, int y
)
681 mgr
->mouseButtonRelease(button
, x
, y
);
683 mgr
->mouseButtonPress(button
, x
, y
);
688 // react to mouse motions with pressed buttons
689 void motion(int x
, int y
)
691 mgr
->mouseMove(x
, y
);
696 void keyboard(unsigned char k
, int x
, int y
)
714 #define COMMAND_FAMILY_SANS 701
715 #define COMMAND_FAMILY_SERIF 702
716 #define COMMAND_FAMILY_TYPEWRITER 703
717 #define COMMAND_FAMILY_BASE 704
718 #define COMMAND_STYLE_PLAIN 301
719 #define COMMAND_STYLE_BOLD 302
720 #define COMMAND_STYLE_ITALIC 303
721 #define COMMAND_STYLE_BOLDITALIC 304
722 #define COMMAND_MAJORALIGNMENT_FIRST 101
723 #define COMMAND_MAJORALIGNMENT_BEGIN 102
724 #define COMMAND_MAJORALIGNMENT_MIDDLE 103
725 #define COMMAND_MAJORALIGNMENT_END 104
726 #define COMMAND_MINORALIGNMENT_FIRST 201
727 #define COMMAND_MINORALIGNMENT_BEGIN 202
728 #define COMMAND_MINORALIGNMENT_MIDDLE 203
729 #define COMMAND_MINORALIGNMENT_END 204
730 #define COMMAND_HORIZONTAL 401
731 #define COMMAND_VERTICAL 402
732 #define COMMAND_LEFTTORIGHT 501
733 #define COMMAND_RIGHTTOLEFT 502
734 #define COMMAND_TOPTOBOTTOM 601
735 #define COMMAND_BOTTOMTOTOP 602
737 void menu(int command
)
741 case COMMAND_FAMILY_SANS
:
745 case COMMAND_FAMILY_SERIF
:
749 case COMMAND_FAMILY_TYPEWRITER
:
750 family
= "TYPEWRITER";
753 case COMMAND_STYLE_PLAIN
:
754 style
= OSG::TextFace::STYLE_PLAIN
;
757 case COMMAND_STYLE_BOLD
:
758 style
= OSG::TextFace::STYLE_BOLD
;
761 case COMMAND_STYLE_ITALIC
:
762 style
= OSG::TextFace::STYLE_ITALIC
;
765 case COMMAND_STYLE_BOLDITALIC
:
766 style
= OSG::TextFace::STYLE_BOLDITALIC
;
769 case COMMAND_MAJORALIGNMENT_FIRST
:
770 layoutParam
.majorAlignment
= OSG::TextLayoutParam::ALIGN_FIRST
;
772 case COMMAND_MAJORALIGNMENT_BEGIN
:
773 layoutParam
.majorAlignment
= OSG::TextLayoutParam::ALIGN_BEGIN
;
775 case COMMAND_MAJORALIGNMENT_MIDDLE
:
776 layoutParam
.majorAlignment
= OSG::TextLayoutParam::ALIGN_MIDDLE
;
778 case COMMAND_MAJORALIGNMENT_END
:
779 layoutParam
.majorAlignment
= OSG::TextLayoutParam::ALIGN_END
;
781 case COMMAND_MINORALIGNMENT_FIRST
:
782 layoutParam
.minorAlignment
= OSG::TextLayoutParam::ALIGN_FIRST
;
784 case COMMAND_MINORALIGNMENT_BEGIN
:
785 layoutParam
.minorAlignment
= OSG::TextLayoutParam::ALIGN_BEGIN
;
787 case COMMAND_MINORALIGNMENT_MIDDLE
:
788 layoutParam
.minorAlignment
= OSG::TextLayoutParam::ALIGN_MIDDLE
;
790 case COMMAND_MINORALIGNMENT_END
:
791 layoutParam
.minorAlignment
= OSG::TextLayoutParam::ALIGN_END
;
793 case COMMAND_HORIZONTAL
:
794 layoutParam
.horizontal
= true;
795 glutSetMenu(mainMenuID
);
796 glutChangeToMenuEntry(5, "Vertical", COMMAND_VERTICAL
);
798 case COMMAND_VERTICAL
:
799 layoutParam
.horizontal
= false;
800 glutSetMenu(mainMenuID
);
801 glutChangeToMenuEntry(5, "Horizontal", COMMAND_HORIZONTAL
);
803 case COMMAND_LEFTTORIGHT
:
804 layoutParam
.leftToRight
= true;
805 glutSetMenu(mainMenuID
);
806 glutChangeToMenuEntry(6, "Right to left", COMMAND_RIGHTTOLEFT
);
808 case COMMAND_RIGHTTOLEFT
:
809 layoutParam
.leftToRight
= false;
810 glutSetMenu(mainMenuID
);
811 glutChangeToMenuEntry(6, "Left to right", COMMAND_LEFTTORIGHT
);
813 case COMMAND_TOPTOBOTTOM
:
814 layoutParam
.topToBottom
= true;
815 glutSetMenu(mainMenuID
);
816 glutChangeToMenuEntry(7, "Bottom to top", COMMAND_BOTTOMTOTOP
);
818 case COMMAND_BOTTOMTOTOP
:
819 layoutParam
.topToBottom
= false;
820 glutSetMenu(mainMenuID
);
821 glutChangeToMenuEntry(7, "Top to bottom", COMMAND_TOPTOBOTTOM
);
824 if (command
< COMMAND_FAMILY_BASE
)
826 family
= families
[command
- COMMAND_FAMILY_BASE
];
834 // setup the GLUT library which handles the windows for us
835 int setupGLUT(int *argc
, char *argv
[])
837 glutInit(argc
, argv
);
838 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
840 int winid
= glutCreateWindow("OpenSG");
842 glutReshapeFunc(reshape
);
843 glutDisplayFunc(display
);
844 glutMouseFunc(mouse
);
845 glutMotionFunc(motion
);
846 glutKeyboardFunc(keyboard
);
848 int familyMenuID
= glutCreateMenu(menu
);
849 glutSetMenu(familyMenuID
);
850 glutAddMenuEntry("SANS", COMMAND_FAMILY_SANS
);
851 glutAddMenuEntry("SERIF", COMMAND_FAMILY_SERIF
);
852 glutAddMenuEntry("TYPEWRITER", COMMAND_FAMILY_TYPEWRITER
);
853 OSG::TextFaceFactory::the()->getFontFamilies(families
);
855 for (i
= 0; i
< families
.size(); ++i
)
856 glutAddMenuEntry(families
[i
].c_str(), COMMAND_FAMILY_BASE
+ i
);
857 int styleMenuID
= glutCreateMenu(menu
);
858 glutSetMenu(styleMenuID
);
859 glutAddMenuEntry("Plain", COMMAND_STYLE_PLAIN
);
860 glutAddMenuEntry("Bold", COMMAND_STYLE_BOLD
);
861 glutAddMenuEntry("Italic", COMMAND_STYLE_ITALIC
);
862 glutAddMenuEntry("Bold + Italic", COMMAND_STYLE_BOLDITALIC
);
863 int majorAlignmentMenuID
= glutCreateMenu(menu
);
864 glutSetMenu(majorAlignmentMenuID
);
865 glutAddMenuEntry("First", COMMAND_MAJORALIGNMENT_FIRST
);
866 glutAddMenuEntry("Begin", COMMAND_MAJORALIGNMENT_BEGIN
);
867 glutAddMenuEntry("Middle", COMMAND_MAJORALIGNMENT_MIDDLE
);
868 glutAddMenuEntry("End", COMMAND_MAJORALIGNMENT_END
);
869 int minorAlignmentMenuID
= glutCreateMenu(menu
);
870 glutSetMenu(minorAlignmentMenuID
);
871 glutAddMenuEntry("First", COMMAND_MINORALIGNMENT_FIRST
);
872 glutAddMenuEntry("Begin", COMMAND_MINORALIGNMENT_BEGIN
);
873 glutAddMenuEntry("Middle", COMMAND_MINORALIGNMENT_MIDDLE
);
874 glutAddMenuEntry("End", COMMAND_MINORALIGNMENT_END
);
875 mainMenuID
= glutCreateMenu(menu
);
876 glutSetMenu(mainMenuID
);
877 glutAddSubMenu("Family", familyMenuID
);
878 glutAddSubMenu("Style", styleMenuID
);
879 glutAddSubMenu("Major Alignment", majorAlignmentMenuID
);
880 glutAddSubMenu("Minor Alignment", minorAlignmentMenuID
);
881 glutAddMenuEntry("Vertical", COMMAND_VERTICAL
);
882 glutAddMenuEntry("Right to left", COMMAND_RIGHTTOLEFT
);
883 glutAddMenuEntry("Bottom to top", COMMAND_BOTTOMTOTOP
);
884 glutAttachMenu(GLUT_RIGHT_BUTTON
);