1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
38 //---------------------------------------------------------------------------
40 //---------------------------------------------------------------------------
44 #include "OSGConfig.h"
48 #include "OSGViewport.h"
50 #include "OSGSimpleStatisticsForeground.h"
51 #include "OSGDefaultFont.h"
53 #include "OSGTextLayoutParam.h"
54 #include "OSGTextLayoutResult.h"
55 #include "OSGTextTXFGlyph.h"
59 // Documentation for this class is emited in the
60 // OSGSimpleStatisticsForegroundBase.cpp file.
61 // To modify it, please change the .fcd file (OSGSimpleStatisticsForeground.fcd) and
62 // regenerate the base file.
64 /*----------------------- constructors & destructors ----------------------*/
66 SimpleStatisticsForeground::SimpleStatisticsForeground(void) :
68 HorizontalAlignE(Left
),
69 VerticalAlignE (Top
),
74 _texenvchunk
= TextureEnvChunk::createLocal();
75 _texenvchunk
->setEnvMode(GL_MODULATE
);
79 SimpleStatisticsForeground::SimpleStatisticsForeground(
80 const SimpleStatisticsForeground
&source
) :
83 HorizontalAlignE(source
.HorizontalAlignE
),
84 VerticalAlignE (source
.VerticalAlignE
),
85 _face (source
._face
),
86 _texchunk (source
._texchunk
),
87 _texenvchunk (source
._texenvchunk
)
92 SimpleStatisticsForeground::~SimpleStatisticsForeground(void)
96 void SimpleStatisticsForeground::resolveLinks(void)
98 Inherited::resolveLinks();
106 /*----------------------------- class specific ----------------------------*/
108 void SimpleStatisticsForeground::initMethod(InitPhase ePhase
)
110 Inherited::initMethod(ePhase
);
114 void SimpleStatisticsForeground::changed(ConstFieldMaskArg whichField
,
118 Inherited::changed(whichField
, origin
, details
);
122 void SimpleStatisticsForeground::dump(UInt32
, const BitVector
) const
124 SLOG
<< "Dump SimpleStatisticsForeground NI" << std::endl
;
127 /*! Convenience function to add an element and format.
129 void SimpleStatisticsForeground::addElement(StatElemDescBase
&desc
,
132 editMFElementIDs()->push_back(desc
.getID());
133 editMFFormats ()->push_back(format
? format
: "");
136 /*! Convenience function to add an element and format.
138 void SimpleStatisticsForeground::addElement(Int32 id
, const char *format
)
140 editMFElementIDs()->push_back(id
);
141 editMFFormats ()->push_back(format
? format
: "");
144 /*! Convenience function to add a line of text.
146 void SimpleStatisticsForeground::addText(const char *text
)
148 addElement( -1, text
);
151 /*! Convenience function to clear all elements.
153 void SimpleStatisticsForeground::clearElems(void)
155 editMFElementIDs()->clear();
156 editMFFormats ()->clear();
158 if(getCollector() != NULL
)
160 getCollector()->clearElems();
164 /*! Initialize the text used. It is compiled into the library as
165 StatisticsDefaultFontData and used as a TXF font.
167 void SimpleStatisticsForeground::initText(const std::string
&family
,
175 if (family
.empty() == false)
178 param
.size
= static_cast<UInt32
>(size
);
179 _face
= TextTXFFace::create(family
, TextFace::STYLE_PLAIN
, param
);
182 _texchunk
= TextureObjChunk::createLocal();
183 ImageUnrecPtr texture
= _face
->getTexture();
184 _texchunk
->setImage(texture
);
185 _texchunk
->setWrapS(GL_CLAMP
);
186 _texchunk
->setWrapT(GL_CLAMP
);
187 _texchunk
->setMinFilter(GL_NEAREST
);
188 _texchunk
->setMagFilter(GL_NEAREST
);
192 // We failed to create the font - fallback to the default font
195 _face
= DefaultFont::the()->getFace();
196 _texchunk
= DefaultFont::the()->getTexture();
200 /*! Draw the statistics lines.
202 void SimpleStatisticsForeground::draw(DrawEnv
*pEnv
)
204 if(getActive() == false)
208 initText(getFamily(), getSize());
210 if ((getCollector() == NULL
) ||
211 (!getCollector()->getNumOfElems() &&
212 !getMFElementIDs()->size()))
213 return; // nothing to do
215 Real32 pw
= Real32(pEnv
->getPixelWidth ());
216 Real32 ph
= Real32(pEnv
->getPixelHeight());
221 glPushAttrib(GL_LIGHTING_BIT
| GL_POLYGON_BIT
| GL_DEPTH_BUFFER_BIT
| GL_COLOR_BUFFER_BIT
);
223 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
224 glDisable(GL_DEPTH_TEST
);
225 glDisable(GL_COLOR_MATERIAL
);
226 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
229 glMatrixMode(GL_MODELVIEW
);
233 glMatrixMode(GL_PROJECTION
);
237 // Set viewport. We want to map one unit to one pixel on the
238 // screen. Some sources in the internet say that we should
239 // add an offset of -0.375 to prevent rounding errors. Don't
240 // know if that is true, but it seems to work.
241 glOrtho(0 - 0.375, pw
- 0.375, 0 - 0.375, ph
- 0.375, 0, 1);
244 std::vector
< std::string
> stat
;
246 StatCollector
*col
= this->getCollector();
249 if(getMFElementIDs()->size() != 0)
251 for(UInt32 i
= 0; i
< getMFElementIDs()->size(); ++i
)
253 Int32
id(getElementIDs(i
));
254 el
= ((id
>= 0) ? col
->getElem(id
) : 0);
256 stat
.resize(stat
.size() + 1);
257 std::vector
< std::string
>::iterator str
= stat
.end() - 1;
259 const char *format
= NULL
;
260 if(i
< getMFFormats()->size() && getFormats(i
).length())
262 format
= getFormats(i
).c_str();
266 el
->putToString(*str
, format
);
271 else // fallback, show all elements
273 for(UInt32 i
= 0; i
< col
->getNumOfElems(); ++i
)
275 el
= col
->getElem(i
, false);
278 std::string
desc(el
->getDesc()->getName()), eltext
;
280 el
->putToString(eltext
);
281 desc
= desc
+ " : " + eltext
;
283 stat
.resize(stat
.size() + 1);
284 std::vector
< std::string
>::iterator str
= stat
.end() - 1;
291 for(size_t i
= 0; i
< stat
.size(); ++i
)
293 fprintf(stderr
, "s[%d] : %s\n",
299 TextLayoutParam layoutParam
;
300 layoutParam
.spacing
= 1.1f
;
301 layoutParam
.majorAlignment
= TextLayoutParam::ALIGN_BEGIN
;
302 layoutParam
.minorAlignment
= TextLayoutParam::ALIGN_BEGIN
;
304 TextLayoutResult layoutResult
;
305 _face
->layout(stat
, layoutParam
, layoutResult
);
307 Real32 scale
= 1 / _face
->getScale();
308 Real32 size
= _face
->getParam().size
;
309 Real32 textWidth
= layoutResult
.textBounds
.x() * scale
+ size
+ getTextMargin().x() * 2.0f
;
310 Real32 textHeight
= layoutResult
.textBounds
.y() * scale
+ size
+ getTextMargin().y() * 2.0f
;
312 // Let's do some simple form of layout management
313 Real32 orthoX
= 0, orthoY
= ph
;
315 switch ( getHorizontalAlign() )
318 orthoX
= pw
- textWidth
;
321 orthoX
= (pw
- textWidth
) * 0.5;
328 switch ( getVerticalAlign() )
334 orthoY
= (ph
- textHeight
) * 0.5 + textHeight
;
341 glTranslatef(orthoX
, orthoY
, 0.0);
344 glColor4fv(static_cast<const GLfloat
*>(getBgColor().getValuesRGBA()));
346 glVertex2f(0, -textHeight
);
347 glVertex2f(textWidth
, -textHeight
);
348 glVertex2f(textWidth
, 0);
353 if(getBorderColor().alpha() >= 0.0f
)
356 static_cast<const GLfloat
*>(getBorderColor().getValuesRGBA()));
358 glBegin(GL_LINE_LOOP
);
359 glVertex2f(getBorderOffset().x(),
360 -textHeight
+ 1 + getBorderOffset().y());
361 glVertex2f(textWidth
- 1 - getBorderOffset().x(),
362 -textHeight
+ 1 + getBorderOffset().y());
363 glVertex2f(textWidth
- 1 - getBorderOffset().x(),
364 -1 - getBorderOffset().y());
365 glVertex2f(getBorderOffset().x(), -1 - getBorderOffset().y());
369 glTranslatef( 0.5 * size
+ getTextMargin().x(),
370 -0.5 * size
- getTextMargin().y(),
373 _texchunk
->activate(pEnv
);
374 _texenvchunk
->activate(pEnv
);
377 glColor4fv(static_cast<const GLfloat
*>(getShadowColor().getValuesRGBA()));
379 glTranslatef(getShadowOffset().x(), getShadowOffset().y(), 0);
380 glScalef(scale
, scale
, 1);
381 _face
->drawCharacters(layoutResult
);
384 glColor4fv(static_cast<const GLfloat
*>(getColor().getValuesRGBA()));
386 glScalef(scale
, scale
, 1);
387 _face
->drawCharacters(layoutResult
);
389 _texchunk
->deactivate(pEnv
);
390 _texenvchunk
->deactivate(pEnv
);
392 glMatrixMode(GL_PROJECTION
);
395 glMatrixMode(GL_MODELVIEW
);