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. VS2012下X64平台嵌入汇编程序

    VS2012在win32平台编译的时候可以很好的支持汇编语言的嵌入.建立一个控制台应用程序,选择空项目.项目建立好之后添加一个.cpp文件.在cpp文件中写入如下代码: #include <io ...

  2. apache配置多个版本php

    参看链接:http://my.oschina.net/u/2366984/blog/543148?p={{page}} 主要虚拟主机配置信息 FcgidInitialEnv PHPRC "D ...

  3. Python lambda函数

    python允许定义单行的小函数,定义lambda函数的形式如下: lambda 参数:表达式lambda函数默认返回表达式的值,可接收任意个参数,包括可选参数,但是表达式只有一个.

  4. linux中grep命令详解

    http://jingyan.baidu.com/article/76a7e409e72777fc3b6e158a.html

  5. Salt安装(yum不可用时)

        salt-master安装   [salt-master]# yum install salt-master   或者 curl -L http://bootstrap.saltstack.o ...

  6. Bulk_Collect 调用方式集锦

    事先申明,本文所有示例都皆源于<Expert PL SQL Practices>这本电子书的第六章.小陈觉得在学习PLSQL的过程中,将来或许会用到,在此笔记一番. 正文如下: 首先准备基 ...

  7. NOI 题库 7084

    7084  迷宫问题 描述 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, ...

  8. 一些用过的我常忘记的小知识(web前端)

    背景图片固定:background-attachment:fixed 将图片的尺寸从中心点开始改变:backgroun-position:center   background-size: ** 旋转 ...

  9. js快速排序

    function sort(arr){ if(arr.length<=1){ return arr; } var num = Math.floor(arr.length/2); var numV ...

  10. java中接口的定义和接口的实现

    1.接口的定义 使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成.定义接口的基本格式如下: [修饰符] interfa ...