Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGGraphicStatisticsForeground.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 //---------------------------------------------------------------------------
00039 //  Includes
00040 //---------------------------------------------------------------------------
00041 #include <OSGConfig.h>
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <iostream>
00046 
00047 #ifdef OSG_HAS_SSTREAM
00048 #include <sstream>
00049 #else
00050 #include <strstream>
00051 #endif
00052 
00053 #include <OSGImage.h>
00054 
00055 #include <OSGTextTXFFace.h>
00056 #include <OSGTextTXFGlyph.h>
00057 #include <OSGTextLayoutResult.h>
00058 
00059 #include <OSGNodePtr.h>
00060 #include <OSGViewport.h>
00061 #include "OSGGraphicStatisticsFont.h"
00062 
00063 #include "OSGStatElem.h"
00064 #include "OSGGraphicStatisticsForeground.h"
00065 #include "OSGGL.h"
00066 
00067 //#include "GL/glut.h"
00068 OSG_USING_NAMESPACE
00069 
00070 /* static vars */
00071 TextTXFFace *GraphicStatisticsForeground::      _face = 0;
00072 TextureChunkPtr GraphicStatisticsForeground::   _texchunk;
00073 
00089 /*----------------------- constructors & destructors ----------------------*/
00090 GraphicStatisticsForeground::GraphicStatisticsForeground(void) :
00091     Inherited()
00092 {
00093 }
00094 
00095 /* */
00096 GraphicStatisticsForeground::GraphicStatisticsForeground(const GraphicStatisticsForeground &source) :
00097         Inherited(source)
00098 {
00099 }
00100 
00101 /* */
00102 GraphicStatisticsForeground::~GraphicStatisticsForeground(void)
00103 {
00104 }
00105 
00106 /*----------------------------- class specific ----------------------------*/
00107 void GraphicStatisticsForeground::initMethod(void)
00108 {
00109 }
00110 
00111 /* */
00112 void GraphicStatisticsForeground::changed(BitVector whichField, UInt32)
00113 {
00114     UInt32  i, n = getHistorySize().size();
00115 
00116     /* Save the data  */
00117     if(whichField & HistorySizeFieldMask)
00118     {
00119         _historyID.resize(n, 0);
00120         _history.resize(n);
00121         for(i = 0; i < n; i++)
00122         {
00123             if(_history[i].size() == 0)
00124             {
00125                 _history[i].resize(getHistorySize()[i],
00126                                                    (getMaxValue()[i] - getMinValue()[i]) / 2.0f);
00127             }
00128         }
00129     }
00130 }
00131 
00132 /* */
00133 void GraphicStatisticsForeground::dump(UInt32, const BitVector) const
00134 {
00135     SLOG << "Dump GraphicStatisticsForeground NI" << std::endl;
00136 }
00137 
00139 void GraphicStatisticsForeground::draw(DrawActionBase *action, Viewport *port)
00140 {
00141     // Check the height and width of the window
00142     if(port->getPixelWidth() < 1 || port->getPixelHeight() < 1)
00143     {
00144         return;
00145     }
00146 
00147     // initialize the text texture
00148     if(_face == 0)
00149     {
00150         initText();
00151     }
00152 
00153     // Save the current OpenGL state
00154     // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
00155     glPushAttrib(GL_ALL_ATTRIB_BITS);
00156 
00157     glMatrixMode(GL_MODELVIEW);
00158     glPushMatrix();
00159     glLoadIdentity();
00160 
00161     glMatrixMode(GL_PROJECTION);
00162     glPushMatrix();
00163     glLoadIdentity();
00164 
00165     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
00166     // Finished saving and setting the matrices
00167     // Enable Alpha Blending
00168     glAlphaFunc(GL_NOTEQUAL, 0);
00169     glEnable(GL_ALPHA_TEST);
00170     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00171     glEnable(GL_BLEND);
00172 
00173     // Enable the scissor test
00174     glEnable(GL_SCISSOR_TEST);
00175 
00176     // Initialize the viewport
00177     glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
00178 
00179     // set the standard line Width
00180     glLineWidth(getLineWidth());
00181 
00182     // Get the Collector
00183     StatCollector   *col = &getCollector();
00184 
00185     // temp StatElem
00186     StatElem        *el;
00187 
00188     // ratio = height / width
00189     //    Real32 ratio  =  ( (Real32)port->getPixelHeight()) /
00190     //                     ((Real32) port->getPixelWidth());
00191     // temp Variables for the loop
00192     Vec2f           pos;
00193     Vec2f           size;
00194 
00195     // Loop over all selected elements
00196     for(UInt32 i = 0; i < getElementIDs().size(); ++i)
00197     {
00198         // get the StatElem and check whether it exists
00199         el = col->getElem(getElementIDs()[i]);
00200         if(!el)
00201         {
00202             continue;
00203         }
00204 
00205         glMatrixMode(GL_MODELVIEW);
00206         glPushMatrix();
00207 
00208         // calculate position and size
00209         calcPosAndSize(i, port, &pos, &size);
00210         glTranslatef(pos[0], pos[1], 0.0);
00211         glScalef(size[0], size[1], 1.0);
00212 
00213         // calculate the pixel size of the display
00214         UInt32  pw = (UInt32) (port->getPixelWidth() * size[0]);
00215         UInt32  ph = (UInt32) (port->getPixelHeight() * size[1]);
00216         UInt32  px = (UInt32) (port->getPixelWidth() * pos[0]);
00217         UInt32  py = (UInt32) (port->getPixelHeight() * pos[1]);
00218         glScissor(px - 1, py - 1, pw + 2, ph + 2);
00219 
00220         //std::cout << pos << std::endl;
00221         //std::cout << size << std::endl;
00222         //std::cout << px << "/" << py << "/" << pw << "/" << ph
00223         //          << std::endl;
00224         // enable GL_POINT_SMOOTH
00225         glEnable(GL_POINT_SMOOTH);
00226 
00227         //select the Method to use for drawing
00228         switch(getDisplayType()[i])
00229         {
00230         case OSG_ANALOG:
00231             //draw an analog display
00232             drawAnalog(i, el, action, port);
00233             break;
00234         case OSG_BAR:
00235             //draw a bar display
00236             drawBar(i, el, action, port);
00237             break;
00238         case OSG_CHART:
00239             //draw a chart
00240             drawChart(i, el, action, port);
00241             break;
00242         case OSG_LINE_CHART:
00243             //draw a linechart
00244             drawLineChart(i, el, action, port);
00245             break;
00246         case OSG_TEXT:
00247             //draw a linechart
00248             drawText(i, el, action, port);
00249             break;
00250 
00251         default:
00252             break;
00253         }                                   //switch()
00254 
00255         glMatrixMode(GL_MODELVIEW);
00256         glPopMatrix();
00257     }                                       //for()
00258 
00259     //reset OpenGL matrices
00260     glMatrixMode(GL_PROJECTION);
00261     glPopMatrix();
00262     glMatrixMode(GL_MODELVIEW);
00263     glPopMatrix();
00264 
00265     // Restore all OpenGL states
00266     glPopAttrib();
00267 }
00268 
00269 //draw();
00270 
00271 /* */
00272 void GraphicStatisticsForeground::addElement(StatElemDescBase &desc,
00273                                              UInt32 displayType, Vec2f pos,
00274                                              Vec2f size, Color4f highColor,
00275                                              Color4f lowColor,
00276                                              Color4f currentColor,
00277                                              Real32 minValue, Real32 maxValue,
00278                                              UInt32 flags, UInt32 historySize,
00279                                              std::string description)
00280 {
00281     /* get the ID of the StatElem to be added */
00282     // Save the given Data
00283     getElementIDs().push_back(desc.getID());
00284     getDisplayType().push_back(displayType);
00285     getPos().push_back(pos);
00286     getSize().push_back(size);
00287     getColorMax().push_back(highColor);
00288     getColorMin().push_back(lowColor);
00289     getColorCurrent().push_back(currentColor);
00290     getMinValue().push_back(minValue);
00291     getMaxValue().push_back(maxValue);
00292     getFlags().push_back(flags);
00293     getHistorySize().push_back(historySize ? historySize : 25);
00294     getDescription().push_back(description);
00295 
00296     // changed() must be called (automatically)
00297     // to sync the _history/_historyID values
00298 }
00299 
00300 //addElement()
00301 
00302 /*******************************************************/
00303 void GraphicStatisticsForeground::removeElement(StatElemDescBase &desc)
00304 {
00305     UInt32  id = desc.getID();
00306     UInt32  i = 0, n = getElementIDs().size();
00307 
00308     for(i = 0; n; i++)
00309     {
00310         if(getElementIDs()[i] == id)
00311             break;
00312     }
00313 
00314     /* Now i is the id of the Element in the MFields. */
00315     if(i != n)
00316     {
00317         /* Erase these entries in the MFields */
00318         getElementIDs().erase(getElementIDs().begin() + i);
00319         getDisplayType().erase(getDisplayType().begin() + i);
00320         getPos().erase(getPos().begin() + i);
00321         getSize().erase(getSize().begin() + i);
00322         getColorMax().erase(getColorMax().begin() + i);
00323         getColorMin().erase(getColorMin().begin() + i);
00324         getColorCurrent().erase(getColorCurrent().begin() + i);
00325         getMinValue().erase(getMinValue().begin() + i);
00326         getMaxValue().erase(getMaxValue().begin() + i);
00327         getFlags().erase(getFlags().begin() + i);
00328         getHistorySize().erase(getHistorySize().begin() + i);
00329 
00330         _history.erase(_history.begin() + i);
00331         _historyID.erase(_historyID.begin() + i);
00332     }
00333 }
00334 
00335 /*******************************************************/
00336 void GraphicStatisticsForeground::drawAnalog(UInt32 elementID, StatElem *el,
00337                                              DrawActionBase *base, Viewport *)
00338 {
00339     // helper Var
00340     Real32  xdist = 0.0;
00341 
00342     // get the current value to be digitised
00343     Real32  value = Real32(el->getValue());
00344     Real32  vsave = value;
00345 
00346     //std::cout << "Analog value: " << value << std::endl;
00347     // process this value according to the flags
00348     processValue(value, elementID);
00349     processOnlyValue(vsave, elementID);
00350 
00351     // calculate minimum value and maximun value
00352     Real32  minV = getMinValue()[elementID];
00353     Real32  maxV = getMaxValue()[elementID];
00354 
00355     // get the colors
00356     Color4f minColor = getColorMin()[elementID];
00357     Color4f currentColor = getColorCurrent()[elementID];
00358     Color4f maxColor = getColorMax()[elementID];
00359 
00360     // xdist helps to calculate the real size[0] of the quadstrip and the colors
00361     xdist = (value - minV) / (maxV - minV);
00362 
00363     // draw a filled circle  with alpha value if expected
00364     Color3f c = getBackgroundColor();
00365     Real32  angle = 0.0;
00366     if(getBackgroundEnabled())
00367     {
00368         // filled circle drawn with a triangle_strip
00369         glMatrixMode(GL_MODELVIEW);
00370         glPushMatrix();
00371         glTranslatef(0.5, 0.5, 0);
00372         glColor4f(c[0], c[1], c[2], 0.4);
00373         glBegin(GL_POLYGON);
00374 
00375         // glVertex2f(0.0, 0.0);
00376         for(angle = 0.0; angle < 2 * Pi; angle += Pi / 24)
00377         {
00378             glVertex2f(0.5f * cos(angle), 0.5f * sin(angle));
00379         }
00380 
00381         glEnd();
00382         glMatrixMode(GL_MODELVIEW);
00383         glPopMatrix();
00384     }
00385 
00386     // draw a Frame around the display
00387     if(getBorderEnabled())
00388     {
00389         glColor4f(c[0], c[1], c[2], 0.8);
00390 
00391         // non filled circle around the filled one
00392         angle = 0.0;
00393         glMatrixMode(GL_MODELVIEW);
00394         glPushMatrix();
00395         glTranslatef(0.5, 0.5, 0);
00396         glBegin(GL_LINE_LOOP);
00397 
00398         for(angle = 0.0; angle < 2 * Pi; angle += Pi / 24)
00399         {
00400             glVertex2f(0.5f * cos(angle), 0.5f * sin(angle));
00401         }
00402 
00403         glEnd();
00404         glMatrixMode(GL_MODELVIEW);
00405         glPopMatrix();
00406     }
00407 
00408     // draw the ticks
00409     glColor3f(1.0f - c[0], 1.0f - c[1], 1.0f - c[2]);
00410     glMatrixMode(GL_MODELVIEW);
00411     glPushMatrix();
00412     glTranslatef(0.5, 0.5, 0.0);
00413     glRotatef(135, 0.0, 0.0, 1.0);
00414 
00415     glColor3f(1.0f - c[0], 1.0f - c[1], 1.0f - c[2]);
00416     for(UInt32 r = 0; r < 10; r++)
00417     {
00418         glBegin(GL_LINES);
00419         glVertex2f(-0.5, 0.0);
00420         glVertex2f(-0.35, 0.0);
00421         glEnd();
00422         glRotatef(30, 0.0, 0.0, 1.0);
00423     }                                       // end for
00424 
00425     glMatrixMode(GL_MODELVIEW);
00426     glPopMatrix();
00427 
00428     // save current matrix, translate to the origin of the pointer and rotate
00429     glMatrixMode(GL_MODELVIEW);
00430     glPushMatrix();
00431     glTranslatef(0.5, 0.5, 0);
00432     glRotatef(45 - (xdist * 270.0f), 0.0, 0.0, 1.0);
00433 
00434     // draw arrow
00435     glColor3f(0.0, 1.0, 0.0);
00436     glBegin(GL_TRIANGLES);
00437     glVertex2f(0.0, 0.0);
00438     glVertex2f(-0.5, 0.0);
00439     glVertex2f(-0.4, 0.05);
00440 
00441     // next triangle -----
00442     glVertex2f(0.0, 0.0);
00443     glVertex2f(-0.5, 0.0);
00444     glVertex2f(-0.4, -0.05);
00445     glEnd();
00446 
00447     // and finally go back
00448     glMatrixMode(GL_MODELVIEW);
00449     glPopMatrix();
00450 
00451     //draw the center of the arrow...
00452     glMatrixMode(GL_MODELVIEW);
00453     glPushMatrix();
00454     glColor3f(1.0f - c[0], 1.0f - c[1], 1.0f - c[2]);
00455     glBegin(GL_QUADS);
00456     glVertex2f(0.475, 0.475);
00457     glVertex2f(0.525, 0.475);
00458     glVertex2f(0.525, 0.525);
00459     glVertex2f(0.475, 0.525);
00460 
00461     glEnd();
00462 
00463     glMatrixMode(GL_MODELVIEW);
00464     glPopMatrix();
00465 
00466     /* draw a line representing the real current value if the value is
00467        smoothed */
00468     UInt32  flags = getFlags()[elementID];
00469     if(flags & OSG_SMOOTH)
00470     {
00471         glMatrixMode(GL_MODELVIEW);
00472         glPushMatrix();
00473         glTranslatef(0.5, 0.5, 0);
00474 
00475         Real32  ang = 1 - ((vsave - minV) / (maxV - minV));
00476         glRotatef(45.0, 0.0, 0.0, 1.0);
00477         glRotatef((ang * 270.0f), 0.0, 0.0, 1.0);
00478         glColor4f(1.0, 1.0, 0.0, 1.0);
00479         glBegin(GL_LINES);
00480         glVertex2f(0.0, 0.0);
00481         glVertex2f(0.0, -0.5);
00482         glEnd();
00483 
00484         glMatrixMode(GL_MODELVIEW);
00485         glPopMatrix();
00486     }
00487 
00488     // draw some text ------------
00489     if(getTextEnabled())
00490     {
00491         // create some Strings to be drawn
00492         std::string maxstr = real2String(maxV);
00493         std::string minstr = real2String(minV);
00494 
00495         //set color for drawing the text
00496         glColor4f(1.0f - c[0], 1.0f - c[1], 1.0f - c[2], 1.0f);
00497 
00498         // Draw the current value under the center.
00499         glMatrixMode(GL_MODELVIEW);
00500         glPushMatrix();
00501         glTranslatef(0.5, 0.5, 0.0);
00502         glScalef(0.2, 0.2, 1.0);
00503         drawString(base, real2String(value), TextLayoutParam::ALIGN_MIDDLE,
00504                    TextLayoutParam::ALIGN_FIRST);
00505         glMatrixMode(GL_MODELVIEW);
00506         glPopMatrix();
00507 
00508         // scale and translate the text
00509         glMatrixMode(GL_MODELVIEW);
00510         glPushMatrix();
00511         glTranslatef(0.2, 0.3, 0.0);
00512         glScalef(0.12, 0.12, 1.0);
00513 
00514         //draw the text
00515         glTranslatef(0.0, -1.5, 0.0);
00516         drawString(base, minstr);
00517         glTranslatef(3.4, 0.0, 0.0);
00518         drawString(base, maxstr);
00519         glMatrixMode(GL_MODELVIEW);
00520         glPopMatrix();
00521     }
00522 
00523     // end of text drawing ------
00524 }
00525 
00526 // end of drawAnalog
00527 
00528 /*******************************************************/
00529 void GraphicStatisticsForeground::drawChart(UInt32 elementID, StatElem *el,
00530                                             DrawActionBase *base, Viewport *port)
00531 {
00532     // The amount of the display to be used for the text on the bottom
00533     Real32  textHeight = 0.0;
00534     Real32  textWidth = 0.0;
00535 
00536     if(getTextEnabled())
00537     {
00538         textHeight = 0.2;
00539         textWidth = 0.25;
00540     }
00541 
00542     /* Height of the current quad */
00543     Real32  currQuadheight = 0.0;
00544 
00545     /* Get the current value and process it */
00546     Real32  value = Real32(el->getValue());
00547     processValue(value, elementID);
00548 
00549     //std::cout << "Chart value: " << value << std::endl;
00550     /* calculate minimum value and maximun value */
00551     Real32  minV = getMinValue()[elementID];
00552     Real32  maxV = getMaxValue()[elementID];
00553 
00554     // draw a rectangle with alpha value
00555     Color3f c = getBackgroundColor();
00556     if(getBackgroundEnabled())
00557     {
00558         glColor4f(c[0], c[1], c[2], 0.4);
00559         glRectf(0.0, 0.0, 1.0, 1.0);
00560     }
00561 
00562     // draw a Frame around the display
00563     if(getBorderEnabled())
00564     {
00565         glColor4f(c[0], c[1], c[2], 0.8);
00566         glBegin(GL_LINE_STRIP);
00567         glVertex2f(textWidth, 0.0);
00568         glVertex2f(1.0, 0.0);
00569         glVertex2f(1.0, 1.0);
00570         glVertex2f(textWidth, 1.0);
00571         glEnd();
00572     }
00573 
00574     /* Number of elements in the cycle buffer */
00575     UInt32  number = _history[elementID].size();
00576 
00577     /* width of each Bar */
00578     Real32  step = (1.0f - textWidth) / number;
00579 
00580     /* The collor of the chart is set by the currentColor of this
00581        statistics Element */
00582     glColor4f(getColorCurrent()[elementID][0],
00583               getColorCurrent()[elementID][1],
00584               getColorCurrent()[elementID][2],
00585               getColorCurrent()[elementID][3]);
00586 
00587     /* Base coordiantes for the chart (lower left corner)
00588        Will be set to the current base coordinates of each bar in the
00589        loop */
00590     Real32  deltax = textWidth;
00591 
00592     glMatrixMode(GL_MODELVIEW);
00593     glPushMatrix();
00594     glTranslatef(0.0, textHeight, 0.0);
00595     glScalef(1.0f, 1.0f - textHeight, 1.0f);
00596 
00597     /* loop over all entries in the cycle buffer */
00598     for(UInt32 i = 0; i < number; i++)
00599     {
00600         /* get the current value out of the cycle Buffer */
00601         value = _history[elementID][((_historyID[elementID]) + i) % number];
00602 
00603         /* calculate the height of the quad to be drawn in this
00604                iteration */
00605         currQuadheight = ((value - minV) / (maxV - minV));
00606 
00607         /* draw the current bar */
00608         glBegin(GL_QUADS);
00609         glVertex2f(deltax, 0.0);
00610         glVertex2f(deltax + step, 0.0);
00611         glVertex2f(deltax + step, currQuadheight);
00612         glVertex2f(deltax, currQuadheight);
00613         glEnd();                            // finished drawing current Quad
00614         deltax += step;
00615     }                                       // end for
00616 
00617     glMatrixMode(GL_MODELVIEW);
00618     glPopMatrix();
00619 
00620     if(getTextEnabled())
00621     {
00622         // create some Strings to be drawn
00623         std::string minstr = real2String(minV, "%.0f");
00624         std::string maxstr = real2String(maxV, "%.0f");
00625         std::string valstr = getDescription()[elementID] + " " + real2String(value);
00626 
00627         // set color to draw the text with
00628         glColor4f(1.0f - c[0], 1.0f - c[1], 1.0f - c[2], 1.0f);
00629 
00630         // scale and translate the text
00631         Real32  ratio = ((Real32) port->getPixelHeight()) /
00632             ((Real32) port->getPixelWidth());
00633 
00634         // bottom: Current Value
00635         glMatrixMode(GL_MODELVIEW);
00636         glPushMatrix();
00637         glTranslatef(0.5, 0.01, 0.0);
00638         glScalef(0.2f * ratio, 0.2f, 1.0f);
00639         drawString(base, valstr, TextLayoutParam::ALIGN_MIDDLE);
00640         glMatrixMode(GL_MODELVIEW);
00641         glPopMatrix();
00642 
00643         //draw: min value
00644         glMatrixMode(GL_MODELVIEW);
00645         glPushMatrix();
00646         glTranslatef(0.0, 0.22, 0.0);
00647         glScalef(0.12f * ratio, 0.12f, 1.0f);
00648         drawString(base, minstr);
00649         glMatrixMode(GL_MODELVIEW);
00650         glPopMatrix();
00651 
00652         //draw: maximum value
00653         glMatrixMode(GL_MODELVIEW);
00654         glPushMatrix();
00655         glTranslatef(0.0, 1.0, 0.0);
00656         glScalef(0.12f * ratio, 0.12f, 1.0f);
00657         drawString(base, maxstr, TextLayoutParam::ALIGN_FIRST, TextLayoutParam::ALIGN_FIRST);
00658         glMatrixMode(GL_MODELVIEW);
00659         glPopMatrix();
00660     }
00661 
00662     // end of text drawing ------
00663 }
00664 
00665 /*******************************************************/
00666 void GraphicStatisticsForeground::drawBar(UInt32 elementID, StatElem *el,
00667                                           DrawActionBase *base, Viewport *port)
00668 {
00669     // The amount of the display to be used for the text on the bottom
00670     Real32  textHeight = 0.0;
00671     Real32  textWidth = 0.0;
00672 
00673     if(getTextEnabled())
00674     {
00675         textHeight = 0.2;
00676         textWidth = 0.0;
00677     }
00678 
00679     Real32  xdist = 0;                      // helper Var
00680     Real32  minV = getMinValue()[elementID];
00681     Real32  maxV = getMaxValue()[elementID];
00682 
00683     Real32  value = Real32(el->getValue());
00684     Real32  vsave = value;
00685 
00686     //std::cout << "Bar value: " << value << std::endl;
00687     processValue(value, elementID);
00688     processOnlyValue(vsave, elementID);
00689 
00690     // draw a rectangle with alpha value
00691     Color3f c = getBackgroundColor();
00692     if(getBackgroundEnabled())
00693     {
00694         glColor4f(c[0], c[1], c[2], 0.4);
00695         glRectf(0.0, 0.0, 1.0, 1.0);
00696     }
00697 
00698     // draw a Frame around the display
00699     if(getBorderEnabled())
00700     {
00701         glColor4f(c[0], c[1], c[2], 0.8);
00702         glBegin(GL_LINE_STRIP);
00703         glVertex2f(0.0, 0.0);
00704         glVertex2f(1.0, 0.0);
00705         glVertex2f(1.0, 1.0);
00706         glVertex2f(0.0, 1.0);
00707         glEnd();
00708     }
00709 
00710     // get the Colors into private vars
00711     Color4f MinColor = getColorMin()[elementID];
00712     Color4f CurrentColor = getColorCurrent()[elementID];
00713     Color4f MaxColor = getColorMax()[elementID];
00714 
00715     // xdist helps to calculate the real size[0] of the quadstrip and the colors
00716     xdist = (value - minV) / (maxV - minV) * (1.0f - 2 * textWidth) + textWidth;
00717 
00718     /* draw the quads */
00719     if(xdist < 0.5)
00720     {
00721         glColor4f(MinColor[0], MinColor[1], MinColor[2], getColorMin()[elementID][3]);
00722         glBegin(GL_QUADS);
00723         glVertex2f(textWidth, textHeight);
00724         glVertex2f(textWidth, 1.0);
00725         glColor4f(CurrentColor[0] * 2 * xdist + MinColor[0] * (1 - (2 * xdist)),
00726                   CurrentColor[1] * 2 * xdist + MinColor[1] * (1 - (2 * xdist)),
00727                   CurrentColor[2] * 2 * xdist + MinColor[2] * (1 - (2 * xdist)),
00728                   getColorCurrent()[elementID][3]);
00729         glVertex2f(xdist, 1.0);
00730         glVertex2f(xdist, textHeight);
00731         glEnd();
00732     }                                       // end if
00733     else                                    //if xdist > 0.5
00734     {
00735         glBegin(GL_QUADS);
00736 
00737         // draw first quad
00738         glColor4f(MinColor[0], MinColor[1], MinColor[2], getColorMin()[elementID][3]);
00739         glVertex2f(textWidth, textHeight);
00740         glVertex2f(textWidth, 1.0);
00741         glColor4f(CurrentColor[0], CurrentColor[1], CurrentColor[2],
00742                   getColorCurrent()[elementID][3]);
00743         glVertex2f(0.5, 1.0);
00744         glVertex2f(0.5, textHeight);
00745 
00746         // draw second quad
00747         glVertex2f(0.5, textHeight);
00748         glVertex2f(0.5, 1.0);
00749         glColor4f(MaxColor[0] * ((xdist - 0.5f) * 2) + CurrentColor[0] *
00750                     (1 - ((xdist - 0.5f) * 2)),
00751                   MaxColor[1] * ((xdist - 0.5f) * 2) + CurrentColor[1] *
00752                     (1 - ((xdist - 0.5f) * 2)),
00753                   MaxColor[2] * ((xdist - 0.5f) * 2) + CurrentColor[2] *
00754                     (1 - ((xdist - 0.5f) * 2)), getColorMax()[elementID][3]);
00755         glVertex2f(0.5f + ((xdist - 0.5f)), 1.0);
00756         glVertex2f(0.5f + ((xdist - 0.5f)), textHeight);
00757         glEnd();
00758     }                                       // end else
00759 
00760     /* draw a line representing the real current value
00761        if the value to be digitized is smoothed */
00762     if(_history[elementID].size() > 0)
00763     {
00764         glColor4f(1.0, 1.0, 0.0, 1.0);
00765         glBegin(GL_LINES);
00766 
00767         glVertex2f((vsave - minV) / (maxV - minV) * (1.0f - 2 * textWidth) +
00768                            textWidth, 1.0f);
00769         glVertex2f((vsave - minV) / (maxV - minV) * (1.0f - 2 * textWidth) +
00770                            textWidth, textHeight);
00771         glEnd();
00772     }
00773 
00774     // Draw the text
00775     if(getTextEnabled())
00776     {
00777         // create some Strings to be drawn
00778         std::string valstr = getDescription()[elementID] + " " + real2String(value);
00779         std::string minstr = real2String(minV, "%.0f");
00780         std::string maxstr = real2String(maxV, "%.0f");
00781 
00782         // set color to draw the text with
00783         glColor4f(1.0f - c[0], 1.0f - c[1], 1.0f - c[2], 1.0f);
00784 
00785         // scale and translate the text
00786         Real32  ratio = ((Real32) port->getPixelHeight()) /
00787             ((Real32) port->getPixelWidth());
00788 
00789         // Left side: Min
00790         glMatrixMode(GL_MODELVIEW);
00791         glPushMatrix();
00792         glTranslatef(0.0, 0.7, 0.0);
00793         glScalef(0.15f * ratio, 0.15f, 1.0f);
00794         drawString(base, minstr);
00795         glMatrixMode(GL_MODELVIEW);
00796         glPopMatrix();
00797 
00798         // right side: Max
00799         glMatrixMode(GL_MODELVIEW);
00800         glPushMatrix();
00801         glTranslatef(1.0, 0.7, 0.0);
00802         glScalef(0.15f * ratio, 0.15f, 1.0f);
00803         drawString(base, maxstr, TextLayoutParam::ALIGN_END);
00804         glMatrixMode(GL_MODELVIEW);
00805         glPopMatrix();
00806 
00807         // bottom: Current Value
00808         glMatrixMode(GL_MODELVIEW);
00809         glPushMatrix();
00810         glTranslatef(0.5f, 0.01f, 0.0f);
00811         glScalef(0.2f * ratio, 0.2f, 1.0f);
00812         drawString(base, valstr, TextLayoutParam::ALIGN_MIDDLE);
00813         glMatrixMode(GL_MODELVIEW);
00814         glPopMatrix();
00815     }
00816 
00817     // end of text drawing ------
00818 }
00819 
00820 /*******************************************************/
00821 
00822 //begin drawlinechart
00823 void GraphicStatisticsForeground::drawLineChart(UInt32 elementID, StatElem *el,
00824                                                 DrawActionBase *base,
00825                                                 Viewport *port)
00826 {
00827     // The amount of the display to be used for the text on the bottom
00828     Real32  textHeight = 0.0;
00829     Real32  textWidth = 0.0;
00830 
00831     if(getTextEnabled())
00832     {
00833         textHeight = 0.2;
00834         textWidth = 0.25;
00835     }
00836 
00837     /* Height of the current quad */
00838     Real32  currHeight = 0.0;
00839 
00840     /* Flags for check whether points should be drawn or not */
00841     UInt32  flags = getFlags()[elementID];
00842 
00843     /* Get the current value and process it */
00844     Real32  value = Real32(el->getValue());
00845     Real32  realValue = (flags & OSG_RECIPROC) ? 1.f / value : value;
00846 
00847     processValue(value, elementID);
00848 
00849     //std::cout << "LineChart value: " << value << std::endl;
00850     /* calculate minimum value and maximun value */
00851     Real32  minV = getMinValue()[elementID];
00852     Real32  maxV = getMaxValue()[elementID];
00853 
00854     // draw a rectangle with alpha value
00855     Color3f c = getBackgroundColor();
00856     if(getBackgroundEnabled())
00857     {
00858         glColor4f(c[0], c[1], c[2], 0.4);
00859         glRectf(0.0, 0.0, 1.0, 1.0);
00860     }
00861 
00862     // draw a Frame around the display
00863     if(getBorderEnabled())
00864     {
00865         glColor4f(c[0], c[1], c[2], 0.8);
00866         glBegin(GL_LINE_STRIP);
00867         glVertex2f(textWidth, 0.0);
00868         glVertex2f(1.0, 0.0);
00869         glVertex2f(1.0, 1.0);
00870         glVertex2f(textWidth, 1.0);
00871         glEnd();
00872     }
00873 
00874     /* Number of elements in the cycle buffer */
00875     UInt32  number = _history[elementID].size();
00876 
00877     /* width of each Bar */
00878     Real32  step = (1.0f - textWidth) / number;
00879 
00880     /* The collor of the chart is set by the currentColor of this
00881        statistics Element */
00882     glColor4f(getColorCurrent()[elementID][0], getColorCurrent()[elementID][1],
00883               getColorCurrent()[elementID][2], getColorCurrent()[elementID][3]);
00884 
00885     /* Base coordiantes for the chart (lower left corner)
00886        Will be set to the current base coordinates of each bar in the
00887        loop */
00888     Real32  deltax = textWidth;
00889 
00890     glMatrixMode(GL_MODELVIEW);
00891     glPushMatrix();
00892     glTranslatef(0.0, textHeight, 0.0);
00893     glScalef(1.0f, 1.0f - textHeight, 1.0f);
00894 
00895     /* loop over all entries in the cycle buffer */
00896     value = _history[elementID][_historyID[elementID]];
00897 
00898     /* save the last x und y value to draw the line in the next
00899        iterarion */
00900     Real32  lastx = textWidth;
00901     Real32  lasty = ((value - minV) / (maxV - minV));
00902 
00903     for(UInt32 i = 0; i < number; i++)
00904     {
00905         /* get the current value out of the cycle Buffer */
00906         value = _history[elementID][((_historyID[elementID]) + i) % number];
00907 
00908         /* calculate the height of the quad to be drawn in this
00909                iteration */
00910         currHeight = ((value - minV) / (maxV - minV));
00911 
00912         /* draw the current line */
00913         glBegin(GL_LINES);
00914         glVertex2f(lastx, lasty);
00915         glVertex2f(deltax, currHeight);
00916         glEnd();
00917 
00918         // save x und y position to draw the line in the next iteration */
00919         lastx = deltax;
00920         lasty = currHeight;
00921 
00922         //            Real32 angle = 0.0;
00923         /* draw Point if wanted */
00924         if(flags & OSG_ENABLE_POINTS)
00925         {
00926             /* filled circle
00927                        glPushMatrix();
00928                        glTranslatef(deltax, currHeight, 0.0);
00929                        glBegin(GL_POLYGON);
00930                        for (angle = 0.0; angle < 2 * Pi; angle += Pi / 24)
00931                        {
00932                        glVertex2f(0.0125 *cos(angle), 0.0125 * sin(angle));
00933                        }
00934                        glEnd();
00935                        glPopMatrix();*/
00936             // draw one single point with GL_POINT_SIZE =
00937             glPointSize(2.0f * getLineWidth());
00938             glBegin(GL_POINTS);
00939             glVertex2f(deltax, currHeight);
00940             glEnd();
00941         }                                   // end if
00942 
00943         deltax += step;
00944     }                                       // end for
00945 
00946     glMatrixMode(GL_MODELVIEW);
00947     glPopMatrix();
00948 
00949     // draw some text ------------
00950     if(getTextEnabled())
00951     {
00952         // create some Strings to be drawn
00953         std::string valstr = getDescription()[elementID] + " " +
00954                     real2String(realValue);
00955 
00956         // set color to draw the text with
00957         glColor4f(1.0f - c[0], 1.0f - c[1], 1.0f - c[2], 1.0f);
00958 
00959         // scale and translate the text
00960         Real32  ratio = ((Real32) port->getPixelHeight()) /
00961             ((Real32) port->getPixelWidth());
00962 
00963         // bottom: Current Value
00964         glMatrixMode(GL_MODELVIEW);
00965         glPushMatrix();
00966         glTranslatef(0.5, 0.01, 0.0);
00967         glScalef(0.2f * ratio, 0.2f, 1.0f);
00968         drawString(base, valstr, TextLayoutParam::ALIGN_MIDDLE);
00969         glMatrixMode(GL_MODELVIEW);
00970         glPopMatrix();
00971 
00972         //draw: min value
00973         if(flags & OSG_MAX_TEXT)
00974         {
00975             std::string minstr = real2String(minV, "%.0f");
00976             glMatrixMode(GL_MODELVIEW);
00977             glPushMatrix();
00978             glTranslatef(0.0, 0.22, 0.0);
00979             glScalef(0.12f * ratio, 0.12f, 1.0f);
00980             drawString(base, minstr);
00981             glMatrixMode(GL_MODELVIEW);
00982             glPopMatrix();
00983         }
00984 
00985         //draw: maximum value
00986         if(flags & OSG_MIN_TEXT)
00987         {
00988             std::string maxstr = real2String(maxV, "%.0f");
00989             glMatrixMode(GL_MODELVIEW);
00990             glPushMatrix();
00991             glTranslatef(0.0, 1.0, 0.0);
00992             glScalef(0.12f * ratio, 0.12f, 1.0f);
00993             drawString(base, maxstr, TextLayoutParam::ALIGN_FIRST,
00994                        TextLayoutParam::ALIGN_FIRST);
00995             glMatrixMode(GL_MODELVIEW);
00996             glPopMatrix();
00997         }
00998     }
00999 
01000     // end of text drawing ------
01001 }
01002 
01003 /* */
01004 void GraphicStatisticsForeground::drawText(UInt32 elementID, StatElem *el,
01005                                            DrawActionBase *base, Viewport *port)
01006 {
01007     /* Get the current value and process it */
01008     Real32  value = Real32(el->getValue());
01009     processOnlyValue(value, elementID);
01010 
01011     //std::cout << "TextChart value: " << value << std::endl;
01012     /* get value, calculate minimum value and maximun value and
01013        convert into a string*/
01014     Real32      minV = getMinValue()[elementID];
01015     Real32      maxV = getMaxValue()[elementID];
01016     std::string minstr = real2String(minV, "%.0f");
01017     std::string maxstr = real2String(maxV, "%.0f");
01018     std::string valstr = getDescription()[elementID] + " " + real2String(value);
01019 
01020     // draw a rectangle with alpha value
01021     Color3f     c = getBackgroundColor();
01022     if(getBackgroundEnabled())
01023     {
01024         glColor4f(c[0], c[1], c[2], 0.4);
01025         glRectf(0.0, 0.0, 1.0, 1.0);
01026     }
01027 
01028     // draw a Frame around the display
01029     if(getBorderEnabled())
01030     {
01031         glColor4f(c[0], c[1], c[2], 0.8);
01032         glBegin(GL_LINE_STRIP);
01033         glVertex2f(0.0, 0.0);
01034         glVertex2f(1.0, 0.0);
01035         glVertex2f(1.0, 1.0);
01036         glVertex2f(0.0, 1.0);
01037         glEnd();
01038     }
01039 
01040     // set color to draw the text with
01041     glColor4f(1.0f - c[0], 1.0f - c[1], 1.0f - c[2], 1.0f);
01042 
01043     // scale and translate the text
01044     Real32  ratio = ((Real32) port->getPixelHeight()) /
01045         ((Real32) port->getPixelWidth());
01046 
01047     // Current Value
01048     glMatrixMode(GL_MODELVIEW);
01049     glPushMatrix();
01050     glTranslatef(0.02, 0.7, 0.0);
01051     glScalef(0.18f * ratio, 0.18f, 1.0f);
01052     drawString(base, valstr);
01053     glMatrixMode(GL_MODELVIEW);
01054     glPopMatrix();
01055 
01056     // MinValue
01057     glMatrixMode(GL_MODELVIEW);
01058     glPushMatrix();
01059     glTranslatef(0.02, 0.5, 0.0);
01060     glScalef(0.18f * ratio, 0.18f, 1.0f);
01061     drawString(base, "Min: " + minstr);
01062     glMatrixMode(GL_MODELVIEW);
01063     glPopMatrix();
01064 
01065     // MaxValue
01066     glMatrixMode(GL_MODELVIEW);
01067     glPushMatrix();
01068     glTranslatef(0.02, 0.3, 0.0);
01069     glScalef(0.18f * ratio, 0.18f, 1.0f);
01070     drawString(base, "Max: " + maxstr);
01071     glMatrixMode(GL_MODELVIEW);
01072     glPopMatrix();
01073 }
01074 
01075 // end of drawText
01076 
01077 /*******************************************************/
01078 
01080 void GraphicStatisticsForeground::calcPosAndSize(const UInt32 &id,
01081                                                  Viewport *port,
01082                                                  Vec2f *Position,
01083                                                  Vec2f *Size)
01084 {
01085     // Width and Height of the current viewport
01086     // needed for pixel to relative conversion
01087     Real32  pw = Real32(port->getPixelWidth ());     // PixelWidth
01088     Real32  ph = Real32(port->getPixelHeight());    // PixelHeight
01089     Real32  ratio = pw / ph;
01090 
01091     /*
01092       Calculate the size
01093     */
01094     Vec2f   size(getSize()[id][0], getSize()[id][1]);   // Temp Size
01095 
01096     // Check for values < 0
01097     // If both values a <0 fall back to
01098     if(size[0] < 0 && size[1] < 0)
01099     {
01100         size[0] = size[1] = 1.0;
01101     }
01102     else
01103     {
01104         if(size[0] < 0)
01105         {
01106             size[0] = osgabs(size[0]) * size[1] / ratio;
01107         }
01108 
01109         if(size[1] < 0)
01110         {
01111             size[1] = osgabs(size[1]) * size[0] * ratio;
01112         }
01113     }
01114 
01115     //convert pixel based sizes to relative ones
01116     if(size[0] > 1.0)
01117         size[0] = size[0] / pw;
01118     if(size[1] > 1.0)
01119         size[1] = size[1] / ph;
01120 
01121     // Save the Size
01122     (*Size) = size;
01123 
01124     /*
01125       calculate the position
01126     */
01127     Vec2f   pos(getPos()[id][0], getPos()[id][1]);      // Temp Position
01128 
01129     // Hack the floats
01130     bool    xneg = false;
01131     bool    yneg = false;
01132 
01133     if(pos[0] < 0)
01134     {
01135         pos[0] = pos[0] + 1;
01136         xneg = true;
01137     }
01138 
01139     if(pos[1] < 0)
01140     {
01141         pos[1] = pos[1] + 1;
01142         yneg = true;
01143     }
01144 
01145     // convert the pixel Data to relative positions
01146     if(osgabs(pos[0]) > 1.0)
01147         pos[0] = pos[0] / pw;
01148     if(osgabs(pos[1]) > 1.0)
01149         pos[1] = pos[1] / ph;
01150 
01151     // check whether the positions are relative to the right/bottom
01152     if(xneg)
01153         pos[0] = 1.0f + pos[0] - size[0];
01154     if(yneg)
01155         pos[1] = 1.0f + pos[1] - size[1];
01156 
01157     // Save the calculated position
01158     (*Position) = pos;
01159 }
01160 
01161 // calcPosAndSize()
01162 
01164 void GraphicStatisticsForeground::initText(void)
01165 {
01166     // create the text needed
01167 #ifdef OSG_HAS_SSTREAM
01168     std::istringstream stream(GraphicsStatisticsFontString,
01169                               std::istringstream::in |
01170                               std::istringstream::out);
01171 #else
01172     std::istrstream stream(
01173         (char *) GraphicsStatisticsFontData,
01174                  GraphicsStatisticsFontDataSize);
01175 #endif
01176 
01177     _face = TextTXFFace::createFromStream(stream);
01178     addRefP(_face);
01179 
01180     ImagePtr texture = _face->getTexture();
01181     _texchunk = TextureChunk::create();
01182     beginEditCP(_texchunk);
01183     {
01184         _texchunk->setImage(texture);
01185         _texchunk->setWrapS(GL_CLAMP);
01186         _texchunk->setWrapT(GL_CLAMP);
01187         _texchunk->setEnvMode(GL_MODULATE);
01188     }
01189     endEditCP(_texchunk);
01190 }
01191 
01193 void GraphicStatisticsForeground::drawString(DrawActionBase *base,
01194                                              const std::string &text,
01195                                              TextLayoutParam::Alignment majorAlignment,
01196                                              TextLayoutParam::Alignment minorAlignment)
01197 {
01198     std::vector < std::string > stat(1);
01199     stat[0] = text;
01200 
01201     TextLayoutParam layoutParam;
01202     layoutParam.majorAlignment = majorAlignment;
01203     layoutParam.minorAlignment = minorAlignment;
01204     TextLayoutResult layoutResult;
01205     _face->layout(stat, layoutParam, layoutResult);
01206 
01207     glMatrixMode(GL_MODELVIEW);
01208     glPushMatrix();
01209 
01210     // Draw the text
01211     _texchunk->activate(base);
01212 
01213     glBegin(GL_QUADS);
01214     UInt32 i, numGlyphs = layoutResult.getNumGlyphs();
01215     for(i = 0; i < numGlyphs; ++i)
01216     {
01217         const TextTXFGlyph &glyph = _face->getTXFGlyph(layoutResult.indices[i]);
01218         Real32 width = glyph.getWidth();
01219         Real32 height = glyph.getHeight();
01220         // No need to draw invisible glyphs
01221         if ((width <= 0.f) || (height <= 0.f))
01222             continue;
01223 
01224         // Calculate coordinates
01225         const Vec2f &pos = layoutResult.positions[i];
01226         Real32 posLeft = pos.x();
01227         Real32 posTop = pos.y();
01228         Real32 posRight = pos.x() + width;
01229         Real32 posBottom = pos.y() - height;
01230         Real32 texCoordLeft = glyph.getTexCoord(TextTXFGlyph::COORD_LEFT);
01231         Real32 texCoordTop = glyph.getTexCoord(TextTXFGlyph::COORD_TOP);
01232         Real32 texCoordRight = glyph.