fixed: let the material fill the override chunk block
[opensg.git] / Source / System / Text / testTextTXFTexture.cpp
blob842d5c8565f0c17df6f1cd2d51db02e7f493db24
1 #include "OSGGLUT.h"
2 #include "OSGConfig.h"
3 #include "OSGSimpleGeometry.h"
4 #include "OSGGLUTWindow.h"
5 #include "OSGSimpleSceneManager.h"
6 #include "OSGBaseFunctions.h"
7 #include "OSGTransform.h"
8 #include "OSGGroup.h"
9 #include "OSGSimpleStatisticsForeground.h"
10 #include "OSGSolidBackground.h"
11 #include "OSGImage.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"
22 #include <sstream>
24 // Activate the OpenSG namespace
25 using namespace std;
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;
64 string family;
65 vector<string> families;
66 OSG::TextFace::Style style = OSG::TextFace::STYLE_PLAIN;
67 OSG::TextTXFParam param;
68 string filename;
70 int mainMenuID;
72 // forward declaration so we can have the interesting stuff upfront
73 int setupGLUT( int *argc, char *argv[] );
75 // Create the metrics
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);
125 // Bounding box
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);
152 return nodePtr;
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);
161 if (newFace == 0)
162 return;
163 face = newFace;
165 if (face == 0)
166 return;
168 // Update information on the screen
169 family = face->getFamily();
171 if(statfg->getCollector() != NULL)
173 statfg->getCollector()->getElem(familyDesc)->set(family);
174 filename = family;
175 string::size_type i;
176 for (i = 0; i < filename.size(); )
177 if (isalnum(filename[i]) == false)
178 filename.erase(i, 1);
179 else
180 ++i;
181 style = face->getStyle();
182 OSG::StatStringElem *statElem = statfg->getCollector()->getElem(styleDesc);
183 switch (style)
185 case OSG::TextFace::STYLE_PLAIN:
186 statElem->set("Plain");
187 filename.append("-Plain.txf");
188 break;
189 case OSG::TextFace::STYLE_BOLD:
190 statElem->set("Bold");
191 filename.append("-Bold.txf");
192 break;
193 case OSG::TextFace::STYLE_ITALIC:
194 statElem->set("Italic");
195 filename.append("-Italic.txf");
196 break;
197 case OSG::TextFace::STYLE_BOLDITALIC:
198 statElem->set("Bold & Italic");
199 filename.append("-BoldItalic.txf");
200 break;
202 statfg->getCollector()->getElem(sizeDesc)->set(face->getParam().size);
203 statfg->getCollector()->getElem(gapDesc)->set(face->getParam().gap);
204 OSG::ImageUnrecPtr imagePtr = face->getTexture();
205 ostringstream os;
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)
216 if(face == NULL)
217 return;
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);
258 geo->setMaterial(m);
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)
268 // OSG init
269 OSG::osgInit(argc,argv);
272 // GLUT init
273 int winid = setupGLUT(&argc, argv);
275 // the connection between GLUT and OpenSG
276 OSG::GLUTWindowUnrecPtr gwin= OSG::GLUTWindow::create();
277 gwin->setGlutId(winid);
278 gwin->init();
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();
286 statfg->setSize(25);
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));
298 if (argc > 1)
300 face = OSG::TextTXFFace::createFromFile(argv[1]);
301 if (face == 0)
302 family = "SANS";
303 else
305 family.erase();
308 else
309 family = "SANS";
310 updateFace();
311 updateScene();
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
321 mgr->showAll();
323 // add the statistics forground
324 gwin->getPort(0)->addForeground(statfg);
325 gwin->getPort(0)->setBackground(bg);
328 // GLUT main loop
329 glutMainLoop();
331 return 0;
335 // GLUT callback functions
338 // redraw the window
339 void display( void )
341 mgr->redraw();
344 // react to size changes
345 void reshape(int w, int h)
347 mgr->resize(w, h);
348 glutPostRedisplay();
351 // react to mouse button presses
352 void mouse(int button, int state, int x, int y)
354 if (state)
355 mgr->mouseButtonRelease(button, x, y);
356 else
357 mgr->mouseButtonPress(button, x, y);
359 glutPostRedisplay();
362 // react to mouse motions with pressed buttons
363 void motion(int x, int y)
365 mgr->mouseMove(x, y);
366 glutPostRedisplay();
369 // react to keys
370 void keyboard(unsigned char k, int x, int y)
372 switch(k)
374 case 27:
376 mgr = NULL;
377 face = NULL;
378 scene = NULL;
379 statfg = NULL;
381 OSG::osgExit();
382 exit(0);
384 break;
388 void menu(int command)
390 switch (command)
392 case COMMAND_FAMILY_SANS:
393 family = "SANS";
394 updateFace();
395 break;
396 case COMMAND_FAMILY_SERIF:
397 family = "SERIF";
398 updateFace();
399 break;
400 case COMMAND_FAMILY_TYPEWRITER:
401 family = "TYPEWRITER";
402 updateFace();
403 break;
404 case COMMAND_STYLE_PLAIN:
405 style = OSG::TextFace::STYLE_PLAIN;
406 updateFace();
407 break;
408 case COMMAND_STYLE_BOLD:
409 style = OSG::TextFace::STYLE_BOLD;
410 updateFace();
411 break;
412 case COMMAND_STYLE_ITALIC:
413 style = OSG::TextFace::STYLE_ITALIC;
414 updateFace();
415 break;
416 case COMMAND_STYLE_BOLDITALIC:
417 style = OSG::TextFace::STYLE_BOLDITALIC;
418 updateFace();
419 break;
420 case COMMAND_SIZE_INC1:
421 param.size += 1;
422 updateFace();
423 break;
424 case COMMAND_SIZE_INC10:
425 param.size += 10;
426 updateFace();
427 break;
428 case COMMAND_SIZE_DEC1:
429 if (param.size <= 1)
430 param.size = 1;
431 else
432 param.size -= 1;
433 updateFace();
434 break;
435 case COMMAND_SIZE_DEC10:
436 if (param.size <= 11)
437 param.size = 1;
438 else
439 param.size -= 10;
440 updateFace();
441 break;
442 case COMMAND_GAP_INC1:
443 param.gap += 1;
444 updateFace();
445 break;
446 case COMMAND_GAP_DEC1:
447 if (param.gap <= 0)
448 param.gap = 0;
449 else
450 param.gap -= 1;
451 updateFace();
452 break;
453 case COMMAND_TEXTUREWIDTH_AUTO:
454 param.textureWidth = 0;
455 updateFace();
456 break;
457 case COMMAND_TEXTUREWIDTH_64:
458 param.textureWidth = 64;
459 updateFace();
460 break;
461 case COMMAND_TEXTUREWIDTH_128:
462 param.textureWidth = 128;
463 updateFace();
464 break;
465 case COMMAND_TEXTUREWIDTH_256:
466 param.textureWidth = 256;
467 updateFace();
468 break;
469 case COMMAND_TEXTUREWIDTH_512:
470 param.textureWidth = 512;
471 updateFace();
472 break;
473 case COMMAND_TEXTUREWIDTH_1024:
474 param.textureWidth = 1024;
475 updateFace();
476 break;
477 case COMMAND_TEXTUREWIDTH_2048:
478 param.textureWidth = 2048;
479 updateFace();
480 break;
481 case COMMAND_TEXTUREWIDTH_4096:
482 param.textureWidth = 4096;
483 updateFace();
484 break;
485 case COMMAND_WRITE_TO_FILE:
486 face->writeToFile(filename);
487 break;
488 default:
489 if (command < COMMAND_FAMILY_BASE)
490 return;
491 family = families[command - COMMAND_FAMILY_BASE];
492 updateFace();
494 updateScene();
495 mgr->showAll();
496 glutPostRedisplay();
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);
519 OSG::UInt32 i;
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);
558 return winid;