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*

 void ccHObject::draw(CC_DRAW_CONTEXT& context)
{
if (!isEnabled())
return; //are we currently drawing objects in 2D or 3D?
bool draw3D = MACRO_Draw3D(context); //the entity must be either visible or selected, and of course it should be displayed in this context
bool drawInThisContext = ((m_visible || m_selected) && m_currentDisplay == context._win); //no need to display anything but clouds and meshes in "element picking mode"
drawInThisContext &= ( ( !MACRO_DrawPointNames(context) || isKindOf(CC_TYPES::POINT_CLOUD) ) ||
( !MACRO_DrawTriangleNames(context) || isKindOf(CC_TYPES::MESH) )); if (draw3D)
{
//apply 3D 'temporary' transformation (for display only)
if (m_glTransEnabled)
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(m_glTrans.data());
} if ( context.decimateCloudOnMove //LOD for clouds is enabled?
&& context.currentLODLevel >= context.minLODLevel //and we are currently rendering higher levels?
)
{
//only for real clouds
drawInThisContext &= isA(CC_TYPES::POINT_CLOUD);
}
} //draw entity
if (m_visible && drawInThisContext)
{
if (( !m_selected || !MACRO_SkipSelected(context) ) &&
( m_selected || !MACRO_SkipUnselected(context) ))
{
//apply default color (in case of)
ccGL::Color3v(context.pointsDefaultCol.rgb); drawMeOnly(context); //draw name in 3D (we display it in the 2D foreground layer in fact!)
if (m_showNameIn3D && MACRO_Draw2D(context) && MACRO_Foreground(context) && !MACRO_DrawNames(context))
drawNameIn3D(context);
}
} //draw entity's children
for (Container::iterator it = m_children.begin(); it != m_children.end(); ++it)
(*it)->draw(context); //if the entity is currently selected, we draw its bounding-box
if (m_selected && draw3D && drawInThisContext && !MACRO_DrawNames(context) && context.currentLODLevel == )
{
drawBB(context.bbDefaultCol);
} if (draw3D && m_glTransEnabled)
glPopMatrix();
}

点云八叉树

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

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

 /*** RENDERING METHODS ***/

 void ccOctree::RenderOctreeAs(  CC_OCTREE_DISPLAY_TYPE octreeDisplayType,
ccOctree* theOctree,
unsigned char level,
ccGenericPointCloud* theAssociatedCloud,
int &octreeGLListID,
bool updateOctreeGLDisplay)
{
if (!theOctree || !theAssociatedCloud)
return; glPushAttrib(GL_LIGHTING_BIT); if (octreeDisplayType == WIRE)
{
//cet affichage demande trop de memoire pour le stocker sous forme de liste OpenGL
//donc on doit le generer dynamiquement glDisable(GL_LIGHTING); //au cas où la lumiere soit allumee
ccGL::Color3v(ccColor::green.rgba); void* additionalParameters[] = { theOctree->m_frustrumIntersector };
theOctree->executeFunctionForAllCellsAtLevel( level,
&DrawCellAsABox,
additionalParameters);
}
else
{
glDrawParams glParams;
theAssociatedCloud->getDrawingParameters(glParams); if (glParams.showNorms)
{
//DGM: Strangely, when Qt::renderPixmap is called, the OpenGL version is sometimes 1.0!
glEnable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE));
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, CC_DEFAULT_CLOUD_AMBIENT_COLOR.rgba );
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, CC_DEFAULT_CLOUD_SPECULAR_COLOR.rgba );
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, CC_DEFAULT_CLOUD_DIFFUSE_COLOR.rgba );
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, CC_DEFAULT_CLOUD_EMISSION_COLOR.rgba );
glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, CC_DEFAULT_CLOUD_SHININESS);
glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
} if (!glParams.showColors)
ccGL::Color3v(ccColor::white.rgba); if (updateOctreeGLDisplay || octreeGLListID < )
{
if (octreeGLListID < )
octreeGLListID = glGenLists();
else if (glIsList(octreeGLListID))
glDeleteLists(octreeGLListID,);
glNewList(octreeGLListID,GL_COMPILE); if (octreeDisplayType == MEAN_POINTS)
{
void* additionalParameters[] = { reinterpret_cast<void*>(&glParams),
reinterpret_cast<void*>(theAssociatedCloud),
}; glBegin(GL_POINTS);
theOctree->executeFunctionForAllCellsAtLevel( level,
&DrawCellAsAPoint,
additionalParameters);
glEnd();
}
else
{
//by default we use a box as primitive
PointCoordinateType cs = theOctree->getCellSize(level);
CCVector3 dims(cs,cs,cs);
ccBox box(dims);
box.showColors(glParams.showColors || glParams.showSF);
box.showNormals(glParams.showNorms); //trick: replace all normal indexes so that they point on the first one
{
if (box.arePerTriangleNormalsEnabled())
for (unsigned i=;i<box.size();++i)
box.setTriangleNormalIndexes(i,,,);
} //fake context
CC_DRAW_CONTEXT context;
context.flags = CC_DRAW_3D | CC_DRAW_FOREGROUND| CC_LIGHT_ENABLED;
context._win = ; void* additionalParameters[] = { reinterpret_cast<void*>(&glParams),
reinterpret_cast<void*>(theAssociatedCloud),
reinterpret_cast<void*>(&box),
reinterpret_cast<void*>(&context)
}; theOctree->executeFunctionForAllCellsAtLevel( level,
&DrawCellAsAPrimitive,
additionalParameters);
} glEndList();
} glCallList(octreeGLListID); if (glParams.showNorms)
{
glDisable(GL_COLOR_MATERIAL);
glDisable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE));
glDisable(GL_LIGHTING);
}
} glPopAttrib();
}

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的一些方法

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

以下为drawMeOnly方法:

 void ccPointCloud::drawMeOnly(CC_DRAW_CONTEXT& context)
{
if (!m_points->isAllocated())
return; if (MACRO_Draw3D(context))
{
//we get display parameters
glDrawParams glParams;
getDrawingParameters(glParams);
//no normals shading without light!
if (!MACRO_LightIsEnabled(context))
glParams.showNorms = false; //can't display a SF without... a SF... and an active color scale!
assert(!glParams.showSF || hasDisplayedScalarField()); //standard case: list names pushing
bool pushName = MACRO_DrawEntityNames(context);
//special case: point names pushing (for picking)
bool pushPointNames = MACRO_DrawPointNames(context);
pushName |= pushPointNames; if (pushName)
{
//not fast at all!
if (MACRO_DrawFastNamesOnly(context))
return; glPushName(getUniqueIDForDisplay());
//minimal display for picking mode!
glParams.showNorms = false;
glParams.showColors = false;
if (glParams.showSF && m_currentDisplayedScalarField->areNaNValuesShownInGrey())
glParams.showSF = false; //--> we keep it only if SF 'NaN' values are potentially hidden
} // L.O.D. display
DisplayDesc toDisplay(,size());
if (!pushName)
{
if ( context.decimateCloudOnMove
&& toDisplay.count > context.minLODPointCount
&& MACRO_LODActivated(context)
)
{
bool skipLoD = false; //is there a LoD structure associated yet?
if (!m_lod.isBroken())
{
if (m_lod.isNull())
{
//auto-init LoD structure
//ccProgressDialog pDlg(false,context._win ? context._win->asWidget() : 0);
initLOD(/*&pDlg*/);
}
else
{
unsigned char maxLevel = m_lod.maxLevel();
bool underConstruction = m_lod.isUnderConstruction(); //if the cloud has less LOD levels than the minimum to display
if (maxLevel <= context.minLODLevel)
{
if (context.currentLODLevel == )
{
//we can display the cloud in fill resolution
if (!underConstruction)
{
//no need for LOD display
skipLoD = true;
}
}
else
{
//already displayed!
return;
}
}
else
{
if (context.currentLODLevel == )
{
toDisplay.indexMap = m_lod.indexes();
assert(toDisplay.indexMap);
//the first time (LoD level = 0), we display all the small levels at once
toDisplay.startIndex = ;
toDisplay.count = ;
{
for (unsigned char l = ; l < context.minLODLevel; ++l)
toDisplay.count += m_lod.level(l).count;
}
toDisplay.endIndex = toDisplay.startIndex + toDisplay.count; //could we draw more points? yes (we know that lod.levels.size() > context.minLODLevel)
context.higherLODLevelsAvailable = true;
}
else if (context.currentLODLevel < maxLevel)
{
toDisplay = m_lod.level(context.currentLODLevel); if (toDisplay.count < context.currentLODStartIndex)
{
//nothing to do at this level
toDisplay.indexMap = ;
}
else
{
toDisplay.indexMap = m_lod.indexes();
assert(toDisplay.indexMap);
//shift current draw range
toDisplay.startIndex += context.currentLODStartIndex;
toDisplay.count -= context.currentLODStartIndex; if (toDisplay.count > MAX_POINT_COUNT_PER_LOD_RENDER_PASS)
{
toDisplay.count = MAX_POINT_COUNT_PER_LOD_RENDER_PASS;
context.moreLODPointsAvailable = true;
}
} //could we draw more points at the next level?
context.higherLODLevelsAvailable = underConstruction || (context.currentLODLevel + < maxLevel);
}
}
}
} if (!toDisplay.indexMap && !skipLoD)
{
//if we don't have a LoD map, we can only display points at level 0!
if (context.currentLODLevel != )
{
return;
} if (toDisplay.count > context.minLODPointCount && context.minLODPointCount != )
{
toDisplay.decimStep = static_cast<int>(ceil(static_cast<float>(toDisplay.count) / context.minLODPointCount));
}
}
}
}
//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"));
bool colorMaterialEnabled = false; if (glParams.showSF || glParams.showColors)
{
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
colorMaterialEnabled = true;
} if (glParams.showColors && isColorOverriden())
{
ccGL::Color3v(m_tempColor.rgb);
glParams.showColors = false;
}
else
{
glColor3ubv(context.pointsDefaultCol.rgb);
} //in the case we need normals (i.e. lighting)
if (glParams.showNorms)
{
//DGM: Strangely, when Qt::renderPixmap is called, the OpenGL version is sometimes 1.0!
glEnable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE));
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, CC_DEFAULT_CLOUD_AMBIENT_COLOR.rgba );
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, CC_DEFAULT_CLOUD_SPECULAR_COLOR.rgba );
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, CC_DEFAULT_CLOUD_DIFFUSE_COLOR.rgba );
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, CC_DEFAULT_CLOUD_EMISSION_COLOR.rgba );
glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, CC_DEFAULT_CLOUD_SHININESS);
glEnable(GL_LIGHTING); if (glParams.showSF)
{
//we must get rid of lights 'color' if a scalar field is displayed!
glPushAttrib(GL_LIGHTING_BIT);
ccMaterial::MakeLightsNeutral();
}
} /*** DISPLAY ***/ //custom point size?
glPushAttrib(GL_POINT_BIT);
if (m_pointSize != )
glPointSize(static_cast<GLfloat>(m_pointSize)); if (!pushPointNames) //standard "full" display
{
//if some points are hidden (= visibility table instantiated), we can't use display arrays :(
if (isVisibilityTableInstantiated())
{
assert(m_pointsVisibility);
//compressed normals set
const ccNormalVectors* compressedNormals = ccNormalVectors::GetUniqueInstance();
assert(compressedNormals); glBegin(GL_POINTS); for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
//we must test each point visibility
unsigned pointIndex = toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j;
if (!m_pointsVisibility || m_pointsVisibility->getValue(pointIndex) == POINT_VISIBLE)
{
if (glParams.showSF)
{
assert(pointIndex < m_currentDisplayedScalarField->currentSize());
const ColorCompType* col = m_currentDisplayedScalarField->getValueColor(pointIndex);
//we force display of points hidden because of their scalar field value
//to be sure that the user don't miss them (during manual segmentation for instance)
glColor3ubv(col ? col : ccColor::lightGrey.rgba);
}
else if (glParams.showColors)
{
glColor3ubv(m_rgbColors->getValue(pointIndex));
}
if (glParams.showNorms)
{
ccGL::Normal3v(compressedNormals->getNormal(m_normals->getValue(pointIndex)).u);
}
ccGL::Vertex3v(m_points->getValue(pointIndex));
}
} glEnd();
}
else if (glParams.showSF) //no visibility table enabled + scalar field
{
assert(m_currentDisplayedScalarField); //if some points may not be displayed, we'll have to be smarter!
bool hiddenPoints = m_currentDisplayedScalarField->mayHaveHiddenValues(); //whether VBOs are available (for faster display) or not
bool useVBOs = false;
if (!hiddenPoints && context.useVBOs && !toDisplay.indexMap) //VBOs are not compatible with LoD
{
//can't use VBOs if some points are hidden
useVBOs = updateVBOs(glParams);
} //color ramp shader initialization
ccColorRampShader* colorRampShader = context.colorRampShader;
{
//color ramp shader is not compatible with VBOs (and VBOs are faster)
if (useVBOs)
{
colorRampShader = ;
}
//FIXME: color ramp shader doesn't support log scale yet!
if (m_currentDisplayedScalarField->logScale())
{
colorRampShader = ;
}
} const ccScalarField::Range& sfDisplayRange = m_currentDisplayedScalarField->displayRange();
const ccScalarField::Range& sfSaturationRange = m_currentDisplayedScalarField->saturationRange(); if (colorRampShader)
{
//max available space for frament's shader uniforms
GLint maxBytes = ;
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,&maxBytes);
GLint maxComponents = (maxBytes>>)-; //leave space for the other uniforms!
unsigned steps = m_currentDisplayedScalarField->getColorRampSteps();
assert(steps != ); if (steps > CC_MAX_SHADER_COLOR_RAMP_SIZE || maxComponents < (GLint)steps)
{
ccLog::WarningDebug("Color ramp steps exceed shader limits!");
colorRampShader = ;
}
else
{
float sfMinSatRel = 0.0f;
float sfMaxSatRel = 1.0f;
if (!m_currentDisplayedScalarField->symmetricalScale())
{
sfMinSatRel = GetNormalizedValue(sfSaturationRange.start(),sfDisplayRange); //doesn't need to be between 0 and 1!
sfMaxSatRel = GetNormalizedValue(sfSaturationRange.stop(),sfDisplayRange); //doesn't need to be between 0 and 1!
}
else
{
//we can only handle 'maximum' saturation
sfMinSatRel = GetSymmetricalNormalizedValue(-sfSaturationRange.stop(),sfSaturationRange);
sfMaxSatRel = GetSymmetricalNormalizedValue(sfSaturationRange.stop(),sfSaturationRange);
//we'll have to handle the 'minimum' saturation manually!
} const ccColorScale::Shared& colorScale = m_currentDisplayedScalarField->getColorScale();
assert(colorScale); colorRampShader->start();
if (!colorRampShader->setup(sfMinSatRel, sfMaxSatRel, steps, colorScale))
{
//An error occurred during shader initialization?
ccLog::WarningDebug("Failed to init ColorRamp shader!");
colorRampShader->stop();
colorRampShader = ;
}
else if (glParams.showNorms)
{
//we must get rid of lights material (other than ambient) for the red and green fields
glPushAttrib(GL_LIGHTING_BIT); //we use the ambient light to pass the scalar value (and 'grayed' marker) without any
//modification from the GPU pipeline, even if normals are enabled!
glDisable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
glEnable(GL_COLOR_MATERIAL); GLint maxLightCount;
glGetIntegerv(GL_MAX_LIGHTS,&maxLightCount);
for (GLint i=; i<maxLightCount; ++i)
{
if (glIsEnabled(GL_LIGHT0+i))
{
float diffuse[],ambiant[],specular[]; glGetLightfv(GL_LIGHT0+i,GL_AMBIENT,ambiant);
glGetLightfv(GL_LIGHT0+i,GL_DIFFUSE,diffuse);
glGetLightfv(GL_LIGHT0+i,GL_SPECULAR,specular); ambiant[] = ambiant[] = 1.0f;
diffuse[] = diffuse[] = 0.0f;
specular[] = specular[] = 0.0f; glLightfv(GL_LIGHT0+i,GL_DIFFUSE,diffuse);
glLightfv(GL_LIGHT0+i,GL_AMBIENT,ambiant);
glLightfv(GL_LIGHT0+i,GL_SPECULAR,specular);
}
}
}
}
} //if all points should be displayed (fastest case)
if (!hiddenPoints)
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
if (glParams.showNorms)
glEnableClientState(GL_NORMAL_ARRAY); if (toDisplay.indexMap) //LoD display
{
unsigned s = toDisplay.startIndex;
while (s < toDisplay.endIndex)
{
unsigned count = std::min(MAX_POINT_COUNT_PER_LOD_RENDER_PASS,toDisplay.endIndex-s);
unsigned e = s+count; //points
glLODChunkVertexPointer(*toDisplay.indexMap,s,e);
//normals
if (glParams.showNorms)
glLODChunkNormalPointer(*toDisplay.indexMap,s,e);
//SF colors
if (colorRampShader)
{
float* _sfColors = s_rgbBuffer3f;
bool symScale = m_currentDisplayedScalarField->symmetricalScale();
for (unsigned j=s; j<e; j++,_sfColors+=)
{
unsigned pointIndex = toDisplay.indexMap->getValue(j);
ScalarType sfVal = m_currentDisplayedScalarField->getValue(pointIndex);
//normalized sf value
_sfColors[] = symScale ? GetSymmetricalNormalizedValue(sfVal,sfSaturationRange) : GetNormalizedValue(sfVal,sfDisplayRange);
//flag: whether point is grayed out or not (NaN values are also rejected!)
_sfColors[] = sfDisplayRange.isInRange(sfVal) ? 1.0f : 0.0f;
//reference value (to get the true lighting value)
_sfColors[] = 1.0f;
}
glColorPointer(,GL_FLOAT,,s_rgbBuffer3f);
}
else
{
glLODChunkSFPointer(*toDisplay.indexMap,s,e);
} glDrawArrays(GL_POINTS,,count); s = e;
}
}
else
{
unsigned chunks = m_points->chunksCount();
for (unsigned k=; k<chunks; ++k)
{
unsigned chunkSize = m_points->chunkSize(k); //points
glChunkVertexPointer(k,toDisplay.decimStep,useVBOs);
//normals
if (glParams.showNorms)
glChunkNormalPointer(k,toDisplay.decimStep,useVBOs);
//SF colors
if (colorRampShader)
{
ScalarType* _sf = m_currentDisplayedScalarField->chunkStartPtr(k);
float* _sfColors = s_rgbBuffer3f;
bool symScale = m_currentDisplayedScalarField->symmetricalScale();
for (unsigned j=; j<chunkSize; j+=toDisplay.decimStep,_sf+=toDisplay.decimStep,_sfColors+=)
{
//normalized sf value
_sfColors[] = symScale ? GetSymmetricalNormalizedValue(*_sf,sfSaturationRange) : GetNormalizedValue(*_sf,sfDisplayRange);
//flag: whether point is grayed out or not (NaN values are also rejected!)
_sfColors[] = sfDisplayRange.isInRange(*_sf) ? 1.0f : 0.0f;
//reference value (to get the true lighting value)
_sfColors[] = 1.0f;
}
glColorPointer(,GL_FLOAT,,s_rgbBuffer3f);
}
else
{
glChunkSFPointer(k,toDisplay.decimStep,useVBOs);
} if (toDisplay.decimStep > )
chunkSize = static_cast<unsigned>( floor(static_cast<float>(chunkSize)/toDisplay.decimStep) );
glDrawArrays(GL_POINTS,,chunkSize);
}
} if (glParams.showNorms)
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
else //potentially hidden points
{
//compressed normals set
const ccNormalVectors* compressedNormals = ccNormalVectors::GetUniqueInstance();
assert(compressedNormals); glBegin(GL_POINTS); if (glParams.showNorms) //with normals (slowest case!)
{
if (colorRampShader)
{
if (!m_currentDisplayedScalarField->symmetricalScale())
{
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
assert(pointIndex < m_currentDisplayedScalarField->currentSize());
const ScalarType sf = m_currentDisplayedScalarField->getValue(pointIndex);
if (sfDisplayRange.isInRange(sf)) //NaN values are rejected
{
glColor3f(GetNormalizedValue(sf,sfDisplayRange),1.0f,1.0f);
ccGL::Normal3v(compressedNormals->getNormal(m_normals->getValue(pointIndex)).u);
ccGL::Vertex3v(m_points->getValue(pointIndex));
}
}
}
else
{
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
assert(pointIndex < m_currentDisplayedScalarField->currentSize());
const ScalarType sf = m_currentDisplayedScalarField->getValue(pointIndex);
if (sfDisplayRange.isInRange(sf)) //NaN values are rejected
{
glColor3f(GetSymmetricalNormalizedValue(sf,sfSaturationRange),1.0f,1.0f);
ccGL::Normal3v(compressedNormals->getNormal(m_normals->getValue(pointIndex)).u);
ccGL::Vertex3v(m_points->getValue(pointIndex));
}
}
}
}
else
{
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
assert(pointIndex < m_currentDisplayedScalarField->currentSize());
const ColorCompType* col = m_currentDisplayedScalarField->getValueColor(pointIndex);
if (col)
{
glColor3ubv(col);
ccGL::Normal3v(compressedNormals->getNormal(m_normals->getValue(pointIndex)).u);
ccGL::Vertex3v(m_points->getValue(pointIndex));
}
}
}
}
else //potentially hidden points without normals (a bit faster)
{
if (colorRampShader)
{
if (!m_currentDisplayedScalarField->symmetricalScale())
{
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
assert(pointIndex < m_currentDisplayedScalarField->currentSize());
const ScalarType sf = m_currentDisplayedScalarField->getValue(pointIndex);
if (sfDisplayRange.isInRange(sf)) //NaN values are rejected
{
glColor3f(GetNormalizedValue(sf,sfDisplayRange),1.0f,1.0f);
ccGL::Vertex3v(m_points->getValue(pointIndex));
}
}
}
else
{
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
assert(pointIndex < m_currentDisplayedScalarField->currentSize());
const ScalarType sf = m_currentDisplayedScalarField->getValue(pointIndex);
if (sfDisplayRange.isInRange(sf)) //NaN values are rejected
{
glColor3f(GetSymmetricalNormalizedValue(sf,sfSaturationRange),1.0f,1.0f);
ccGL::Vertex3v(m_points->getValue(pointIndex));
}
}
}
}
else
{
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
assert(pointIndex < m_currentDisplayedScalarField->currentSize());
const ColorCompType* col = m_currentDisplayedScalarField->getValueColor(pointIndex);
if (col)
{
glColor3ubv(col);
ccGL::Vertex3v(m_points->getValue(pointIndex));
}
}
}
}
glEnd();
} if (colorRampShader)
{
colorRampShader->stop(); if (glParams.showNorms)
glPopAttrib(); //GL_LIGHTING_BIT
}
}
else //no visibility table enabled, no scalar field
{
bool useVBOs = context.useVBOs && !toDisplay.indexMap ? updateVBOs(glParams) : false; //VBOs are not compatible with LoD unsigned chunks = m_points->chunksCount(); glEnableClientState(GL_VERTEX_ARRAY);
if (glParams.showNorms)
glEnableClientState(GL_NORMAL_ARRAY);
if (glParams.showColors)
glEnableClientState(GL_COLOR_ARRAY); if (toDisplay.indexMap) //LoD display
{
unsigned s = toDisplay.startIndex;
while (s < toDisplay.endIndex)
{
unsigned count = std::min(MAX_POINT_COUNT_PER_LOD_RENDER_PASS,toDisplay.endIndex-s);
unsigned e = s+count; //points
glLODChunkVertexPointer(*toDisplay.indexMap,s,e);
//normals
if (glParams.showNorms)
glLODChunkNormalPointer(*toDisplay.indexMap,s,e);
//colors
if (glParams.showColors)
glLODChunkColorPointer(*toDisplay.indexMap,s,e); glDrawArrays(GL_POINTS,,count);
s = e;
}
}
else
{
for (unsigned k=; k<chunks; ++k)
{
unsigned chunkSize = m_points->chunkSize(k); //points
glChunkVertexPointer(k,toDisplay.decimStep,useVBOs);
//normals
if (glParams.showNorms)
glChunkNormalPointer(k,toDisplay.decimStep,useVBOs);
//colors
if (glParams.showColors)
glChunkColorPointer(k,toDisplay.decimStep,useVBOs); if (toDisplay.decimStep > )
chunkSize = static_cast<unsigned>(floor(static_cast<float>(chunkSize)/toDisplay.decimStep));
glDrawArrays(GL_POINTS,,chunkSize);
}
} glDisableClientState(GL_VERTEX_ARRAY);
if (glParams.showNorms)
glDisableClientState(GL_NORMAL_ARRAY);
if (glParams.showColors)
glDisableClientState(GL_COLOR_ARRAY);
}
}
else //special case: point names pushing (for picking) --> no need for colors, normals, etc.
{
glPushName();
//however we must take hidden points into account!
if (isVisibilityTableInstantiated())
{
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
if (m_pointsVisibility->getValue(j) == POINT_VISIBLE)
{
glLoadName(pointIndex);
glBegin(GL_POINTS);
ccGL::Vertex3v(m_points->getValue(pointIndex));
glEnd();
}
}
}
else //no visibility table instantiated...
{
//... but potentially points with NAN SF values (also hidden!)
bool hiddenPoints = false;
if (glParams.showSF)
{
assert(m_currentDisplayedScalarField);
hiddenPoints = m_currentDisplayedScalarField->mayHaveHiddenValues() && m_currentDisplayedScalarField->getColorScale();
} if (hiddenPoints) //potentially hidden points
{
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
//we must generate the synthetic "color" of each point
const ColorCompType* col = getPointScalarValueColor(pointIndex);
if (col)
{
glLoadName(pointIndex);
glBegin(GL_POINTS);
ccGL::Vertex3v(m_points->getValue(pointIndex));
glEnd();
}
}
}
else
{
//no hidden point
for (unsigned j=toDisplay.startIndex; j<toDisplay.endIndex; j+=toDisplay.decimStep)
{
unsigned pointIndex = (toDisplay.indexMap ? toDisplay.indexMap->getValue(j) : j);
glLoadName(pointIndex);
glBegin(GL_POINTS);
ccGL::Vertex3v(m_points->getValue(pointIndex));
glEnd();
}
}
} //glEnd();
glPopName();
} /*** END DISPLAY ***/ glPopAttrib(); //GL_POINT_BIT if (colorMaterialEnabled)
glDisable(GL_COLOR_MATERIAL); //we can now switch the light off
if (glParams.showNorms)
{
if (glParams.showSF)
glPopAttrib(); //GL_LIGHTING_BIT glDisable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE));
glDisable(GL_LIGHTING);
} if (pushName)
glPopName();
}
else if (MACRO_Draw2D(context))
{
if (MACRO_Foreground(context) && !context.sfColorScaleToDisplay)
{
if (sfColorScaleShown() && sfShown())
{
//drawScale(context);
addColorRampInfo(context);
}
}
}
}

ccPointCloud::drawMeOnly

[CC]LOD技术的更多相关文章

  1. Unity性能优化——LOD技术

    LOD,中文名多层次细节,是游戏中最常用的技术,它按照模型的位置和重要程度决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算.今天我们来实现使用它来做一个简单的优化例子. ...

  2. cc攻击技术

    攻击者借助代理服务器生成指向受害主机的合法请求,实现DOS,和伪装就叫:cc(ChallengeCollapsar). CC主要是用来攻击页面的.大家都有这样的经历,就是在访问论坛时,如果这个论坛比较 ...

  3. unity3d的优化场景技术LOD+IOC

    一.unity3d的优化场景技术  LOD+IOC 遮挡剔除(occlusion culling)其实就是在摄像机范围内的物体才被渲染出来,没有在视野范围内的,统统关掉渲染,这样能让性能大大提高. I ...

  4. Unity中的优化技术

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/candycat1992/article/ ...

  5. Unity教程之再谈Unity中的优化技术

    这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体   这一步主要是为了针对性能瓶颈中的”顶点 ...

  6. 【Unity技巧】Unity中的优化技术

    http://blog.csdn.net/candycat1992/article/details/42127811 写在前面 这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得 ...

  7. [转]unity之LOD

    LOD技术有点类似于Mipmap技术,不同的是,LOD是对模型建立了一个模型金字塔,根据摄像机距离对象的远近,选择使用不同精度的模型. 它的好处是可以在适当的时候大量减少需要绘制的顶点数目. 它的缺点 ...

  8. Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术

    转自冯乐乐的 <Unity Shader 入门精要> 移动平台的特点 为了尽可能一处那些隐藏的表面,减少overdraw(即一个像素被绘制多次),PowerVR芯片(通常用于ios设备和某 ...

  9. 总结的U3D面试题

    1.配置Unity 3d调试环境? 1)          Visual Studio Tools for Unity 2)          访问http://unityvs.com 3)      ...

随机推荐

  1. EM算法总结

    EM算法总结 - The EM Algorithm EM是我一直想深入学习的算法之一,第一次听说是在NLP课中的HMM那一节,为了解决HMM的参数估计问题,使用了EM算法.在之后的MT中的词对齐中也用 ...

  2. 【转】一台电脑同时运行多个tomcat配置方法

    参考:http://blog.csdn.net/zyk906705975/article/details/8471475

  3. Ubuntu菜鸟入门(一)—— 截图工具安装

    Ubuntu截图工具Shutter 1.添加安装包软件源 sudo add-apt-repository ppa:shutter/ppa 2.更新源并安装 shutter sudo apt-get u ...

  4. Oracle 第一天

    Oracle 第一天 1.oracle数据库下载.安装和配置 1.1 下载压缩包后解压并将压缩包2里面的文件覆盖至压缩包1中 1.2 按照步骤逐步安装 1.3 设置管理员密码时,默认情况下四个管理员是 ...

  5. CentOS6.7安装Python3.4

    1.下载Python3.4安装包 wget https://www.python.org/ftp/python/3.4.4/Python-3.4.4.tgz 2.解压.编译.安装 .tgz cd Py ...

  6. erlang mac os 10.9 卸载脚本

    #!/bin/bash if [ "$(id -u)" != "0" ]; then echo "Insufficient permissions. ...

  7. phpunit学习 3:

    16:17 2015/12/11phpunit学习 3:单元测试的大概步骤是:编写待测试类,编写测试用例类,编写测试类,测试.1.如果你有多个类,多个测试类的test类,那么可以编写一个AllTest ...

  8. Hello cnblog!

    Test Markdown #!/usr/env/python # coding: utf-8 # 这是一个测试文件 print "hahah" def t(): print &q ...

  9. STM32之EXTI——外部中断

    互联网的广大网友,大家早上中午晚上好.EXTI...故名思义..EX表外,出..I表示Intrrupt..所以合起来就是外部中断...说到这..我觉得我最近的六级水平(背单词)又进了一步,稍微自夸了下 ...

  10. shujuk

    数据库管理的目标:在适当的时候以适当的形式向适当的人提供适当的数据. 2. 数据管理的内容:组织业务的管理(学生的信息) :技术的管理(数据库的建立等) 3. 数据库管理的发展阶段:人工,文件,数据库 ...