//绘制点云 void DcGp::DcGpPointCloud::DrawMyselfOnly(DcGpDrawContext& context) { //如果数据隐藏,则返回上层数据 if (!IsVisible()) { return; } //是否存在点数据,否则返回上层函数 if (m_pDcGpPointCloudImpl->m_points.empty()) return; //判断是否是绘制三维物体 if (MACRO_Draw3D(context)) { glPushAttrib(GL_ALL_ATTRIB_BITS); if (!m_pDcGpPointCloudImpl->m_generalDrawShader.getProgramIndex()) { //! 初始化一个shader program,用来处理快速渲染时候点隐藏的问题 char* byteGlVersion = (char*)glGetString(GL_VERSION); if (byteGlVersion[0] < '3' ) { return; } else { m_pDcGpPointCloudImpl->SetupGeneralDrawShaders(); } } if (m_pDcGpPointCloudImpl->m_generalDrawShader.getProgramIndex()) { glUseProgram(m_pDcGpPointCloudImpl->m_generalDrawShader.getProgramIndex()); //! 为block量赋值 double matrixProjection[16]; double matrixView[16]; glGetDoublev(GL_PROJECTION_MATRIX, matrixProjection); glGetDoublev(GL_MODELVIEW_MATRIX, matrixView); DCCore::mat4 matPro; DCCore::mat4 matView; for (int i = 0; i != 16; ++i) { matPro.ptr()[i] = matrixProjection[i]; matView.ptr()[i] = matrixView[i]; } DCCore::mat4 pvm = matPro * matView; m_pDcGpPointCloudImpl->m_generalDrawShader.setUniform("pvm", pvm.ptr()); float isSingleColor = 0; m_pDcGpPointCloudImpl->m_generalDrawShader.setUniform("isSingleColor", &isSingleColor); } //获取显示参数 glDrawParameters glParams; GetDrawingParameters(glParams); glParams.showNormals &= bool(MACRO_LightIsEnabled(context)); //是否使用光照 //! 计算纯色值 std::vector<float > singleColor; if (glParams.showColors && IsColorOverriden()) { singleColor.push_back(GetTempColor()[0]); singleColor.push_back(GetTempColor()[1]); singleColor.push_back(GetTempColor()[2]); glParams.showColors = false; } else { singleColor.push_back(context.pointsDefaultCol[0]); singleColor.push_back(context.pointsDefaultCol[1]); singleColor.push_back(context.pointsDefaultCol[2]); } // L.O.D. unsigned numberOfPoints = Size(); unsigned decimStep = 0; if (m_pDcGpPointCloudImpl->m_pointSize != 0) glPointSize((GLfloat)m_pDcGpPointCloudImpl->m_pointSize); //! 渲染绘制,因为为shader传入了可见性变量,所以不管什么情况只要控制传入 //! 顶点、颜色、法向量即可。顶点是不变的,颜色是变化的(纯色、标量色、选取色),法向量是不变的(存在或者不存在) //!开启alpha测试 glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0f); int sample = 0; //! 1、每帧中顶点不变 glEnableVertexAttribArray(VSShaderLib::VERTEX_COORD_ATTRIB); glVertexAttribPointer(VSShaderLib::VERTEX_COORD_ATTRIB, 3, GL_FLOAT, 0, sample * 3 * sizeof(PointCoordinateType), &(m_pDcGpPointCloudImpl->m_points[0][0])); //! 2、每帧中顶点可见性不变,传递顶点的可见性变量到shader中 glEnableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB1); glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB1, 1, GL_INT, 0, sample * 1 * sizeof(int), &(m_pDcGpPointCloudImpl->m_pointsVisibility[0])); //! 3、确定颜色值怎么选择(只存在纯色、真彩色、标量色三种) if (glParams.showColors) { glEnableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB2); if (IsChoosed()) { glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_choosedColors[0][0])); } else { glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_rgbColors[0][0])); } } else if (glParams.showScalarField) { glEnableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB2); if (IsChoosed()) { glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_choosedColors[0][0])); } else { glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_scalarColors[0][0])); } } else { if (IsChoosed()) { float isSingleColor = 0; m_pDcGpPointCloudImpl->m_generalDrawShader.setUniform("isSingleColor", &isSingleColor); glEnableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB2); glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_choosedColors[0][0])); } else { //! 纯色处理,由于纯色不是颜色数组,所以采用uniform实现 float isSingleColor = 1; m_pDcGpPointCloudImpl->m_generalDrawShader.setUniform("isSingleColor", &isSingleColor); //!传入纯色值 m_pDcGpPointCloudImpl->m_generalDrawShader.setUniform("singleColor", &singleColor[0]); } } //! 渲染 //glDrawArrays(GL_POINTS, 0, numberOfPoints); //绘制顶点数组时候均采用循环处理,采用数据定长处理,每次处理100000数据 if (GetChunk() > 1) { for (long i = 0; i != GetChunk(); ++i) { if (i == GetChunk()-1) { glDrawArrays(GL_POINTS, DC_CHUNK_COUNT * i, Size() - DC_CHUNK_COUNT * i); } else { glDrawArrays(GL_POINTS, DC_CHUNK_COUNT * i, DC_CHUNK_COUNT); } } } else { glDrawArrays(GL_POINTS, 0, Size()); } glDisableVertexAttribArray(VSShaderLib::VERTEX_COORD_ATTRIB); glDisableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB1); glDisableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB2); glDisable(GL_ALPHA_TEST); glPopAttrib(); glUseProgram(0); } else if (MACRO_Draw2D(context)) { if (MACRO_Foreground(context) && !context.sfColorScaleToDisplay) { if (IsSfColorbarVisible() && ScalarFieldShown()) { //drawScale(context); AddColorBarInfo(context); } } } //绘制文本 //context._win->Display3DLabel( "Qt", GetPoint(0) + DCVector3D(context.pickedPointsTextShift), DCColor::MAGENTA, QFont()); }
void ccGenericMesh::drawMeOnly(CC_DRAW_CONTEXT& context) { ccGenericPointCloud* vertices = getAssociatedCloud(); if (!vertices) return; handleColorRamp(context); //3D pass if (MACRO_Draw3D(context)) { //any triangle? unsigned triNum = size(); if (triNum == 0) return; //L.O.D. bool lodEnabled = (triNum > GET_MAX_LOD_FACES_NUMBER() && context.decimateMeshOnMove && MACRO_LODActivated(context)); unsigned decimStep = (lodEnabled ? (unsigned)ceil((float)triNum*3 / (float)GET_MAX_LOD_FACES_NUMBER()) : 1); unsigned displayedTriNum = triNum / decimStep; //display parameters glDrawParams glParams; getDrawingParameters(glParams); glParams.showNorms &= bool(MACRO_LightIsEnabled(context)); //vertices visibility const ccGenericPointCloud::VisibilityTableType* verticesVisibility = vertices->getTheVisibilityArray(); bool visFiltering = (verticesVisibility && verticesVisibility->isAllocated()); //wireframe ? (not compatible with LOD) bool showWired = isShownAsWire() && !lodEnabled; //per-triangle normals? bool showTriNormals = (hasTriNormals() && triNormsShown()); //fix 'showNorms' glParams.showNorms = showTriNormals || (vertices->hasNormals() && m_normalsDisplayed); //materials & textures bool applyMaterials = (hasMaterials() && materialsShown()); bool showTextures = (hasTextures() && materialsShown() && !lodEnabled); //GL name pushing bool pushName = MACRO_DrawEntityNames(context); //special case: triangle names pushing (for picking) bool pushTriangleNames = MACRO_DrawTriangleNames(context); pushName |= pushTriangleNames; if (pushName) { //not fast at all! if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); //minimal display for picking mode! glParams.showNorms = false; glParams.showColors = false; //glParams.showSF --> we keep it only if SF 'NaN' values are hidden showTriNormals = false; applyMaterials = false; showTextures = false; } //in the case we need to display scalar field colors ccScalarField* currentDisplayedScalarField = 0; bool greyForNanScalarValues = true; unsigned colorRampSteps = 0; ccColorScale::Shared colorScale(0); if (glParams.showSF) { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); ccPointCloud* cloud = static_cast<ccPointCloud*>(vertices); greyForNanScalarValues = (cloud->getCurrentDisplayedScalarField() && cloud->getCurrentDisplayedScalarField()->areNaNValuesShownInGrey()); if (greyForNanScalarValues && pushName) { //in picking mode, no need to take SF into account if we don't hide any points! glParams.showSF = false; } else { currentDisplayedScalarField = cloud->getCurrentDisplayedScalarField(); colorScale = currentDisplayedScalarField->getColorScale(); colorRampSteps = currentDisplayedScalarField->getColorRampSteps(); assert(colorScale); //get default color ramp if cloud has no scale associated?! if (!colorScale) colorScale = ccColorScalesManager::GetUniqueInstance()->getDefaultScale(ccColorScalesManager::BGYR); } } //materials or color? bool colorMaterial = false; if (glParams.showSF || glParams.showColors) { applyMaterials = false; colorMaterial = true; glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); } //in the case we need to display vertex colors ColorsTableType* rgbColorsTable = 0; if (glParams.showColors) { if (isColorOverriden()) { glColor3ubv(m_tempColor); glParams.showColors = false; } else { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); rgbColorsTable = static_cast<ccPointCloud*>(vertices)->rgbColors(); } } else { glColor3fv(context.defaultMat.diffuseFront); } if (glParams.showNorms) { //DGM: Strangely, when Qt::renderPixmap is called, the OpenGL version can fall to 1.0! glEnable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE)); glEnable(GL_LIGHTING); context.defaultMat.applyGL(true,colorMaterial); } //in the case we need normals (i.e. lighting) NormsIndexesTableType* normalsIndexesTable = 0; ccNormalVectors* compressedNormals = 0; if (glParams.showNorms) { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); normalsIndexesTable = static_cast<ccPointCloud*>(vertices)->normals(); compressedNormals = ccNormalVectors::GetUniqueInstance(); } //stipple mask if (stipplingEnabled()) EnableGLStippleMask(true); if (!pushTriangleNames && !visFiltering && !(applyMaterials || showTextures) && (!glParams.showSF || greyForNanScalarValues)) { //the GL type depends on the PointCoordinateType 'size' (float or double) GLenum GL_COORD_TYPE = sizeof(PointCoordinateType) == 4 ? GL_FLOAT : GL_DOUBLE; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_COORD_TYPE,0,GetVertexBuffer()); if (glParams.showNorms) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_COORD_TYPE,0,GetNormalsBuffer()); } if (glParams.showSF || glParams.showColors) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3,GL_UNSIGNED_BYTE,0,GetColorsBuffer()); } //we can scan and process each chunk separately in an optimized way //we mimic the way ccMesh beahves by using virtual chunks! unsigned chunks = static_cast<unsigned>(ceil((double)displayedTriNum/(double)MAX_NUMBER_OF_ELEMENTS_PER_CHUNK)); unsigned chunkStart = 0; const colorType* col = 0; for (unsigned k=0; k<chunks; ++k, chunkStart += MAX_NUMBER_OF_ELEMENTS_PER_CHUNK) { //virtual chunk size const unsigned chunkSize = k+1 < chunks ? MAX_NUMBER_OF_ELEMENTS_PER_CHUNK : (displayedTriNum % MAX_NUMBER_OF_ELEMENTS_PER_CHUNK); //vertices PointCoordinateType* _vertices = GetVertexBuffer(); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_vertices,vertices->getPoint(ti->i1)->u,sizeof(PointCoordinateType)*3); _vertices+=3; memcpy(_vertices,vertices->getPoint(ti->i2)->u,sizeof(PointCoordinateType)*3); _vertices+=3; memcpy(_vertices,vertices->getPoint(ti->i3)->u,sizeof(PointCoordinateType)*3); _vertices+=3; } //scalar field if (glParams.showSF) { colorType* _rgbColors = GetColorsBuffer(); assert(colorScale); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); col = currentDisplayedScalarField->getValueColor(ti->i1); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; col = currentDisplayedScalarField->getValueColor(ti->i2); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; col = currentDisplayedScalarField->getValueColor(ti->i3); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; } } //colors else if (glParams.showColors) { colorType* _rgbColors = GetColorsBuffer(); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_rgbColors,rgbColorsTable->getValue(ti->i1),sizeof(colorType)*3); _rgbColors += 3; memcpy(_rgbColors,rgbColorsTable->getValue(ti->i2),sizeof(colorType)*3); _rgbColors += 3; memcpy(_rgbColors,rgbColorsTable->getValue(ti->i3),sizeof(colorType)*3); _rgbColors += 3; } } //normals if (glParams.showNorms) { PointCoordinateType* _normals = GetNormalsBuffer(); if (showTriNormals) { for (unsigned n=0; n<chunkSize; n+=decimStep) { CCVector3 Na, Nb, Nc; getTriangleNormals(chunkStart + n, Na, Nb, Nc); memcpy(_normals,Na.u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,Nb.u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,Nc.u,sizeof(PointCoordinateType)*3); _normals+=3; } } else { for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_normals,vertices->getPointNormal(ti->i1).u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,vertices->getPointNormal(ti->i2).u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,vertices->getPointNormal(ti->i3).u,sizeof(PointCoordinateType)*3); _normals+=3; } } } if (!showWired) { glDrawArrays(lodEnabled ? GL_POINTS : GL_TRIANGLES,0,(chunkSize/decimStep)*3); } else { glDrawElements(GL_LINES,(chunkSize/decimStep)*6,GL_UNSIGNED_INT,GetWireVertexIndexes()); } } //disable arrays glDisableClientState(GL_VERTEX_ARRAY); if (glParams.showNorms) glDisableClientState(GL_NORMAL_ARRAY); if (glParams.showSF || glParams.showColors) glDisableClientState(GL_COLOR_ARRAY); } else { //current vertex color const colorType *col1=0,*col2=0,*col3=0; //current vertex normal const PointCoordinateType *N1=0,*N2=0,*N3=0; //current vertex texture coordinates float *Tx1=0,*Tx2=0,*Tx3=0; //loop on all triangles int lasMtlIndex = -1; if (showTextures) { //#define TEST_TEXTURED_BUNDLER_IMPORT #ifdef TEST_TEXTURED_BUNDLER_IMPORT glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(context.sourceBlend, context.destBlend); #endif glEnable(GL_TEXTURE_2D); } if (pushTriangleNames) glPushName(0); GLenum triangleDisplayType = lodEnabled ? GL_POINTS : showWired ? GL_LINE_LOOP : GL_TRIANGLES; glBegin(triangleDisplayType); //per-triangle normals const NormsIndexesTableType* triNormals = getTriNormsTable(); //materials const ccMaterialSet* materials = getMaterialSet(); for (unsigned n=0; n<triNum; ++n) { //current triangle vertices const CCLib::TriangleSummitsIndexes* tsi = getTriangleIndexes(n); //LOD: shall we display this triangle? if (n % decimStep) continue; if (visFiltering) { //we skip the triangle if at least one vertex is hidden if ((verticesVisibility->getValue(tsi->i1) != POINT_VISIBLE) || (verticesVisibility->getValue(tsi->i2) != POINT_VISIBLE) || (verticesVisibility->getValue(tsi->i3) != POINT_VISIBLE)) continue; } if (glParams.showSF) { assert(colorScale); col1 = currentDisplayedScalarField->getValueColor(tsi->i1); if (!col1) continue; col2 = currentDisplayedScalarField->getValueColor(tsi->i2); if (!col2) continue; col3 = currentDisplayedScalarField->getValueColor(tsi->i3); if (!col3) continue; } else if (glParams.showColors) { col1 = rgbColorsTable->getValue(tsi->i1); col2 = rgbColorsTable->getValue(tsi->i2); col3 = rgbColorsTable->getValue(tsi->i3); } if (glParams.showNorms) { if (showTriNormals) { assert(triNormals); int n1,n2,n3; getTriangleNormalIndexes(n,n1,n2,n3); N1 = (n1>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n1)).u : 0); N2 = (n1==n2 ? N1 : n1>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n2)).u : 0); N3 = (n1==n3 ? N1 : n3>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n3)).u : 0); } else { N1 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i1)).u; N2 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i2)).u; N3 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i3)).u; } } if (applyMaterials || showTextures) { assert(materials); int newMatlIndex = this->getTriangleMtlIndex(n); //do we need to change material? if (lasMtlIndex != newMatlIndex) { assert(newMatlIndex<(int)materials->size()); glEnd(); if (showTextures) { GLuint texID = (newMatlIndex>=0 ? (*materials)[newMatlIndex].texID : 0); if (texID>0) assert(glIsTexture(texID)); glBindTexture(GL_TEXTURE_2D, texID); } //if we don't have any current material, we apply default one (newMatlIndex>=0 ? (*materials)[newMatlIndex] : context.defaultMat).applyGL(glParams.showNorms,false); glBegin(triangleDisplayType); lasMtlIndex=newMatlIndex; } if (showTextures) { getTriangleTexCoordinates(n,Tx1,Tx2,Tx3); } } if (pushTriangleNames) { glEnd(); glLoadName(n); glBegin(triangleDisplayType); } else if (showWired) { glEnd(); glBegin(triangleDisplayType); } //vertex 1 if (N1) ccGL::Normal3v(N1); if (col1) glColor3ubv(col1); if (Tx1) glTexCoord2fv(Tx1); ccGL::Vertex3v(vertices->getPoint(tsi->i1)->u); //vertex 2 if (N2) ccGL::Normal3v(N2); if (col2) glColor3ubv(col2); if (Tx2) glTexCoord2fv(Tx2); ccGL::Vertex3v(vertices->getPoint(tsi->i2)->u); //vertex 3 if (N3) ccGL::Normal3v(N3); if (col3) glColor3ubv(col3); if (Tx3) glTexCoord2fv(Tx3); ccGL::Vertex3v(vertices->getPoint(tsi->i3)->u); } glEnd(); if (pushTriangleNames) glPopName(); if (showTextures) { #ifdef TEST_TEXTURED_BUNDLER_IMPORT glPopAttrib(); //GL_COLOR_BUFFER_BIT #endif glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); } } if (stipplingEnabled()) EnableGLStippleMask(false); if (colorMaterial) glDisable(GL_COLOR_MATERIAL); if (glParams.showNorms) { glDisable(GL_LIGHTING); glDisable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE)); } if (pushName) glPopName(); } }
void DcGp::DcGpPointCloud::FastDrawMyselfOnly(DcGpDrawContext& context) { //如果数据隐藏,则返回上层数据 if (!IsVisible()) { return; } //是否存在点数据,否则返回上层函数 if (m_pDcGpPointCloudImpl->m_points.empty()) return; //判断是否是绘制三维物体 if (MACRO_Draw3D(context)) { glPushAttrib(GL_ALL_ATTRIB_BITS); if (!m_pDcGpPointCloudImpl->m_fastDrawShader.getProgramIndex()) { //! 初始化一个shader program,用来处理快速渲染时候点隐藏的问题 char* byteGlVersion = (char*)glGetString(GL_VERSION); if (byteGlVersion[0] < '3' ) { return; } else { m_pDcGpPointCloudImpl->SetupFastDrawShaders(); } } if (m_pDcGpPointCloudImpl->m_fastDrawShader.getProgramIndex()) { glUseProgram(m_pDcGpPointCloudImpl->m_fastDrawShader.getProgramIndex()); //! 为block量赋值 double matrixProjection[16]; double matrixView[16]; glGetDoublev(GL_PROJECTION_MATRIX, matrixProjection); glGetDoublev(GL_MODELVIEW_MATRIX, matrixView); DCCore::mat4 matPro; DCCore::mat4 matView; for (int i = 0; i != 16; ++i) { matPro.ptr()[i] = matrixProjection[i]; matView.ptr()[i] = matrixView[i]; } DCCore::mat4 pvm = matPro * matView; m_pDcGpPointCloudImpl->m_fastDrawShader.setUniform("pvm", pvm.ptr()); float isSingleColor = 0; m_pDcGpPointCloudImpl->m_fastDrawShader.setUniform("isSingleColor", &isSingleColor); } //获取显示参数 glDrawParameters glParams; GetDrawingParameters(glParams); glParams.showNormals &= bool(MACRO_LightIsEnabled(context)); //是否使用光照 //! 计算纯色值 std::vector<float > singleColor; if (glParams.showColors && IsColorOverriden()) { singleColor.push_back(GetTempColor()[0]); singleColor.push_back(GetTempColor()[1]); singleColor.push_back(GetTempColor()[2]); glParams.showColors = false; } else { singleColor.push_back(context.pointsDefaultCol[0]); singleColor.push_back(context.pointsDefaultCol[1]); singleColor.push_back(context.pointsDefaultCol[2]); } // L.O.D. unsigned numberOfPoints = Size(); unsigned sample = 1;//标准的显示全部点 unsigned totalSamplePoints = numberOfPoints; if (numberOfPoints >= DCCore::MAX_FACE_NUM) { sample = static_cast<int>(ceil(static_cast<float>(numberOfPoints) / DCCore::MAX_FACE_NUM)); } if (m_pDcGpPointCloudImpl->m_pointSize != 0) glPointSize((GLfloat)m_pDcGpPointCloudImpl->m_pointSize); //! 渲染绘制,因为为shader传入了可见性变量,所以不管什么情况只要控制传入 //! 顶点、颜色、法向量即可。顶点是不变的,颜色是变化的(纯色、标量色、选取色),法向量是不变的(存在或者不存在) //!开启alpha测试 glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0f); //! 1、每帧中顶点不变 glEnableVertexAttribArray(VSShaderLib::VERTEX_COORD_ATTRIB); glVertexAttribPointer(VSShaderLib::VERTEX_COORD_ATTRIB, 3, GL_FLOAT, 0, sample * 3 * sizeof(PointCoordinateType), &(m_pDcGpPointCloudImpl->m_points[0][0])); //! 2、每帧中顶点可见性不变,传递顶点的可见性变量到shader中 glEnableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB1); glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB1, 1, GL_INT, 0, sample * 1 * sizeof(int), &(m_pDcGpPointCloudImpl->m_pointsVisibility[0])); //! 3、确定颜色值怎么选择(只存在纯色、真彩色、标量色三种) if (glParams.showColors) { glEnableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB2); if (IsChoosed()) { glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_choosedColors[0][0])); } else { glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_rgbColors[0][0])); } } else if (glParams.showScalarField) { glEnableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB2); if (IsChoosed()) { glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_choosedColors[0][0])); } else { glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_scalarColors[0][0])); } } else { if (IsChoosed()) { float isSingleColor = 0; m_pDcGpPointCloudImpl->m_fastDrawShader.setUniform("isSingleColor", &isSingleColor); glEnableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB2); glVertexAttribPointer(VSShaderLib::VERTEX_ATTRIB2, 3, GL_UNSIGNED_BYTE, 0, sample * 3 * sizeof(ColorType), &(m_pDcGpPointCloudImpl->m_choosedColors[0][0])); } else { //! 纯色处理,由于纯色不是颜色数组,所以采用uniform实现 float isSingleColor = 1; m_pDcGpPointCloudImpl->m_fastDrawShader.setUniform("isSingleColor", &isSingleColor); //!传入纯色值 m_pDcGpPointCloudImpl->m_fastDrawShader.setUniform("singleColor", &singleColor[0]); } } //! 渲染 long lodNum = Size(); if (sample > 1) { float numFloat = static_cast<float >(lodNum) / sample; lodNum = static_cast<unsigned>(floor(numFloat)); } glDrawArrays(GL_POINTS, 0, lodNum); glDisableVertexAttribArray(VSShaderLib::VERTEX_COORD_ATTRIB); glDisableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB1); glDisableVertexAttribArray(VSShaderLib::VERTEX_ATTRIB2); glDisable(GL_ALPHA_TEST); glPopAttrib(); glUseProgram(0); } }