zoukankan      html  css  js  c++  java
  • [CC]LOD技术

    ccGLWindow::paintGL()

                 |

      ccGLWindow::fullRenderingPass(...)

            |

          ccGLWindow::drawBackground(context, renderingParams);

          ccGLWindow::draw3D(context, renderingParams);//ccGLWindow::draw3D(CC_DRAW_CONTEXT& CONTEXT, RenderingParams& renderingParams)

              |

             m_globalDBRoot->draw(CONTEXT); // ccHObject*

             m_winDBRoot->draw(CONTEXT);  //ccHObject*

     1 void ccHObject::draw(CC_DRAW_CONTEXT& context)
     2 {
     3     if (!isEnabled())
     4         return;
     5 
     6     //are we currently drawing objects in 2D or 3D?
     7     bool draw3D = MACRO_Draw3D(context);
     8     
     9     //the entity must be either visible or selected, and of course it should be displayed in this context
    10     bool drawInThisContext = ((m_visible || m_selected) && m_currentDisplay == context._win);
    11 
    12     //no need to display anything but clouds and meshes in "element picking mode"
    13     drawInThisContext &= (    ( !MACRO_DrawPointNames(context)    || isKindOf(CC_TYPES::POINT_CLOUD) ) || 
    14                             ( !MACRO_DrawTriangleNames(context)    || isKindOf(CC_TYPES::MESH) ));
    15 
    16     if (draw3D)
    17     {
    18         //apply 3D 'temporary' transformation (for display only)
    19         if (m_glTransEnabled)
    20         {
    21             glMatrixMode(GL_MODELVIEW);
    22             glPushMatrix();
    23             glMultMatrixf(m_glTrans.data());
    24         }
    25 
    26         if (    context.decimateCloudOnMove                        //LOD for clouds is enabled?
    27             &&    context.currentLODLevel >= context.minLODLevel    //and we are currently rendering higher levels?
    28             )
    29         {
    30             //only for real clouds
    31             drawInThisContext &= isA(CC_TYPES::POINT_CLOUD);
    32         }
    33     }
    34 
    35     //draw entity
    36     if (m_visible && drawInThisContext)
    37     {
    38         if (( !m_selected || !MACRO_SkipSelected(context) ) &&
    39             (  m_selected || !MACRO_SkipUnselected(context) ))
    40         {
    41             //apply default color (in case of)
    42             ccGL::Color3v(context.pointsDefaultCol.rgb);
    43 
    44             drawMeOnly(context);
    45 
    46             //draw name in 3D (we display it in the 2D foreground layer in fact!)
    47             if (m_showNameIn3D && MACRO_Draw2D(context) && MACRO_Foreground(context) && !MACRO_DrawNames(context))
    48                 drawNameIn3D(context);
    49         }
    50     }
    51 
    52     //draw entity's children
    53     for (Container::iterator it = m_children.begin(); it != m_children.end(); ++it)
    54         (*it)->draw(context);
    55 
    56     //if the entity is currently selected, we draw its bounding-box
    57     if (m_selected && draw3D && drawInThisContext && !MACRO_DrawNames(context) && context.currentLODLevel == 0)
    58     {
    59         drawBB(context.bbDefaultCol);
    60     }
    61 
    62     if (draw3D && m_glTransEnabled)
    63         glPopMatrix();
    64 }

     点云八叉树

    class QCC_DB_LIB_API ccOctree : public CCLib::DgmOctree, public ccHObject

      八叉树的网格显示,QCC_DB_LIB项目下。

      1 /*** RENDERING METHODS ***/
      2 
      3 void ccOctree::RenderOctreeAs(  CC_OCTREE_DISPLAY_TYPE octreeDisplayType,
      4                                 ccOctree* theOctree,
      5                                 unsigned char level,
      6                                 ccGenericPointCloud* theAssociatedCloud,
      7                                 int &octreeGLListID,
      8                                 bool updateOctreeGLDisplay)
      9 {
     10     if (!theOctree || !theAssociatedCloud)
     11         return;
     12 
     13     glPushAttrib(GL_LIGHTING_BIT);
     14 
     15     if (octreeDisplayType == WIRE)
     16     {
     17         //cet affichage demande trop de memoire pour le stocker sous forme de liste OpenGL
     18         //donc on doit le generer dynamiquement
     19         
     20         glDisable(GL_LIGHTING); //au cas où la lumiere soit allumee
     21         ccGL::Color3v(ccColor::green.rgba);
     22 
     23         void* additionalParameters[] = { theOctree->m_frustrumIntersector };
     24         theOctree->executeFunctionForAllCellsAtLevel(    level,
     25                                                         &DrawCellAsABox,
     26                                                         additionalParameters);
     27     }
     28     else
     29     {
     30         glDrawParams glParams;
     31         theAssociatedCloud->getDrawingParameters(glParams);
     32 
     33         if (glParams.showNorms)
     34         {
     35             //DGM: Strangely, when Qt::renderPixmap is called, the OpenGL version is sometimes 1.0!
     36             glEnable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE));
     37             glMaterialfv(GL_FRONT_AND_BACK,    GL_AMBIENT,        CC_DEFAULT_CLOUD_AMBIENT_COLOR.rgba  );
     38             glMaterialfv(GL_FRONT_AND_BACK,    GL_SPECULAR,    CC_DEFAULT_CLOUD_SPECULAR_COLOR.rgba );
     39             glMaterialfv(GL_FRONT_AND_BACK,    GL_DIFFUSE,        CC_DEFAULT_CLOUD_DIFFUSE_COLOR.rgba  );
     40             glMaterialfv(GL_FRONT_AND_BACK,    GL_EMISSION,    CC_DEFAULT_CLOUD_EMISSION_COLOR.rgba );
     41             glMaterialf (GL_FRONT_AND_BACK,    GL_SHININESS,    CC_DEFAULT_CLOUD_SHININESS);
     42             glEnable(GL_LIGHTING);
     43 
     44             glEnable(GL_COLOR_MATERIAL);
     45             glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
     46         }
     47 
     48         if (!glParams.showColors)
     49             ccGL::Color3v(ccColor::white.rgba);
     50 
     51         if (updateOctreeGLDisplay || octreeGLListID < 0)
     52         {
     53             if (octreeGLListID < 0)
     54                 octreeGLListID = glGenLists(1);
     55             else if (glIsList(octreeGLListID))
     56                 glDeleteLists(octreeGLListID,1);
     57             glNewList(octreeGLListID,GL_COMPILE);
     58 
     59             if (octreeDisplayType == MEAN_POINTS)
     60             {
     61                 void* additionalParameters[2] = {    reinterpret_cast<void*>(&glParams),
     62                                                     reinterpret_cast<void*>(theAssociatedCloud),
     63                 };
     64 
     65                 glBegin(GL_POINTS);
     66                 theOctree->executeFunctionForAllCellsAtLevel(    level,
     67                                                                 &DrawCellAsAPoint,
     68                                                                 additionalParameters);
     69                 glEnd();
     70             }
     71             else
     72             {
     73                 //by default we use a box as primitive
     74                 PointCoordinateType cs = theOctree->getCellSize(level);
     75                 CCVector3 dims(cs,cs,cs);
     76                 ccBox box(dims);
     77                 box.showColors(glParams.showColors || glParams.showSF);
     78                 box.showNormals(glParams.showNorms);
     79 
     80                 //trick: replace all normal indexes so that they point on the first one
     81                 {
     82                     if (box.arePerTriangleNormalsEnabled())
     83                         for (unsigned i=0;i<box.size();++i)
     84                             box.setTriangleNormalIndexes(i,0,0,0);
     85                 }
     86 
     87                 //fake context
     88                 CC_DRAW_CONTEXT context;
     89                 context.flags = CC_DRAW_3D | CC_DRAW_FOREGROUND| CC_LIGHT_ENABLED;
     90                 context._win = 0;
     91 
     92                 void* additionalParameters[4] = {    reinterpret_cast<void*>(&glParams),
     93                                                     reinterpret_cast<void*>(theAssociatedCloud),
     94                                                     reinterpret_cast<void*>(&box),
     95                                                     reinterpret_cast<void*>(&context)
     96                 };
     97 
     98                 theOctree->executeFunctionForAllCellsAtLevel(    level,
     99                                                                 &DrawCellAsAPrimitive,
    100                                                                 additionalParameters);
    101             }
    102 
    103             glEndList();
    104         }
    105 
    106         glCallList(octreeGLListID);
    107 
    108         if (glParams.showNorms)
    109         {
    110             glDisable(GL_COLOR_MATERIAL);
    111             glDisable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE));
    112             glDisable(GL_LIGHTING);
    113         }
    114     }
    115 
    116     glPopAttrib();
    117 }
    ccOctree::RenderOctreeAs

    点云类

    class QCC_DB_LIB_API ccPointCloud : public CCLib::ChunkedPointCloud, public ccGenericPointCloud

    class QCC_DB_LIB_API ccGenericPointCloud : public ccShiftedObject,  virtual public CCLib::GenericIndexedCloudPersist

    class CC_CORE_LIB_API GenericIndexedCloudPersist : virtual public GenericIndexedCloud

    class CC_CORE_LIB_API GenericIndexedCloud : virtual public GenericCloud

    注意ccPointCloud重载了ccHObject的一些方法

    1 virtual void drawMeOnly(CC_DRAW_CONTEXT& context);
    2 virtual void applyGLTransformation(const ccGLMatrix& trans);
    3 virtual bool toFile_MeOnly(QFile& out) const;
    4 virtual bool fromFile_MeOnly(QFile& in, short dataVersion, int flags);
    5 virtual void notifyGeometryUpdate();


    以下为drawMeOnly方法:

      1 void ccPointCloud::drawMeOnly(CC_DRAW_CONTEXT& context)
      2 {
      3     if (!m_points->isAllocated())
      4         return;
      5 
      6     if (MACRO_Draw3D(context))
      7     {
      8         //we get display parameters
      9         glDrawParams glParams;
     10         getDrawingParameters(glParams);
     11         //no normals shading without light!
     12         if (!MACRO_LightIsEnabled(context))
     13             glParams.showNorms = false;
     14 
     15         //can't display a SF without... a SF... and an active color scale!
     16         assert(!glParams.showSF || hasDisplayedScalarField());
     17 
     18         //standard case: list names pushing
     19         bool pushName = MACRO_DrawEntityNames(context);
     20         //special case: point names pushing (for picking)
     21         bool pushPointNames = MACRO_DrawPointNames(context);
     22         pushName |= pushPointNames;
     23 
     24         if (pushName)
     25         {
     26             //not fast at all!
     27             if (MACRO_DrawFastNamesOnly(context))
     28                 return;
     29 
     30             glPushName(getUniqueIDForDisplay());
     31             //minimal display for picking mode!
     32             glParams.showNorms = false;
     33             glParams.showColors = false;
     34             if (glParams.showSF && m_currentDisplayedScalarField->areNaNValuesShownInGrey())
     35                 glParams.showSF = false; //--> we keep it only if SF 'NaN' values are potentially hidden
     36         }
     37 
     38         // L.O.D. display
     39         DisplayDesc toDisplay(0,size());
     40         if (!pushName)
     41         {
     42             if (    context.decimateCloudOnMove
     43                 &&    toDisplay.count > context.minLODPointCount
     44                 &&    MACRO_LODActivated(context)
     45                 )
     46             {
     47                 bool skipLoD = false;
     48 
     49                 //is there a LoD structure associated yet?
     50                 if (!m_lod.isBroken())
     51                 {
     52                     if (m_lod.isNull())
     53                     {
     54                         //auto-init LoD structure
     55                         //ccProgressDialog pDlg(false,context._win ? context._win->asWidget() : 0);
     56                         initLOD(0/*&pDlg*/);
     57                     }
     58                     else
     59                     {
     60                         unsigned char maxLevel = m_lod.maxLevel();
     61                         bool underConstruction = m_lod.isUnderConstruction();
     62 
     63                         //if the cloud has less LOD levels than the minimum to display
     64                         if (maxLevel <= context.minLODLevel)
     65                         {
     66                             if (context.currentLODLevel == 0)
     67                             {
     68                                 //we can display the cloud in fill resolution
     69                                 if (!underConstruction)
     70                                 {
     71                                     //no need for LOD display
     72                                     skipLoD = true;
     73                                 }
     74                             }
     75                             else
     76                             {
     77                                 //already displayed!
     78                                 return;
     79                             }
     80                         }
     81                         else
     82                         {
     83                             if (context.currentLODLevel == 0)
     84                             {
     85                                 toDisplay.indexMap = m_lod.indexes();
     86                                 assert(toDisplay.indexMap);
     87                                 //the first time (LoD level = 0), we display all the small levels at once
     88                                 toDisplay.startIndex = 0;
     89                                 toDisplay.count = 0;
     90                                 {
     91                                     for (unsigned char l = 1; l < context.minLODLevel; ++l)
     92                                         toDisplay.count += m_lod.level(l).count;
     93                                 }
     94                                 toDisplay.endIndex = toDisplay.startIndex + toDisplay.count;
     95 
     96                                 //could we draw more points? yes (we know that lod.levels.size() > context.minLODLevel)
     97                                 context.higherLODLevelsAvailable = true;
     98                             }
     99                             else if (context.currentLODLevel < maxLevel)
    100                             {
    101                                 toDisplay = m_lod.level(context.currentLODLevel);
    102 
    103                                 if (toDisplay.count < context.currentLODStartIndex)
    104                                 {
    105                                     //nothing to do at this level
    106                                     toDisplay.indexMap = 0;
    107                                 }
    108                                 else
    109                                 {
    110                                     toDisplay.indexMap = m_lod.indexes();
    111                                     assert(toDisplay.indexMap);
    112                                     //shift current draw range
    113                                     toDisplay.startIndex += context.currentLODStartIndex;
    114                                     toDisplay.count -= context.currentLODStartIndex;
    115 
    116                                     if (toDisplay.count > MAX_POINT_COUNT_PER_LOD_RENDER_PASS)
    117                                     {
    118                                         toDisplay.count = MAX_POINT_COUNT_PER_LOD_RENDER_PASS;
    119                                         context.moreLODPointsAvailable = true;
    120                                     }
    121                                 }
    122 
    123                                 //could we draw more points at the next level?
    124                                 context.higherLODLevelsAvailable = underConstruction || (context.currentLODLevel + 1 < maxLevel);
    125                             }
    126                         }
    127                     }
    128                 }
    129 
    130                 if (!toDisplay.indexMap && !skipLoD)
    131                 {
    132                     //if we don't have a LoD map, we can only display points at level 0!
    133                     if (context.currentLODLevel != 0)
    134                     {
    135                         return;
    136                     }
    137 
    138                     if (toDisplay.count > context.minLODPointCount && context.minLODPointCount != 0)
    139                     {
    140                         toDisplay.decimStep = static_cast<int>(ceil(static_cast<float>(toDisplay.count) / context.minLODPointCount));
    141                     }
    142                 }
    143             }
    144         }
    145         //ccLog::Print(QString("Rendering %1 points starting from index %2 (LoD = %3 / PN = %4)").arg(toDisplay.count).arg(toDisplay.startIndex).arg(toDisplay.indexMap ? "yes" : "no").arg(pushName ? "yes" : "no"));
    146         bool colorMaterialEnabled = false;
    147 
    148         if (glParams.showSF || glParams.showColors)
    149         {
    150             glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
    151             glEnable(GL_COLOR_MATERIAL);
    152             colorMaterialEnabled = true;
    153         }
    154 
    155         if (glParams.showColors && isColorOverriden())
    156         {
    157             ccGL::Color3v(m_tempColor.rgb);
    158             glParams.showColors = false;
    159         }
    160         else
    161         {
    162             glColor3ubv(context.pointsDefaultCol.rgb);
    163         }
    164 
    165         //in the case we need normals (i.e. lighting)
    166         if (glParams.showNorms)
    167         {
    168             //DGM: Strangely, when Qt::renderPixmap is called, the OpenGL version is sometimes 1.0!
    169             glEnable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE));
    170             glMaterialfv(GL_FRONT_AND_BACK,    GL_AMBIENT,        CC_DEFAULT_CLOUD_AMBIENT_COLOR.rgba  );
    171             glMaterialfv(GL_FRONT_AND_BACK,    GL_SPECULAR,    CC_DEFAULT_CLOUD_SPECULAR_COLOR.rgba );
    172             glMaterialfv(GL_FRONT_AND_BACK,    GL_DIFFUSE,        CC_DEFAULT_CLOUD_DIFFUSE_COLOR.rgba  );
    173             glMaterialfv(GL_FRONT_AND_BACK,    GL_EMISSION,    CC_DEFAULT_CLOUD_EMISSION_COLOR.rgba );
    174             glMaterialf (GL_FRONT_AND_BACK,    GL_SHININESS,    CC_DEFAULT_CLOUD_SHININESS);
    175             glEnable(GL_LIGHTING);
    176 
    177             if (glParams.showSF)
    178             {
    179                 //we must get rid of lights 'color' if a scalar field is displayed!
    180                 glPushAttrib(GL_LIGHTING_BIT);
    181                 ccMaterial::MakeLightsNeutral();
    182             }
    183         }
    184 
    185         /*** DISPLAY ***/
    186 
    187         //custom point size?
    188         glPushAttrib(GL_POINT_BIT);
    189         if (m_pointSize != 0)
    190             glPointSize(static_cast<GLfloat>(m_pointSize));
    191 
    192         if (!pushPointNames) //standard "full" display
    193         {
    194             //if some points are hidden (= visibility table instantiated), we can't use display arrays :(
    195             if (isVisibilityTableInstantiated())
    196             {
    197                 assert(m_pointsVisibility);
    198                 //compressed normals set
    199                 const ccNormalVectors* compressedNormals = ccNormalVectors::GetUniqueInstance();
    200                 assert(compressedNormals);
    201 
    202                 glBegin(GL_POINTS);
    203 
    204                 for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    205                 {
    206                     //we must test each point visibility
    207                     unsigned pointIndex = toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j;
    208                     if (!m_pointsVisibility || m_pointsVisibility->getValue(pointIndex) == POINT_VISIBLE)
    209                     {
    210                         if (glParams.showSF)
    211                         {
    212                             assert(pointIndex < m_currentDisplayedScalarField->currentSize());
    213                             const ColorCompType* col = m_currentDisplayedScalarField->getValueColor(pointIndex);
    214                             //we force display of points hidden because of their scalar field value
    215                             //to be sure that the user don't miss them (during manual segmentation for instance)
    216                             glColor3ubv(col ? col : ccColor::lightGrey.rgba);
    217                         }
    218                         else if (glParams.showColors)
    219                         {
    220                             glColor3ubv(m_rgbColors->getValue(pointIndex));
    221                         }
    222                         if (glParams.showNorms)
    223                         {
    224                             ccGL::Normal3v(compressedNormals->getNormal(m_normals->getValue(pointIndex)).u);
    225                         }
    226                         ccGL::Vertex3v(m_points->getValue(pointIndex));
    227                     }
    228                 }
    229 
    230                 glEnd();
    231             }
    232             else if (glParams.showSF) //no visibility table enabled + scalar field
    233             {
    234                 assert(m_currentDisplayedScalarField);
    235 
    236                 //if some points may not be displayed, we'll have to be smarter!
    237                 bool hiddenPoints = m_currentDisplayedScalarField->mayHaveHiddenValues();
    238 
    239                 //whether VBOs are available (for faster display) or not
    240                 bool useVBOs = false;
    241                 if (!hiddenPoints && context.useVBOs && !toDisplay.indexMap) //VBOs are not compatible with LoD
    242                 {
    243                     //can't use VBOs if some points are hidden
    244                     useVBOs = updateVBOs(glParams);
    245                 }
    246 
    247                 //color ramp shader initialization
    248                 ccColorRampShader* colorRampShader = context.colorRampShader;
    249                 {
    250                     //color ramp shader is not compatible with VBOs (and VBOs are faster)
    251                     if (useVBOs)
    252                     {
    253                         colorRampShader = 0;
    254                     }
    255                     //FIXME: color ramp shader doesn't support log scale yet!
    256                     if (m_currentDisplayedScalarField->logScale())
    257                     {
    258                         colorRampShader = 0;
    259                     }
    260                 }
    261 
    262                 const ccScalarField::Range& sfDisplayRange = m_currentDisplayedScalarField->displayRange();
    263                 const ccScalarField::Range& sfSaturationRange = m_currentDisplayedScalarField->saturationRange();
    264 
    265                 if (colorRampShader)
    266                 {
    267                     //max available space for frament's shader uniforms
    268                     GLint maxBytes = 0;
    269                     glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,&maxBytes);
    270                     GLint maxComponents = (maxBytes>>2)-4; //leave space for the other uniforms!
    271                     unsigned steps = m_currentDisplayedScalarField->getColorRampSteps();
    272                     assert(steps != 0);
    273 
    274                     if (steps > CC_MAX_SHADER_COLOR_RAMP_SIZE || maxComponents < (GLint)steps)
    275                     {
    276                         ccLog::WarningDebug("Color ramp steps exceed shader limits!");
    277                         colorRampShader = 0;
    278                     }
    279                     else
    280                     {
    281                         float sfMinSatRel = 0.0f;
    282                         float sfMaxSatRel = 1.0f;
    283                         if (!m_currentDisplayedScalarField->symmetricalScale())
    284                         {
    285                             sfMinSatRel = GetNormalizedValue(sfSaturationRange.start(),sfDisplayRange);    //doesn't need to be between 0 and 1!
    286                             sfMaxSatRel = GetNormalizedValue(sfSaturationRange.stop(),sfDisplayRange);    //doesn't need to be between 0 and 1!
    287                         }
    288                         else
    289                         {
    290                             //we can only handle 'maximum' saturation
    291                             sfMinSatRel = GetSymmetricalNormalizedValue(-sfSaturationRange.stop(),sfSaturationRange);
    292                             sfMaxSatRel = GetSymmetricalNormalizedValue(sfSaturationRange.stop(),sfSaturationRange);
    293                             //we'll have to handle the 'minimum' saturation manually!
    294                         }
    295 
    296                         const ccColorScale::Shared& colorScale = m_currentDisplayedScalarField->getColorScale();
    297                         assert(colorScale);
    298 
    299                         colorRampShader->start();
    300                         if (!colorRampShader->setup(sfMinSatRel, sfMaxSatRel, steps, colorScale))
    301                         {
    302                             //An error occurred during shader initialization?
    303                             ccLog::WarningDebug("Failed to init ColorRamp shader!");
    304                             colorRampShader->stop();
    305                             colorRampShader = 0;
    306                         }
    307                         else if (glParams.showNorms)
    308                         {
    309                             //we must get rid of lights material (other than ambient) for the red and green fields
    310                             glPushAttrib(GL_LIGHTING_BIT);
    311 
    312                             //we use the ambient light to pass the scalar value (and 'grayed' marker) without any
    313                             //modification from the GPU pipeline, even if normals are enabled!
    314                             glDisable(GL_COLOR_MATERIAL);
    315                             glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
    316                             glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
    317                             glEnable(GL_COLOR_MATERIAL);
    318 
    319                             GLint maxLightCount;
    320                             glGetIntegerv(GL_MAX_LIGHTS,&maxLightCount);
    321                             for (GLint i=0; i<maxLightCount; ++i)
    322                             {
    323                                 if (glIsEnabled(GL_LIGHT0+i))
    324                                 {
    325                                     float diffuse[4],ambiant[4],specular[4];
    326 
    327                                     glGetLightfv(GL_LIGHT0+i,GL_AMBIENT,ambiant);
    328                                     glGetLightfv(GL_LIGHT0+i,GL_DIFFUSE,diffuse);
    329                                     glGetLightfv(GL_LIGHT0+i,GL_SPECULAR,specular);
    330 
    331                                     ambiant[0]  = ambiant[1]  = 1.0f;
    332                                     diffuse[0]  = diffuse[1]  = 0.0f;
    333                                     specular[0] = specular[1] = 0.0f;
    334 
    335                                     glLightfv(GL_LIGHT0+i,GL_DIFFUSE,diffuse);
    336                                     glLightfv(GL_LIGHT0+i,GL_AMBIENT,ambiant);
    337                                     glLightfv(GL_LIGHT0+i,GL_SPECULAR,specular);
    338                                 }
    339                             }
    340                         }
    341                     }
    342                 }
    343 
    344                 //if all points should be displayed (fastest case)
    345                 if (!hiddenPoints)
    346                 {
    347                     glEnableClientState(GL_VERTEX_ARRAY);
    348                     glEnableClientState(GL_COLOR_ARRAY);
    349                     if (glParams.showNorms)
    350                         glEnableClientState(GL_NORMAL_ARRAY);
    351 
    352                     if (toDisplay.indexMap) //LoD display
    353                     {
    354                         unsigned s = toDisplay.startIndex;
    355                         while (s < toDisplay.endIndex)
    356                         {
    357                             unsigned count = std::min(MAX_POINT_COUNT_PER_LOD_RENDER_PASS,toDisplay.endIndex-s);
    358                             unsigned e = s+count;
    359 
    360                             //points
    361                             glLODChunkVertexPointer(*toDisplay.indexMap,s,e);
    362                             //normals
    363                             if (glParams.showNorms)
    364                                 glLODChunkNormalPointer(*toDisplay.indexMap,s,e);
    365                             //SF colors
    366                             if (colorRampShader)
    367                             {
    368                                 float* _sfColors = s_rgbBuffer3f;
    369                                 bool symScale = m_currentDisplayedScalarField->symmetricalScale();
    370                                 for (unsigned j=s; j<e; j++,_sfColors+=3)
    371                                 {
    372                                     unsigned pointIndex = toDisplay.indexMap->getValue(j);
    373                                     ScalarType sfVal = m_currentDisplayedScalarField->getValue(pointIndex);
    374                                     //normalized sf value
    375                                     _sfColors[0] = symScale ? GetSymmetricalNormalizedValue(sfVal,sfSaturationRange) : GetNormalizedValue(sfVal,sfDisplayRange);
    376                                     //flag: whether point is grayed out or not (NaN values are also rejected!)
    377                                     _sfColors[1] = sfDisplayRange.isInRange(sfVal) ? 1.0f : 0.0f;
    378                                     //reference value (to get the true lighting value)
    379                                     _sfColors[2] = 1.0f;
    380                                 }
    381                                 glColorPointer(3,GL_FLOAT,0,s_rgbBuffer3f);
    382                             }
    383                             else
    384                             {
    385                                 glLODChunkSFPointer(*toDisplay.indexMap,s,e);
    386                             }
    387 
    388                             glDrawArrays(GL_POINTS,0,count);
    389 
    390                             s = e;
    391                         }
    392                     }
    393                     else
    394                     {
    395                         unsigned chunks = m_points->chunksCount();
    396                         for (unsigned k=0; k<chunks; ++k)
    397                         {
    398                             unsigned chunkSize = m_points->chunkSize(k);
    399 
    400                             //points
    401                             glChunkVertexPointer(k,toDisplay.decimStep,useVBOs);
    402                             //normals
    403                             if (glParams.showNorms)
    404                                 glChunkNormalPointer(k,toDisplay.decimStep,useVBOs);
    405                             //SF colors
    406                             if (colorRampShader)
    407                             {
    408                                 ScalarType* _sf = m_currentDisplayedScalarField->chunkStartPtr(k);
    409                                 float* _sfColors = s_rgbBuffer3f;
    410                                 bool symScale = m_currentDisplayedScalarField->symmetricalScale();
    411                                 for (unsigned j=0; j<chunkSize; j+=toDisplay.decimStep,_sf+=toDisplay.decimStep,_sfColors+=3)
    412                                 {
    413                                     //normalized sf value
    414                                     _sfColors[0] = symScale ? GetSymmetricalNormalizedValue(*_sf,sfSaturationRange) : GetNormalizedValue(*_sf,sfDisplayRange);
    415                                     //flag: whether point is grayed out or not (NaN values are also rejected!)
    416                                     _sfColors[1] = sfDisplayRange.isInRange(*_sf) ? 1.0f : 0.0f;
    417                                     //reference value (to get the true lighting value)
    418                                     _sfColors[2] = 1.0f;
    419                                 }
    420                                 glColorPointer(3,GL_FLOAT,0,s_rgbBuffer3f);
    421                             }
    422                             else
    423                             {
    424                                 glChunkSFPointer(k,toDisplay.decimStep,useVBOs);
    425                             }
    426 
    427                             if (toDisplay.decimStep > 1)
    428                                 chunkSize = static_cast<unsigned>( floor(static_cast<float>(chunkSize)/toDisplay.decimStep) );
    429                             glDrawArrays(GL_POINTS,0,chunkSize);
    430                         }
    431                     }
    432 
    433                     if (glParams.showNorms)
    434                         glDisableClientState(GL_NORMAL_ARRAY);
    435                     glDisableClientState(GL_COLOR_ARRAY);
    436                     glDisableClientState(GL_VERTEX_ARRAY);
    437                 }
    438                 else //potentially hidden points
    439                 {
    440                     //compressed normals set
    441                     const ccNormalVectors* compressedNormals = ccNormalVectors::GetUniqueInstance();
    442                     assert(compressedNormals);
    443 
    444                     glBegin(GL_POINTS);
    445 
    446                     if (glParams.showNorms) //with normals (slowest case!)
    447                     {
    448                         if (colorRampShader)
    449                         {
    450                             if (!m_currentDisplayedScalarField->symmetricalScale())
    451                             {
    452                                 for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    453                                 {
    454                                     unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    455                                     assert(pointIndex < m_currentDisplayedScalarField->currentSize());
    456                                     const ScalarType sf = m_currentDisplayedScalarField->getValue(pointIndex);
    457                                     if (sfDisplayRange.isInRange(sf)) //NaN values are rejected
    458                                     {
    459                                         glColor3f(GetNormalizedValue(sf,sfDisplayRange),1.0f,1.0f);
    460                                         ccGL::Normal3v(compressedNormals->getNormal(m_normals->getValue(pointIndex)).u);
    461                                         ccGL::Vertex3v(m_points->getValue(pointIndex));
    462                                     }
    463                                 }
    464                             }
    465                             else
    466                             {
    467                                 for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    468                                 {
    469                                     unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    470                                     assert(pointIndex < m_currentDisplayedScalarField->currentSize());
    471                                     const ScalarType sf = m_currentDisplayedScalarField->getValue(pointIndex);
    472                                     if (sfDisplayRange.isInRange(sf)) //NaN values are rejected
    473                                     {
    474                                         glColor3f(GetSymmetricalNormalizedValue(sf,sfSaturationRange),1.0f,1.0f);
    475                                         ccGL::Normal3v(compressedNormals->getNormal(m_normals->getValue(pointIndex)).u);
    476                                         ccGL::Vertex3v(m_points->getValue(pointIndex));
    477                                     }
    478                                 }
    479                             }
    480                         }
    481                         else
    482                         {
    483                             for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    484                             {
    485                                 unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    486                                 assert(pointIndex < m_currentDisplayedScalarField->currentSize());
    487                                 const ColorCompType* col = m_currentDisplayedScalarField->getValueColor(pointIndex);
    488                                 if (col)
    489                                 {
    490                                     glColor3ubv(col);
    491                                     ccGL::Normal3v(compressedNormals->getNormal(m_normals->getValue(pointIndex)).u);
    492                                     ccGL::Vertex3v(m_points->getValue(pointIndex));
    493                                 }
    494                             }
    495                         }
    496                     }
    497                     else //potentially hidden points without normals (a bit faster)
    498                     {
    499                         if (colorRampShader)
    500                         {
    501                             if (!m_currentDisplayedScalarField->symmetricalScale())
    502                             {
    503                                 for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    504                                 {
    505                                     unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    506                                     assert(pointIndex < m_currentDisplayedScalarField->currentSize());
    507                                     const ScalarType sf = m_currentDisplayedScalarField->getValue(pointIndex);
    508                                     if (sfDisplayRange.isInRange(sf)) //NaN values are rejected
    509                                     {
    510                                         glColor3f(GetNormalizedValue(sf,sfDisplayRange),1.0f,1.0f);
    511                                         ccGL::Vertex3v(m_points->getValue(pointIndex));
    512                                     }
    513                                 }
    514                             }
    515                             else
    516                             {
    517                                 for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    518                                 {
    519                                     unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    520                                     assert(pointIndex < m_currentDisplayedScalarField->currentSize());
    521                                     const ScalarType sf = m_currentDisplayedScalarField->getValue(pointIndex);
    522                                     if (sfDisplayRange.isInRange(sf)) //NaN values are rejected
    523                                     {
    524                                         glColor3f(GetSymmetricalNormalizedValue(sf,sfSaturationRange),1.0f,1.0f);
    525                                         ccGL::Vertex3v(m_points->getValue(pointIndex));
    526                                     }
    527                                 }
    528                             }
    529                         }
    530                         else
    531                         {
    532                             for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    533                             {
    534                                 unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    535                                 assert(pointIndex < m_currentDisplayedScalarField->currentSize());
    536                                 const ColorCompType* col = m_currentDisplayedScalarField->getValueColor(pointIndex);
    537                                 if (col)
    538                                 {
    539                                     glColor3ubv(col);
    540                                     ccGL::Vertex3v(m_points->getValue(pointIndex));
    541                                 }
    542                             }
    543                         }
    544                     }
    545                     glEnd();
    546                 }
    547 
    548                 if (colorRampShader)
    549                 {
    550                     colorRampShader->stop();
    551 
    552                     if (glParams.showNorms)
    553                         glPopAttrib(); //GL_LIGHTING_BIT
    554                 }
    555             }
    556             else //no visibility table enabled, no scalar field
    557             {
    558                 bool useVBOs = context.useVBOs && !toDisplay.indexMap ? updateVBOs(glParams) : false; //VBOs are not compatible with LoD
    559 
    560                 unsigned chunks = m_points->chunksCount();
    561 
    562                 glEnableClientState(GL_VERTEX_ARRAY);
    563                 if (glParams.showNorms)
    564                     glEnableClientState(GL_NORMAL_ARRAY);
    565                 if (glParams.showColors)
    566                     glEnableClientState(GL_COLOR_ARRAY);
    567 
    568                 if (toDisplay.indexMap) //LoD display
    569                 {
    570                     unsigned s = toDisplay.startIndex;
    571                     while (s < toDisplay.endIndex)
    572                     {
    573                         unsigned count = std::min(MAX_POINT_COUNT_PER_LOD_RENDER_PASS,toDisplay.endIndex-s);
    574                         unsigned e = s+count;
    575 
    576                         //points
    577                         glLODChunkVertexPointer(*toDisplay.indexMap,s,e);
    578                         //normals
    579                         if (glParams.showNorms)
    580                             glLODChunkNormalPointer(*toDisplay.indexMap,s,e);
    581                         //colors
    582                         if (glParams.showColors)
    583                             glLODChunkColorPointer(*toDisplay.indexMap,s,e);
    584 
    585                         glDrawArrays(GL_POINTS,0,count);
    586                         s = e;
    587                     }
    588                 }
    589                 else
    590                 {
    591                     for (unsigned k=0; k<chunks; ++k)
    592                     {
    593                         unsigned chunkSize = m_points->chunkSize(k);
    594 
    595                         //points
    596                         glChunkVertexPointer(k,toDisplay.decimStep,useVBOs);
    597                         //normals
    598                         if (glParams.showNorms)
    599                             glChunkNormalPointer(k,toDisplay.decimStep,useVBOs);
    600                         //colors
    601                         if (glParams.showColors)
    602                             glChunkColorPointer(k,toDisplay.decimStep,useVBOs);
    603 
    604                         if (toDisplay.decimStep > 1)
    605                             chunkSize = static_cast<unsigned>(floor(static_cast<float>(chunkSize)/toDisplay.decimStep));
    606                         glDrawArrays(GL_POINTS,0,chunkSize);
    607                     }
    608                 }
    609 
    610                 glDisableClientState(GL_VERTEX_ARRAY);
    611                 if (glParams.showNorms)
    612                     glDisableClientState(GL_NORMAL_ARRAY);
    613                 if (glParams.showColors)
    614                     glDisableClientState(GL_COLOR_ARRAY);
    615             }
    616         }
    617         else //special case: point names pushing (for picking) --> no need for colors, normals, etc.
    618         {
    619             glPushName(0);
    620             //however we must take hidden points into account!
    621             if (isVisibilityTableInstantiated())
    622             {
    623                 for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    624                 {
    625                     unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    626                     if (m_pointsVisibility->getValue(j) == POINT_VISIBLE)
    627                     {
    628                         glLoadName(pointIndex);
    629                         glBegin(GL_POINTS);
    630                         ccGL::Vertex3v(m_points->getValue(pointIndex));
    631                         glEnd();
    632                     }
    633                 }
    634             }
    635             else //no visibility table instantiated...
    636             {
    637                 //... but potentially points with NAN SF values (also hidden!)
    638                 bool hiddenPoints = false;
    639                 if (glParams.showSF)
    640                 {
    641                     assert(m_currentDisplayedScalarField);
    642                     hiddenPoints = m_currentDisplayedScalarField->mayHaveHiddenValues() && m_currentDisplayedScalarField->getColorScale();
    643                 }
    644                 
    645                 if (hiddenPoints) //potentially hidden points
    646                 {
    647                     for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    648                     {
    649                         unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    650                         //we must generate the synthetic "color" of each point
    651                         const ColorCompType* col = getPointScalarValueColor(pointIndex);
    652                         if (col)
    653                         {
    654                             glLoadName(pointIndex);
    655                             glBegin(GL_POINTS);
    656                             ccGL::Vertex3v(m_points->getValue(pointIndex));
    657                             glEnd();
    658                         }
    659                     }
    660                 }
    661                 else
    662                 {
    663                     //no hidden point
    664                     for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
    665                     {
    666                         unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
    667                         glLoadName(pointIndex);
    668                         glBegin(GL_POINTS);
    669                         ccGL::Vertex3v(m_points->getValue(pointIndex));
    670                         glEnd();
    671                     }
    672                 }
    673             }
    674 
    675             //glEnd();
    676             glPopName();
    677         }
    678 
    679         /*** END DISPLAY ***/
    680 
    681         glPopAttrib(); //GL_POINT_BIT
    682 
    683         if (colorMaterialEnabled)
    684             glDisable(GL_COLOR_MATERIAL);
    685 
    686         //we can now switch the light off
    687         if (glParams.showNorms)
    688         {
    689             if (glParams.showSF)
    690                 glPopAttrib(); //GL_LIGHTING_BIT
    691 
    692             glDisable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE));
    693             glDisable(GL_LIGHTING);
    694         }
    695 
    696         if (pushName)
    697             glPopName();
    698     }
    699     else if (MACRO_Draw2D(context))
    700     {
    701         if (MACRO_Foreground(context) && !context.sfColorScaleToDisplay)
    702         {
    703             if (sfColorScaleShown() && sfShown())
    704             {
    705                 //drawScale(context);
    706                 addColorRampInfo(context);
    707             }
    708         }
    709     }
    710 }
    ccPointCloud::drawMeOnly
  • 相关阅读:
    软退回和硬退回的区别和联系
    十家国内知名的EDM服务提供商
    2018年第一记:EDM策略分享-EDM营销的策略分析
    分享几个目前研究出来的邮件不进垃圾箱技巧
    如何快速增加邮件列表用户数量
    EDM数据营销之电商篇| 六大事务性邮件,环环相扣打造极致用户体验!
    如何整合线上和线下营销进行深度交融
    品牌logo在EDM数据营销中的运用
    2017年内容营销如何提高ROI转化率
    营销必读:2017移动应用的五大营销趋势
  • 原文地址:https://www.cnblogs.com/yhlx125/p/6020857.html
Copyright © 2011-2022 走看看