⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soperfgraph.cpp

📁 海量地形数据漫游系统,对于OPENGL开发人员具有一定的参考
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************\ * * SoPerfGraph.cpp * * Performance graph node * * Authors: PCJohn (peciva AT fit.vutbr.cz) * Contributors: * * ---------------------------------------------------------------------------- * * THIS SOFTWARE IS NOT COPYRIGHTED * * This source code is offered for use in the public domain. * You may use, modify or distribute it freely. * * This source code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY.  ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY * DISCLAIMED.  This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * If you find the source code useful, authors will kindly welcome * if you give them credit and keep their names with their source code, * but do not feel forced to do so. *\*****************************************************************************/#include <Inventor/nodes/SoAnnotation.h>#include <Inventor/nodes/SoBaseColor.h>#include <Inventor/nodes/SoComplexity.h>#include <Inventor/nodes/SoCoordinate3.h>#include <Inventor/nodes/SoFont.h>#include <Inventor/nodes/SoIndexedTriangleStripSet.h>#include <Inventor/nodes/SoLightModel.h>#include <Inventor/nodes/SoMaterial.h>#include <Inventor/nodes/SoOrthographicCamera.h>#include <Inventor/nodes/SoText2.h>#include <Inventor/nodes/SoTexture2.h>#include <Inventor/nodes/SoTextureCoordinate2.h>#include <Inventor/nodes/SoTranslation.h>#include <Inventor/nodes/SoTransparencyType.h>#include <Inventor/actions/SoGLRenderAction.h>#include <Inventor/actions/SoGetBoundingBoxAction.h>#include <Inventor/actions/SoPickAction.h>#include <Inventor/sensors/SoNodeSensor.h>#include <Inventor/misc/SoChildList.h>#include <Inventor/SbTime.h>#include <Inventor/C/tidbits.h> // coin_next_power_of_two#include "SoPerfGraph.h"SO_NODE_SOURCE(SoPerfGraph);#define THIS this->pimpl#define TEXTURE_COMPONENTS  4#define NUM_VALUES_OVER  20#define AVG_UPDATE_TIME  0.35#define AVG_SUM_TIME  1.class SoPerfGraphP {public:  float *values;  double *timeStamps;  int numValues;  int startIndex;  float maxValue;  float renderedMax;  int texRequestedWidth;  int texRequestedHeight;  float maxTexCoordX;  float maxTexCoordY;  int texIndex;  SoChildList children;  SoPerfGraph *parent;  SoOrthographicCamera *camera;  SoCoordinate3 *coordNode;  SoIndexedTriangleStripSet *triStrip;  SoTexture2 *textureNode;  SoTextureCoordinate2 *texCoordNode;  SoTranslation *textTranslationMaxNode;  SoTranslation *textTranslationAvgNode;  SoText2 *textNodeMax;  SoText2 *textNodeAvg;  double lastAvgUpdate;  SbViewportRegion previousViewport;  SoNodeSensor nodeSensor;  struct objData {    SbBool vpValid : 1;    SbBool posValid : 1;    SbBool sizeValid : 1;    SbBool textureNeedsResize : 1;    objData() : vpValid(FALSE), posValid(FALSE), sizeValid(FALSE), textureNeedsResize(TRUE)  {}  } objData;  SoPerfGraphP(SoPerfGraph *aparent) : values(NULL), timeStamps(NULL),      children(aparent), parent(aparent), lastAvgUpdate(0.)  {    maxTexCoordX = 1.f; // this value may be used BEFORE its proper initialization in updateSceneIfNecessary()    nodeSensor.setFunction(fieldChangedCB);    nodeSensor.setData(this);    nodeSensor.setPriority(0);     nodeSensor.attach(aparent);   }  ~SoPerfGraphP()  { delete[] values; delete[] timeStamps; }  static void fieldChangedCB(void *data, SoSensor *sensor);  void updateSceneIfNecessary(const SbViewportRegion &vp, SbBool textureDataRequired);  void updateTextureCoordinates(int texSizeY);  void redrawTexture();  static float roundUp(float value);};static int32_t coordIndices[] = { 0,1,2,3,-1, };static SbVec2f texCoords[] = { SbVec2f(0.f,0.f), SbVec2f(0.f,1.f), SbVec2f(1.f,0.f), SbVec2f(1.f,1.f) };SoPerfGraph::SoPerfGraph(){  SO_NODE_CONSTRUCTOR(SoPerfGraph);  SO_NODE_ADD_FIELD(vertAlignment,    (BOTTOM));  SO_NODE_ADD_FIELD(horAlignment,     (LEFT));  SO_NODE_ADD_FIELD(size,             (0.35f,0.15f));  SO_NODE_ADD_FIELD(position,         (0.03f,0.03f));  SO_NODE_ADD_FIELD(sizeInPixels,     (0,0));  SO_NODE_ADD_FIELD(positionInPixels, (0,0));  SO_NODE_ADD_FIELD(vertScreenOrigin, (BOTTOM));  SO_NODE_ADD_FIELD(horScreenOrigin,  (LEFT));  SO_NODE_ADD_FIELD(dataScale,        (2.f,1.f));  SO_NODE_DEFINE_ENUM_VALUE(VertAlignment, BOTTOM);  SO_NODE_DEFINE_ENUM_VALUE(VertAlignment, HALF);  SO_NODE_DEFINE_ENUM_VALUE(VertAlignment, TOP);  SO_NODE_SET_SF_ENUM_TYPE(vertAlignment, VertAlignment);  SO_NODE_SET_SF_ENUM_TYPE(vertScreenOrigin, VertAlignment);  SO_NODE_DEFINE_ENUM_VALUE(HorAlignment, LEFT);  SO_NODE_DEFINE_ENUM_VALUE(HorAlignment, CENTER);  SO_NODE_DEFINE_ENUM_VALUE(HorAlignment, RIGHT);  SO_NODE_SET_SF_ENUM_TYPE(horAlignment, HorAlignment);  SO_NODE_SET_SF_ENUM_TYPE(horScreenOrigin, HorAlignment);  pimpl = new SoPerfGraphP(this);  THIS->numValues = 128 + NUM_VALUES_OVER;  THIS->values = new float[THIS->numValues];  THIS->timeStamps = new double[THIS->numValues];  memset(THIS->values, 0, THIS->numValues*sizeof(float));  memset(THIS->timeStamps, 0, THIS->numValues*sizeof(double));  THIS->maxValue = 0.f;  THIS->renderedMax = 0.f;  THIS->startIndex = 0;  THIS->texIndex = 0;  SoSeparator *root = new SoAnnotation;  root->renderCaching = SoSeparator::OFF;  THIS->camera = new SoOrthographicCamera;  THIS->camera->height = 1.f;  THIS->camera->viewportMapping = SoCamera::LEAVE_ALONE;  root->addChild(THIS->camera);  SoLightModel *lm = new SoLightModel;  lm->model.setValue(SoLightModel::BASE_COLOR);  root->addChild(lm);  SoTransparencyType *tt = new SoTransparencyType;  tt->value = SoTransparencyType::BLEND;  root->addChild(tt);  THIS->coordNode = new SoCoordinate3;  THIS->coordNode->point.setNum(4);  root->addChild(THIS->coordNode);  THIS->texCoordNode = new SoTextureCoordinate2;  THIS->texCoordNode->point.setValues(0, sizeof(texCoords)/sizeof(int32_t), texCoords);  root->addChild(THIS->texCoordNode);  SoComplexity *cplx = new SoComplexity;  cplx->textureQuality = 0.1f; // this should disable texture filtering,                               // that we do not want to happen in our graph (causes distortion)  cplx->type.setIgnored(TRUE);  cplx->value.setIgnored(TRUE);  root->addChild(cplx);  THIS->textureNode = new SoTexture2;  THIS->textureNode->model = SoTexture2::REPLACE;  root->addChild(THIS->textureNode);  THIS->triStrip = new SoIndexedTriangleStripSet;  THIS->triStrip->coordIndex.setValues(0, sizeof(coordIndices)/sizeof(int32_t), coordIndices);  root->addChild(THIS->triStrip);  // set default font  SoFont *font = new SoFont;  root->addChild(font);  root->addChild(new SoTexture2);  THIS->textTranslationMaxNode = new SoTranslation;  root->addChild(THIS->textTranslationMaxNode);  THIS->textNodeMax = new SoText2;  root->addChild(THIS->textNodeMax);  THIS->textTranslationAvgNode = new SoTranslation;  root->addChild(THIS->textTranslationAvgNode);  THIS->textNodeAvg = new SoText2;  THIS->textNodeAvg->justification.setValue(SoText2::RIGHT);  THIS->textNodeAvg->string.setValue("12");  root->addChild(THIS->textNodeAvg);  THIS->children.append(root);}SoPerfGraph::~SoPerfGraph(){  delete pimpl;}void SoPerfGraphP::fieldChangedCB(void *data, SoSensor *sensor){  SoPerfGraphP *p = (SoPerfGraphP*)data;  if (((SoNodeSensor*)sensor)->getTriggerNode() != p->parent)    return;  SoField *f = ((SoNodeSensor*)sensor)->getTriggerField();  // Camera settings may need to be changed  if (f == &p->parent->vertScreenOrigin || f == &p->parent->horScreenOrigin)    p->objData.vpValid = FALSE;  // Coordinates may need recalculation  if (f == &p->parent->vertAlignment || f == &p->parent->horAlignment ||      f == &p->parent->position || f == &p->parent->positionInPixels)    p->objData.posValid = FALSE;  // Texture size and coordinates may need to be updated  if (f == &p->parent->size || f == &p->parent->sizeInPixels ||      f == &p->parent->dataScale)    p->objData.sizeValid = FALSE;}void SoPerfGraph::appendValue(float v){  // update maxValue  float newMax = THIS->renderedMax;  if (v > THIS->maxValue) {    // incoming value is the greatest one    THIS->maxValue = v;    newMax = THIS->roundUp(THIS->maxValue);  } else {    // leaving value is the greatest one    if (THIS->values[THIS->startIndex] == THIS->maxValue) {      float max = v;      THIS->values[THIS->startIndex] = v; // old value, that we certainly do not want to find      int i,c = THIS->numValues;      for (i=0; i<c; i++)        if (THIS->values[i] > max)          max = THIS->values[i];      THIS->maxValue = max;      newMax = THIS->roundUp(THIS->maxValue);    }  }  // update text  if (newMax != THIS->renderedMax) {        // postphone scaling down (avoids quick rescalling)    if (newMax < THIS->renderedMax)      newMax = THIS->roundUp(THIS->maxValue * 1.1f);    // update text and texture    if (newMax != THIS->renderedMax) {      THIS->renderedMax = newMax;      THIS->redrawTexture();      SbString s;      s.sprintf("%.5g", newMax);      THIS->textNodeMax->string.setValue(s);    }  }  // update value array  THIS->values[THIS->startIndex] = v;  THIS->timeStamps[THIS->startIndex] = SbTime::getTimeOfDay().getValue();  // update avg value  // The update is done four times per second from values up to one second old.  if (THIS->lastAvgUpdate + AVG_UPDATE_TIME <= THIS->timeStamps[THIS->startIndex]) {    THIS->lastAvgUpdate = THIS->timeStamps[THIS->startIndex];    double stop = THIS->timeStamps[THIS->startIndex] - AVG_SUM_TIME;    float sum = THIS->values[THIS->startIndex];    int num = 1;    int i = THIS->startIndex - 1;    if (i<0)  i += THIS->numValues;    while (THIS->timeStamps[i] > stop && i != THIS->startIndex) {      sum += THIS->values[THIS->startIndex];      num++;      if (--i<0)  i += THIS->numValues;    }    SbString s;    s.sprintf("avg: %#.5g", sum/num);    THIS->textNodeAvg->string.setValue(s);  }  // move to the next index  THIS->startIndex++;  if (THIS->startIndex == THIS->numValues)    THIS->startIndex = 0;  // update texture  SbVec2s texSize;  int components;  unsigned char *img = THIS->textureNode->image.startEditing(texSize, components);  if (img) {    rasterizeColumn(img+THIS->texIndex*texSize[0]*TEXTURE_COMPONENTS, texSize[0], v);    THIS->texIndex++;    if (THIS->texIndex == texSize[1])      THIS->texIndex = 0;  }  THIS->textureNode->image.finishEditing();  // animate texture coordinates  THIS->updateTextureCoordinates(texSize[1]);}void SoPerfGraphP::updateSceneIfNecessary(const SbViewportRegion &vp, SbBool textureDataRequired){  if (!(vp == previousViewport) || !objData.posValid || !objData.sizeValid) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -