[CC]LOD技术「建议收藏」

[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项目下。

[CC]LOD技术「建议收藏」
[CC]LOD技术「建议收藏」

  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方法:

[CC]LOD技术「建议收藏」
[CC]LOD技术「建议收藏」

  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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108809.html原文链接:https://javaforall.net

(0)
上一篇 2022年2月22日 上午9:00
下一篇 2022年2月22日 上午10:00


相关推荐

  • 怎么开启小米Note 3的root超级权限

    怎么开启小米Note 3的root超级权限小米 Note3 有没有办法获得 Root 权限 我们都知道 android 设备有 Root 权限 一旦手机获得 root 相关权限 就能够实现更好的功能 举个栗子我们单位的营销部门的妹纸 使用一些营销工具都需要在 Root 权限下工作 如果手机无能获的 root 的权限 就没办法正常使用相关的功能 小米 Note3 开发版系统版本本身拥有 root 权限管理工具 但是如果你使用的是小米 Note3 稳定版 建议可以先将小

    2026年3月17日
    2
  • php中利用header设置content-type和常见文件类型的content-type

    php中利用header设置content-type和常见文件类型的content-typephp中利用header设置content-type和常见文件类型的content-type在PHP中可以通过header函数来发送头信息,还可以设置文件的content-type,下面整理了一些常见文件类型对于的content-type值。部分header头参考:http://www.lai18.com/content/433566.html//aut

    2022年8月24日
    6
  • 快慢指针java

    快慢指针java1 中间值的问题 定义两个指针 fastslow 最开始的时候都指向头节点 当块指针指向为空的时候 就可以结束了 慢指针指向的节点就是中间值 2 链表有环的问题定义两个指针 fastslow 最开始的时候都指向头节点 快指针的速度是慢指针速度的两倍 当出现快指针指向同一个元素 节点 的时候 就说明这个时候的链表是有环的 3 有环量链表的入口问题 当快慢指针相遇的时候 我们可以判断链表中是有环的 这个时候重

    2026年2月9日
    2
  • ECharts 饼图颜色设置教程 – 4 种方式设置饼图颜色

    ECharts 饼图颜色设置教程 – 4 种方式设置饼图颜色ECharts 饼状图中的每个扇形颜色其实都可以自定义或者随机显示颜色 比如 X 轴是各销售渠道名 那么你可以需要使用全局统一的识别色彩 那么就需要指定每个扇面的颜色 本文讲解 4 种配置修改 ECharts 饼图颜色的方法

    2026年3月17日
    2
  • 六大算法之动态规划_动态规划求解最大子数组

    六大算法之动态规划_动态规划求解最大子数组一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?示例 1:输入:m = 3, n = 7输出:28示例 2:输入:m = 3, n = 2输出:3解释:从左上角开始,总共有 3 条路径可以到达右下角。向右 -> 向下 -> 向下向下 -> 向下 -> 向右向下 -> 向右 -&gt

    2022年8月9日
    10
  • Google Earth Engine学习笔记——介绍和入门

    Google Earth Engine学习笔记——介绍和入门   最近接触GoogleEarthEngine,觉得很好玩,也很有应用前景,关键是免费的地理计算云平台。所以想认真学习下,学习过程中作些小的总结和记录,资料来源均为网络或GoogleEarthEngineAPI指南,今天先讲讲入门的知识。1、GoogleEarthEngine介绍   GoogleEarthEngine是Google提供的对大量全球尺度地球科学资料(尤其是…

    2026年1月24日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号