[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
原文地址:https://www.cnblogs.com/yhlx125/p/6020857.html