3 #include "OSGSimpleGeometry.h"
4 #include "OSGGLUTWindow.h"
5 #include "OSGSimpleSceneManager.h"
6 #include "OSGBaseFunctions.h"
7 #include "OSGTransform.h"
9 #include "OSGSimpleStatisticsForeground.h"
10 #include "OSGSolidBackground.h"
12 #include "OSGMaterialChunk.h"
13 #include "OSGTextureTransformChunk.h"
14 #include "OSGSolidBackground.h"
15 #include "OSGGeometry.h"
16 #include "OSGTypedGeoIntegralProperty.h"
18 #include "OSGTextTXFFace.h"
19 #include "OSGTextTXFGlyph.h"
20 #include "OSGTextFaceFactory.h"
24 // Activate the OpenSG namespace
27 #define COMMAND_FAMILY_SANS 701
28 #define COMMAND_FAMILY_SERIF 702
29 #define COMMAND_FAMILY_TYPEWRITER 703
30 #define COMMAND_FAMILY_BASE 704
31 #define COMMAND_STYLE_PLAIN 301
32 #define COMMAND_STYLE_BOLD 302
33 #define COMMAND_STYLE_ITALIC 303
34 #define COMMAND_STYLE_BOLDITALIC 304
35 #define COMMAND_SIZE_INC1 401
36 #define COMMAND_SIZE_INC10 402
37 #define COMMAND_SIZE_DEC1 403
38 #define COMMAND_SIZE_DEC10 404
39 #define COMMAND_GAP_INC1 501
40 #define COMMAND_GAP_DEC1 502
41 #define COMMAND_TEXTUREWIDTH_AUTO 601
42 #define COMMAND_TEXTUREWIDTH_64 602
43 #define COMMAND_TEXTUREWIDTH_128 603
44 #define COMMAND_TEXTUREWIDTH_256 604
45 #define COMMAND_TEXTUREWIDTH_512 605
46 #define COMMAND_TEXTUREWIDTH_1024 606
47 #define COMMAND_TEXTUREWIDTH_2048 607
48 #define COMMAND_TEXTUREWIDTH_4096 608
49 #define COMMAND_WRITE_TO_FILE 901
51 // The SimpleSceneManager to manage simple applications
52 OSG::SimpleSceneManagerRefPtr mgr
;
54 OSG::NodeRecPtr scene
;
56 OSG::SimpleStatisticsForegroundRecPtr statfg
;
57 OSG::StatElemDesc
<OSG::StatStringElem
> familyDesc("family", "The font family");
58 OSG::StatElemDesc
<OSG::StatStringElem
> styleDesc("style", "The font style");
59 OSG::StatElemDesc
<OSG::StatIntElem
> sizeDesc("size", "The height of the characters");
60 OSG::StatElemDesc
<OSG::StatIntElem
> gapDesc("gap", "The gap between characters");
61 OSG::StatElemDesc
<OSG::StatStringElem
> textureSizeDesc("textureSize", "The size of the texture");
63 OSG::TextTXFFaceRefPtr face
= 0;
65 vector
<string
> families
;
66 OSG::TextFace::Style style
= OSG::TextFace::STYLE_PLAIN
;
67 OSG::TextTXFParam param
;
72 // forward declaration so we can have the interesting stuff upfront
73 int setupGLUT( int *argc
, char *argv
[] );
76 OSG::NodeTransitPtr
createMetrics(OSG::TextTXFFace
*face
, OSG::UInt32 width
, OSG::UInt32 height
)
78 OSG::GeometryUnrecPtr geoPtr
= OSG::Geometry::create();
80 OSG::GeoUInt8PropertyUnrecPtr typesPtr
= OSG::GeoUInt8Property::create();
81 geoPtr
->setTypes(typesPtr
);
83 OSG::GeoUInt32PropertyUnrecPtr lensPtr
= OSG::GeoUInt32Property::create();
84 geoPtr
->setLengths(lensPtr
);
86 OSG::GeoPnt3fPropertyUnrecPtr posPtr
= OSG::GeoPnt3fProperty::create();
87 geoPtr
->setPositions(posPtr
);
89 OSG::GeoColor3fPropertyUnrecPtr colorsPtr
= OSG::GeoColor3fProperty::create();
90 colorsPtr
->push_back(OSG::Color3f(0.f
, 0.f
, 1.f
));
91 colorsPtr
->push_back(OSG::Color3f(1.f
, 0.f
, 0.f
));
92 geoPtr
->setColors(colorsPtr
);
94 OSG::GeoUInt32PropertyUnrecPtr posIndicesPtr
= OSG::GeoUInt32Property::create();
95 geoPtr
->setIndex(posIndicesPtr
, OSG::Geometry::PositionsIndex
);
96 OSG::GeoUInt32PropertyUnrecPtr colIndicesPtr
= OSG::GeoUInt32Property::create();
97 geoPtr
->setIndex(colIndicesPtr
, OSG::Geometry::ColorsIndex
);
99 wstring characters
= face
->getParam().getCharacters();
100 wstring::const_iterator it
;
101 for (it
= characters
.begin(); it
!= characters
.end(); ++it
)
103 const OSG::TextTXFGlyph
&glyph
= face
->getTXFGlyph(*it
);
104 typesPtr
->push_back(GL_LINE_LOOP
);
105 lensPtr
->push_back(4);
106 OSG::Real32 left
= static_cast<OSG::Real32
>(width
) * -0.5f
+ glyph
.getX();
107 OSG::Real32 right
= left
+ static_cast<OSG::Real32
>(glyph
.getPixmapWidth());
108 OSG::Real32 bottom
= static_cast<OSG::Real32
>(height
) * -0.5f
+ glyph
.getY();
109 OSG::Real32 top
= bottom
+ static_cast<OSG::Real32
>(glyph
.getPixmapHeight());
110 OSG::UInt32 posOffset
= posPtr
->size();
111 posPtr
->push_back(OSG::Vec3f(left
, bottom
, 0.f
));
112 posPtr
->push_back(OSG::Vec3f(right
, bottom
, 0.f
));
113 posPtr
->push_back(OSG::Vec3f(right
, top
, 0.f
));
114 posPtr
->push_back(OSG::Vec3f(left
, top
, 0.f
));
115 posIndicesPtr
->push_back(posOffset
);
116 colIndicesPtr
->push_back(0);
117 posIndicesPtr
->push_back(posOffset
+ 1);
118 colIndicesPtr
->push_back(0);
119 posIndicesPtr
->push_back(posOffset
+ 2);
120 colIndicesPtr
->push_back(0);
121 posIndicesPtr
->push_back(posOffset
+ 3);
122 colIndicesPtr
->push_back(0);
126 typesPtr
->push_back(GL_LINE_LOOP
);
127 lensPtr
->push_back(4);
128 OSG::Real32 left
= static_cast<OSG::Real32
>(width
) * -0.5f
;
129 OSG::Real32 right
= static_cast<OSG::Real32
>(width
) * 0.5f
;
130 OSG::Real32 top
= static_cast<OSG::Real32
>(height
) * 0.5f
;
131 OSG::Real32 bottom
= static_cast<OSG::Real32
>(height
) * -0.5f
;
132 OSG::UInt32 posOffset
= posPtr
->size();
133 posPtr
->push_back(OSG::Vec3f(left
, bottom
, 0.f
));
134 posPtr
->push_back(OSG::Vec3f(right
, bottom
, 0.f
));
135 posPtr
->push_back(OSG::Vec3f(right
, top
, 0.f
));
136 posPtr
->push_back(OSG::Vec3f(left
, top
, 0.f
));
137 posIndicesPtr
->push_back(posOffset
);
138 colIndicesPtr
->push_back(1);
139 posIndicesPtr
->push_back(posOffset
+ 1);
140 colIndicesPtr
->push_back(1);
141 posIndicesPtr
->push_back(posOffset
+ 2);
142 colIndicesPtr
->push_back(1);
143 posIndicesPtr
->push_back(posOffset
+ 3);
144 colIndicesPtr
->push_back(1);
146 OSG::SimpleMaterialUnrecPtr matPtr
= OSG::SimpleMaterial::create();
147 geoPtr
->setMaterial(matPtr
);
149 OSG::NodeTransitPtr nodePtr
= OSG::Node::create();
150 nodePtr
->setCore(geoPtr
);
155 void updateFace(void)
157 // Try to create new face
158 if (family
.empty() == false)
160 OSG::TextTXFFaceRefPtr newFace
= OSG::TextTXFFace::create(family
, style
, param
);
168 // Update information on the screen
169 family
= face
->getFamily();
171 if(statfg
->getCollector() != NULL
)
173 statfg
->getCollector()->getElem(familyDesc
)->set(family
);
176 for (i
= 0; i
< filename
.size(); )
177 if (isalnum(filename
[i
]) == false)
178 filename
.erase(i
, 1);
181 style
= face
->getStyle();
182 OSG::StatStringElem
*statElem
= statfg
->getCollector()->getElem(styleDesc
);
185 case OSG::TextFace::STYLE_PLAIN
:
186 statElem
->set("Plain");
187 filename
.append("-Plain.txf");
189 case OSG::TextFace::STYLE_BOLD
:
190 statElem
->set("Bold");
191 filename
.append("-Bold.txf");
193 case OSG::TextFace::STYLE_ITALIC
:
194 statElem
->set("Italic");
195 filename
.append("-Italic.txf");
197 case OSG::TextFace::STYLE_BOLDITALIC
:
198 statElem
->set("Bold & Italic");
199 filename
.append("-BoldItalic.txf");
202 statfg
->getCollector()->getElem(sizeDesc
)->set(face
->getParam().size
);
203 statfg
->getCollector()->getElem(gapDesc
)->set(face
->getParam().gap
);
204 OSG::ImageUnrecPtr imagePtr
= face
->getTexture();
206 os
<< imagePtr
->getWidth() << 'x' << imagePtr
->getHeight();
207 statfg
->getCollector()->getElem(textureSizeDesc
)->set(os
.str());
210 glutSetMenu(mainMenuID
);
211 glutChangeToMenuEntry(6, (string("Write to ") + filename
).c_str(), COMMAND_WRITE_TO_FILE
);
214 void updateScene(void)
219 // Put it all together into a Geometry NodeCore.
220 OSG::ImageUnrecPtr imagePtr
= face
->getTexture();
221 OSG::GeometryUnrecPtr geo
= OSG::makePlaneGeo(imagePtr
->getWidth(), imagePtr
->getHeight(), 1, 1);
222 OSG::NodeUnrecPtr textNode
= OSG::Node::create();
223 textNode
->setCore(geo
);
224 OSG::NodeUnrecPtr transNodePtr
= OSG::Node::create();
225 OSG::TransformUnrecPtr transPtr
= OSG::Transform::create();
226 OSG::Matrix transMatrix
;
227 transMatrix
.setTranslate(0.f
, 0.f
, -1.f
);
228 transPtr
->setMatrix(transMatrix
);
229 transNodePtr
->setCore(transPtr
);
230 transNodePtr
->addChild(textNode
);
232 OSG::TextureObjChunkUnrecPtr texObjChunk
= OSG::TextureObjChunk::create();
233 texObjChunk
->setImage(imagePtr
);
234 texObjChunk
->setWrapS(GL_CLAMP
);
235 texObjChunk
->setWrapT(GL_CLAMP
);
236 texObjChunk
->setMagFilter(GL_NEAREST
);
237 texObjChunk
->setMinFilter(GL_NEAREST
);
238 OSG::TextureEnvChunkUnrecPtr texEnvChunk
= OSG::TextureEnvChunk::create();
239 texEnvChunk
->setEnvMode(GL_MODULATE
);
241 OSG::MaterialChunkUnrecPtr matChunk
= OSG::MaterialChunk::create();
242 matChunk
->setAmbient(OSG::Color4f(1.f
, 1.f
, 1.f
, 1.f
));
243 matChunk
->setDiffuse(OSG::Color4f(1.f
, 1.f
, 1.f
, 1.f
));
244 matChunk
->setEmission(OSG::Color4f(0.f
, 0.f
, 0.f
, 1.f
));
245 matChunk
->setSpecular(OSG::Color4f(0.f
, 0.f
, 0.f
, 1.f
));
246 matChunk
->setShininess(0);
248 OSG::BlendChunkUnrecPtr blendChunk
= OSG::BlendChunk::create();
249 blendChunk
->setSrcFactor(GL_SRC_ALPHA
);
250 blendChunk
->setDestFactor(GL_ONE_MINUS_SRC_ALPHA
);
252 OSG::ChunkMaterialUnrecPtr m
= OSG::ChunkMaterial::create();
253 m
->addChunk(texObjChunk
);
254 m
->addChunk(texEnvChunk
);
255 m
->addChunk(matChunk
);
256 m
->addChunk(blendChunk
);
260 scene
->clearChildren();
261 scene
->addChild(createMetrics(face
, imagePtr
->getWidth(), imagePtr
->getHeight()));
262 scene
->addChild(transNodePtr
);
265 // Initialize GLUT & OpenSG and set up the scene
266 int main(int argc
, char **argv
)
269 OSG::osgInit(argc
,argv
);
273 int winid
= setupGLUT(&argc
, argv
);
275 // the connection between GLUT and OpenSG
276 OSG::GLUTWindowUnrecPtr gwin
= OSG::GLUTWindow::create();
277 gwin
->setGlutId(winid
);
280 // put the geometry core into a node
281 scene
= OSG::Node::create();
282 OSG::GroupUnrecPtr groupPtr
= OSG::Group::create();
283 scene
->setCore(groupPtr
);
285 statfg
= OSG::SimpleStatisticsForeground::create();
287 statfg
->setColor(OSG::Color4f(0,1,0,0.9f
));
288 statfg
->addElement(familyDesc
, "Family: %s");
289 statfg
->addElement(styleDesc
, "Style: %s");
290 statfg
->addElement(sizeDesc
, "Size: %i");
291 statfg
->addElement(gapDesc
, "Gap: %i");
292 statfg
->addElement(textureSizeDesc
, "Texture Size: %s");
294 // Create the background
295 OSG::SolidBackgroundUnrecPtr bg
= OSG::SolidBackground::create();
296 bg
->setColor(OSG::Color3f(0.1f
, 0.1f
, 0.5f
));
300 face
= OSG::TextTXFFace::createFromFile(argv
[1]);
313 // create the SimpleSceneManager helper
314 mgr
= OSG::SimpleSceneManager::create();
316 // tell the manager what to manage
317 mgr
->setWindow(gwin
);
318 mgr
->setRoot (scene
);
320 // show the whole scene
323 // add the statistics forground
324 gwin
->getPort(0)->addForeground(statfg
);
325 gwin
->getPort(0)->setBackground(bg
);
335 // GLUT callback functions
344 // react to size changes
345 void reshape(int w
, int h
)
351 // react to mouse button presses
352 void mouse(int button
, int state
, int x
, int y
)
355 mgr
->mouseButtonRelease(button
, x
, y
);
357 mgr
->mouseButtonPress(button
, x
, y
);
362 // react to mouse motions with pressed buttons
363 void motion(int x
, int y
)
365 mgr
->mouseMove(x
, y
);
370 void keyboard(unsigned char k
, int x
, int y
)
388 void menu(int command
)
392 case COMMAND_FAMILY_SANS
:
396 case COMMAND_FAMILY_SERIF
:
400 case COMMAND_FAMILY_TYPEWRITER
:
401 family
= "TYPEWRITER";
404 case COMMAND_STYLE_PLAIN
:
405 style
= OSG::TextFace::STYLE_PLAIN
;
408 case COMMAND_STYLE_BOLD
:
409 style
= OSG::TextFace::STYLE_BOLD
;
412 case COMMAND_STYLE_ITALIC
:
413 style
= OSG::TextFace::STYLE_ITALIC
;
416 case COMMAND_STYLE_BOLDITALIC
:
417 style
= OSG::TextFace::STYLE_BOLDITALIC
;
420 case COMMAND_SIZE_INC1
:
424 case COMMAND_SIZE_INC10
:
428 case COMMAND_SIZE_DEC1
:
435 case COMMAND_SIZE_DEC10
:
436 if (param
.size
<= 11)
442 case COMMAND_GAP_INC1
:
446 case COMMAND_GAP_DEC1
:
453 case COMMAND_TEXTUREWIDTH_AUTO
:
454 param
.textureWidth
= 0;
457 case COMMAND_TEXTUREWIDTH_64
:
458 param
.textureWidth
= 64;
461 case COMMAND_TEXTUREWIDTH_128
:
462 param
.textureWidth
= 128;
465 case COMMAND_TEXTUREWIDTH_256
:
466 param
.textureWidth
= 256;
469 case COMMAND_TEXTUREWIDTH_512
:
470 param
.textureWidth
= 512;
473 case COMMAND_TEXTUREWIDTH_1024
:
474 param
.textureWidth
= 1024;
477 case COMMAND_TEXTUREWIDTH_2048
:
478 param
.textureWidth
= 2048;
481 case COMMAND_TEXTUREWIDTH_4096
:
482 param
.textureWidth
= 4096;
485 case COMMAND_WRITE_TO_FILE
:
486 face
->writeToFile(filename
);
489 if (command
< COMMAND_FAMILY_BASE
)
491 family
= families
[command
- COMMAND_FAMILY_BASE
];
499 // setup the GLUT library which handles the windows for us
500 int setupGLUT(int *argc
, char *argv
[])
502 glutInit(argc
, argv
);
503 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
505 int winid
= glutCreateWindow("OpenSG");
507 glutReshapeFunc(reshape
);
508 glutDisplayFunc(display
);
509 glutMouseFunc(mouse
);
510 glutMotionFunc(motion
);
511 glutKeyboardFunc(keyboard
);
513 int familyMenuID
= glutCreateMenu(menu
);
514 glutSetMenu(familyMenuID
);
515 glutAddMenuEntry("SANS", COMMAND_FAMILY_SANS
);
516 glutAddMenuEntry("SERIF", COMMAND_FAMILY_SERIF
);
517 glutAddMenuEntry("TYPEWRITER", COMMAND_FAMILY_TYPEWRITER
);
518 OSG::TextFaceFactory::the()->getFontFamilies(families
);
520 for (i
= 0; i
< families
.size(); ++i
)
521 glutAddMenuEntry(families
[i
].c_str(), COMMAND_FAMILY_BASE
+ i
);
522 int styleMenuID
= glutCreateMenu(menu
);
523 glutSetMenu(styleMenuID
);
524 glutAddMenuEntry("Plain", COMMAND_STYLE_PLAIN
);
525 glutAddMenuEntry("Bold", COMMAND_STYLE_BOLD
);
526 glutAddMenuEntry("Italic", COMMAND_STYLE_ITALIC
);
527 glutAddMenuEntry("Bold + Italic", COMMAND_STYLE_BOLDITALIC
);
528 int sizeMenuID
= glutCreateMenu(menu
);
529 glutSetMenu(sizeMenuID
);
530 glutAddMenuEntry("Increment size by 1", COMMAND_SIZE_INC1
);
531 glutAddMenuEntry("Increment size by 10", COMMAND_SIZE_INC10
);
532 glutAddMenuEntry("Decrement size by 1", COMMAND_SIZE_DEC1
);
533 glutAddMenuEntry("Decrement size by 10", COMMAND_SIZE_DEC10
);
534 int gapMenuID
= glutCreateMenu(menu
);
535 glutSetMenu(gapMenuID
);
536 glutAddMenuEntry("Increment gap by 1", COMMAND_GAP_INC1
);
537 glutAddMenuEntry("Decrement gap by 1", COMMAND_GAP_DEC1
);
538 int textureWidthMenuID
= glutCreateMenu(menu
);
539 glutSetMenu(textureWidthMenuID
);
540 glutAddMenuEntry("Automatic", COMMAND_TEXTUREWIDTH_AUTO
);
541 glutAddMenuEntry("64", COMMAND_TEXTUREWIDTH_64
);
542 glutAddMenuEntry("128", COMMAND_TEXTUREWIDTH_128
);
543 glutAddMenuEntry("256", COMMAND_TEXTUREWIDTH_256
);
544 glutAddMenuEntry("512", COMMAND_TEXTUREWIDTH_512
);
545 glutAddMenuEntry("1024", COMMAND_TEXTUREWIDTH_1024
);
546 glutAddMenuEntry("2048", COMMAND_TEXTUREWIDTH_2048
);
547 glutAddMenuEntry("4096", COMMAND_TEXTUREWIDTH_4096
);
548 mainMenuID
= glutCreateMenu(menu
);
549 glutSetMenu(mainMenuID
);
550 glutAddSubMenu("Family", familyMenuID
);
551 glutAddSubMenu("Style", styleMenuID
);
552 glutAddSubMenu("Size", sizeMenuID
);
553 glutAddSubMenu("Gap", gapMenuID
);
554 glutAddSubMenu("TextureWidth", textureWidthMenuID
);
555 glutAddMenuEntry("Write to ", COMMAND_WRITE_TO_FILE
);
556 glutAttachMenu(GLUT_RIGHT_BUTTON
);