void ccGenericMesh::drawMeOnly(CC_DRAW_CONTEXT& context) { if (MACRO_Draw2D(context)) { if (MACRO_Foreground(context) && !context.sfColorScaleToDisplay) { if (!m_associatedCloud || !m_associatedCloud->isA(CC_POINT_CLOUD)) return; ccPointCloud* cloud = static_cast<ccPointCloud*>(m_associatedCloud); //we just want to display the current SF scale if the vertices cloud is hidden //(otherwise, it will take the SF display in charge) if (!cloud->sfColorScaleShown() || (cloud->isEnabled() && cloud->isVisible())) return; //we must also check that the parent is not a mesh itself with the same vertices! (in //which case it will also take that in charge) ccHObject* parent = getParent(); if (parent && parent->isKindOf(CC_MESH) && (static_cast<ccGenericMesh*>(parent)->getAssociatedCloud() == m_associatedCloud)) return; cloud->addColorRampInfo(context); //cloud->drawScale(context); } } //*/ }
void ccGenericMesh::handleColorRamp(CC_DRAW_CONTEXT& context) { if (MACRO_Draw2D(context)) { if (MACRO_Foreground(context) && !context.sfColorScaleToDisplay) { if (sfShown()) { ccGenericPointCloud* vertices = getAssociatedCloud(); if (!vertices || !vertices->isA(CC_TYPES::POINT_CLOUD)) return; ccPointCloud* cloud = static_cast<ccPointCloud*>(vertices); //we just need to 'display' the current SF scale if the vertices cloud is hidden //(otherwise, it will be taken in charge by the cloud itself) if (!cloud->sfColorScaleShown() || (cloud->sfShown() && cloud->isEnabled() && cloud->isVisible())) return; //we must also check that the parent is not a mesh itself with the same vertices! (in //which case it will also take that in charge) ccHObject* parent = getParent(); if (parent && parent->isKindOf(CC_TYPES::MESH) && (ccHObjectCaster::ToGenericMesh(parent)->getAssociatedCloud() == vertices)) return; cloud->addColorRampInfo(context); //cloud->drawScale(context); } } } }
void ccPolyline::drawMeOnly(CC_DRAW_CONTEXT& context) { if (size() < 2) return; bool draw = false; if (MACRO_Draw3D(context)) { draw = !m_mode2D; } else if (m_mode2D) { bool drawFG = MACRO_Foreground(context); draw = ((drawFG && m_foreground) || (!drawFG && !m_foreground)); } if (draw) { if (colorsShown()) glColor3ubv(m_rgbColor); glBegin(m_isClosed ? GL_LINE_LOOP : GL_LINE_STRIP); unsigned count=size(); for (unsigned i=0;i<count;++i) glVertex3fv(m_theAssociatedCloud->getPoint(m_theIndexes->getValue(i))->u); glEnd(); } }
void cc2DLabel::drawMeOnly(CC_DRAW_CONTEXT& context) { if (m_points.empty()) return; //2D foreground only if (!MACRO_Foreground(context)) return; //Not compatible with virtual transformation (see ccDrawableObject::enableGLTransformation) if (MACRO_VirtualTransEnabled(context)) return; if (MACRO_Draw3D(context)) drawMeOnly3D(context); else if (MACRO_Draw2D(context)) drawMeOnly2D(context); }
void ccImage::drawMeOnly(CC_DRAW_CONTEXT& context) { if (m_image.isNull()) return; if (MACRO_Draw2D(context)) { if (MACRO_Foreground(context)) { glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); if (bindToGlTexture(context._win)) { //we make the texture fit inside viewport int realWidth = (int)((float)m_height * m_aspectRatio); //take aspect ratio into account! GLfloat cw = GLfloat(context.glW)/GLfloat(realWidth); GLfloat ch = GLfloat(context.glH)/GLfloat(m_height); GLfloat zoomFactor = (cw > ch ? ch : cw)*0.5f; GLfloat dX = GLfloat(realWidth)*zoomFactor; GLfloat dY = GLfloat(m_height)*zoomFactor; glColor4f(1, 1, 1, m_texAlpha); glBegin(GL_QUADS); glTexCoord2f(0,m_texV); glVertex2f(-dX, -dY); glTexCoord2f(m_texU,m_texV); glVertex2f(dX, -dY); glTexCoord2f(m_texU,0); glVertex2f(dX, dY); glTexCoord2f(0,0); glVertex2f(-dX, dY); glEnd(); } glDisable(GL_TEXTURE_2D); glPopAttrib(); } } }
void ccSymbolCloud::drawMeOnly(CC_DRAW_CONTEXT& context) { if (!m_points->isAllocated()) return; //nothing to do?! if (!m_showSymbols && !m_showLabels) return; if (MACRO_Draw2D(context) && MACRO_Foreground(context)) { //we get display parameters glDrawParams glParams; getDrawingParameters(glParams); //standard case: list names pushing bool pushName = MACRO_DrawEntityNames(context); bool hasLabels = !m_labels.empty(); if (pushName) { //not fast at all! if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueID()); hasLabels = false; //no need to display labels in 'picking' mode } //we should already be in orthoprojective & centered omde //glOrtho(-halfW,halfW,-halfH,halfH,-maxS,maxS); //default color const unsigned char* color = context.pointsDefaultCol; if (isColorOverriden()) { color = m_tempColor; glParams.showColors = false; } if (!glParams.showColors) glColor3ubv(color); unsigned numberOfPoints = size(); //viewport parameters (will be used to project 3D positions to 2D) int VP[4]; context._win->getViewportArray(VP); const double* MM = context._win->getModelViewMatd(); //viewMat const double* MP = context._win->getProjectionMatd(); //projMat //only usefull when displaying labels! QFont font(context._win->getTextDisplayFont()); //takes rendering zoom into account! font.setPointSize(static_cast<int>(m_fontSize * context.renderZoom)); //font.setBold(true); QFontMetrics fontMetrics(font); double symbolSizeBackup = m_symbolSize; m_symbolSize *= static_cast<double>(context.renderZoom); double xpShift = 0.0; if (m_labelAlignFlags & ccGenericGLDisplay::ALIGN_HLEFT) xpShift = m_symbolSize/2.0; else if (m_labelAlignFlags & ccGenericGLDisplay::ALIGN_HRIGHT) xpShift = -m_symbolSize/2.0; double ypShift = 0.0; if (m_labelAlignFlags & ccGenericGLDisplay::ALIGN_VTOP) ypShift = m_symbolSize/2.0; else if (m_labelAlignFlags & ccGenericGLDisplay::ALIGN_VBOTTOM) ypShift = -m_symbolSize/2.0; //draw symbols + labels { for (unsigned i=0;i<numberOfPoints;i++) { //symbol center const CCVector3* P = getPoint(i); //project it in 2D screen coordinates GLdouble xp,yp,zp; gluProject(P->x,P->y,P->z,MM,MP,VP,&xp,&yp,&zp); //apply point color (if any) if (glParams.showColors) { color = getPointColor(i); glColor3ubv(color); } //draw associated symbol if (m_showSymbols && m_symbolSize > 0.0) { drawSymbolAt(xp-static_cast<double>(context.glW/2),yp-static_cast<double>(context.glH/2)); } //draw associated label? if (m_showLabels && hasLabels && m_labels.size() > i && !m_labels[i].isNull()) { //draw label context._win->displayText(m_labels[i],static_cast<int>(xp+xpShift),static_cast<int>(yp+ypShift),m_labelAlignFlags,0,color,&font); } } } //restore original symbol size m_symbolSize = symbolSizeBackup; if (pushName) glPopName(); } }
void ccPolyline::drawMeOnly(CC_DRAW_CONTEXT& context) { //no picking enabled on polylines if (MACRO_DrawPointNames(context)) return; unsigned vertCount = size(); if (vertCount < 2) return; bool draw = false; if (MACRO_Draw3D(context)) { draw = !m_mode2D; } else if (m_mode2D) { bool drawFG = MACRO_Foreground(context); draw = ((drawFG && m_foreground) || (!drawFG && !m_foreground)); } if (draw) { //standard case: list names pushing bool pushName = MACRO_DrawEntityNames(context); if (pushName) glPushName(getUniqueIDForDisplay()); if (colorsShown()) ccGL::Color3v(m_rgbColor.rgb); //display polyline if (vertCount > 1) { if (m_width != 0) { glPushAttrib(GL_LINE_BIT); glLineWidth(static_cast<GLfloat>(m_width)); } //DGM: we do the 'GL_LINE_LOOP' manually as I have a strange bug //on one on my graphic card with this mode! //glBegin(m_isClosed ? GL_LINE_LOOP : GL_LINE_STRIP); glBegin(GL_LINE_STRIP); for (unsigned i=0; i<vertCount; ++i) { ccGL::Vertex3v(getPoint(i)->u); } if (m_isClosed) { ccGL::Vertex3v(getPoint(0)->u); } glEnd(); //display arrow if (m_showArrow && m_arrowIndex < vertCount && (m_arrowIndex > 0 || m_isClosed)) { const CCVector3* P0 = getPoint(m_arrowIndex == 0 ? vertCount-1 : m_arrowIndex-1); const CCVector3* P1 = getPoint(m_arrowIndex); //direction of the last polyline chunk CCVector3 u = *P1 - *P0; u.normalize(); if (m_mode2D) { u *= -m_arrowLength; static const PointCoordinateType s_defaultArrowAngle = static_cast<PointCoordinateType>(15.0 * CC_DEG_TO_RAD); static const PointCoordinateType cost = cos(s_defaultArrowAngle); static const PointCoordinateType sint = sin(s_defaultArrowAngle); CCVector3 A(cost * u.x - sint * u.y, sint * u.x + cost * u.y, 0); CCVector3 B(cost * u.x + sint * u.y, -sint * u.x + cost * u.y, 0); glBegin(GL_POLYGON); ccGL::Vertex3v((A+*P1).u); ccGL::Vertex3v((B+*P1).u); ccGL::Vertex3v(( *P1).u); glEnd(); } else { if (!c_unitArrow) { c_unitArrow = QSharedPointer<ccCone>(new ccCone(0.5,0.0,1.0)); c_unitArrow->showColors(true); c_unitArrow->showNormals(false); c_unitArrow->setVisible(true); c_unitArrow->setEnabled(true); } if (colorsShown()) c_unitArrow->setTempColor(m_rgbColor); else c_unitArrow->setTempColor(context.pointsDefaultCol); //build-up unit arrow own 'context' CC_DRAW_CONTEXT markerContext = context; markerContext.flags &= (~CC_DRAW_ENTITY_NAMES); //we must remove the 'push name flag' so that the sphere doesn't push its own! markerContext._win = 0; glMatrixMode(GL_MODELVIEW); glPushMatrix(); ccGL::Translate(P1->x,P1->y,P1->z); ccGLMatrix rotMat = ccGLMatrix::FromToRotation(CCVector3(0,0,1),u); glMultMatrixf(rotMat.inverse().data()); glScalef(m_arrowLength,m_arrowLength,m_arrowLength); ccGL::Translate(0.0,0.0,-0.5); c_unitArrow->draw(markerContext); glPopMatrix(); } } if (m_width != 0) { glPopAttrib(); } } //display vertices if (m_showVertices) { glPushAttrib(GL_POINT_BIT); glPointSize((GLfloat)m_vertMarkWidth); glBegin(GL_POINTS); for (unsigned i=0; i<vertCount; ++i) { ccGL::Vertex3v(getPoint(i)->u); } glEnd(); glPopAttrib(); } if (pushName) glPopName(); } }
void ccPolyline::drawMeOnly(CC_DRAW_CONTEXT& context) { //no picking enabled on polylines if (MACRO_DrawPointNames(context)) return; unsigned vertCount = size(); if (vertCount < 2) return; bool draw = false; if (MACRO_Draw3D(context)) { draw = !m_mode2D; } else if (m_mode2D) { bool drawFG = MACRO_Foreground(context); draw = ((drawFG && m_foreground) || (!drawFG && !m_foreground)); } if (draw) { //standard case: list names pushing bool pushName = MACRO_DrawEntityNames(context); if (pushName) glPushName(getUniqueIDForDisplay()); if (colorsShown()) glColor3ubv(m_rgbColor); //display polyline { if (m_width != 0) { glPushAttrib(GL_LINE_BIT); glLineWidth(static_cast<GLfloat>(m_width)); } glBegin(m_isClosed ? GL_LINE_LOOP : GL_LINE_STRIP); for (unsigned i=0; i<vertCount; ++i) { ccGL::Vertex3v(getPoint(i)->u); } glEnd(); if (m_width != 0) { glPopAttrib(); } } //display vertices if (m_showVertices) { glPushAttrib(GL_POINT_BIT); glPointSize((GLfloat)m_vertMarkWidth); glBegin(GL_POINTS); for (unsigned i=0; i<vertCount; ++i) { ccGL::Vertex3v(getPoint(i)->u); } glEnd(); glPopAttrib(); } if (pushName) glPopName(); } }
//================================================draw====================================================// 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 and 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); //LOD只对点云有效?????????? } } //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); //绘制BB //if the entity is currently selected, we draw its bounding-box if (m_selected && draw3D && drawInThisContext && !MACRO_DrawNames(context) && context.currentLODLevel == 0){ drawBB(context.bbDefaultCol); } if (draw3D && m_glTransEnabled) glPopMatrix(); }
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 and 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) )); //apply 3D 'temporary' transformation (for display only) if (draw3D && m_glTransEnabled) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(m_glTrans.data()); } //draw entity if (m_visible && drawInThisContext) { if (( !m_selected || !MACRO_SkipSelected(context) ) && ( m_selected || !MACRO_SkipUnselected(context) )) { //apply default color (in case of) glColor3ubv(context.pointsDefaultCol); 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)) { switch (m_selectionBehavior) { case SELECTION_AA_BBOX: drawBB(context.bbDefaultCol); break; case SELECTION_FIT_BBOX: { ccGLMatrix trans; ccBBox box = getFitBB(trans); if (box.isValid()) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(trans.data()); box.draw(context.bbDefaultCol); glPopMatrix(); } } break; case SELECTION_IGNORED: break; default: assert(false); } } if (draw3D && m_glTransEnabled) glPopMatrix(); }
void cc2DViewportLabel::drawMeOnly(CC_DRAW_CONTEXT& context) { //2D foreground only if (!MACRO_Foreground(context) || !MACRO_Draw2D(context)) return; //test viewport parameters const ccViewportParameters& params = context._win->getViewportParameters(); //in perspective mode, screenPan or zoom cannot be easily compensated if (m_params.perspectiveView && ( params.zoom != m_params.zoom || params.globalZoom != m_params.globalZoom || params.screenPan[0] != m_params.screenPan[0] || params.screenPan[1] != m_params.screenPan[1] || (params.pivotPoint - m_params.pivotPoint).norm() > ZERO_TOLERANCE)) return; //test base view matrix for (unsigned i=0;i<12;++i) if (fabs(params.baseViewMat.data()[i] - m_params.baseViewMat.data()[i])>ZERO_TOLERANCE) return; //general parameters if (params.perspectiveView != m_params.perspectiveView || params.objectCenteredPerspective != m_params.objectCenteredPerspective //|| (params.pivotPoint - m_params.pivotPoint).norm() > ZERO_TOLERANCE || params.aspectRatio != m_params.aspectRatio || params.fov != m_params.fov) return; glPushAttrib(GL_LINE_BIT); //Screen pan & pivot compensation float dx=0.0f,dy=0.0f,relativeZoom=1.0f; if (!m_params.perspectiveView) { float totalZoom = m_params.zoom*m_params.globalZoom; float winTotalZoom = params.zoom*params.globalZoom; relativeZoom = winTotalZoom/totalZoom; dx = m_params.screenPan[0] - params.screenPan[0]; dy = m_params.screenPan[1] - params.screenPan[1]; CCVector3 P = m_params.pivotPoint-params.pivotPoint; m_params.baseViewMat.apply(P); dx += P.x; dy += P.y; dx *= winTotalZoom; dy *= winTotalZoom; } //thick dotted line glLineWidth(2); glLineStipple(1, 0xAAAA); glEnable(GL_LINE_STIPPLE); const colorType* defaultColor = selected ? ccColor::red : context.textDefaultCol; glColor3ubv(defaultColor); glBegin(GL_LINE_LOOP); glVertex2f(dx+m_roi[0]*relativeZoom,dy+m_roi[1]*relativeZoom); glVertex2f(dx+m_roi[2]*relativeZoom,dy+m_roi[1]*relativeZoom); glVertex2f(dx+m_roi[2]*relativeZoom,dy+m_roi[3]*relativeZoom); glVertex2f(dx+m_roi[0]*relativeZoom,dy+m_roi[3]*relativeZoom); glEnd(); glPopAttrib(); //title QString title(getName()); if (!title.isEmpty()) { QFont titleFont(context._win->getTextDisplayFont()); titleFont.setBold(true); QFontMetrics titleFontMetrics(titleFont); int titleHeight = titleFontMetrics.height(); int xStart = (int)(dx+0.5f*(float)context.glW+std::min<float>(m_roi[0],m_roi[2])*relativeZoom); int yStart = (int)(dy+0.5f*(float)context.glH+std::min<float>(m_roi[1],m_roi[3])*relativeZoom); context._win->displayText(title,xStart,yStart-5-titleHeight,false,defaultColor,titleFont); } }
//绘制点云 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 ccHObject::draw(CC_DRAW_CONTEXT& context) { if (!isEnabled()) return; bool draw3D = MACRO_Draw3D(context); bool drawInThisContext = (!m_visible && !m_selected ? false : m_currentDisplay == context._win); //no need to display anything but clouds and meshes in "point picking mode" bool DrawMesh = false; if (MACRO_DrawTriangleNames(context) && isKindOf(CC_MESH)) { ccGenericMesh *mesh = static_cast<ccGenericMesh*>(this); ccGenericPointCloud *cloud = mesh->getAssociatedCloud(); DrawMesh = (cloud == NULL || !cloud->isEnabled()); } drawInThisContext &= ( (!MACRO_DrawPointNames(context) || isKindOf(CC_POINT_CLOUD)) || (!MACRO_DrawTriangleNames(context) || DrawMesh) ); //apply 3D 'temporary' transformation (for display only) if (draw3D && m_glTransEnabled) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(m_glTrans.data()); } //draw entity if (m_visible && drawInThisContext) { if ((!m_selected || !MACRO_SkipSelected(context)) && (m_selected || !MACRO_SkipUnselected(context))) { glColor3ubv(context.pointsDefaultCol); 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 if (m_selected && draw3D && drawInThisContext) { switch (m_selectionBehavior) { case SELECTION_AA_BBOX: drawBB(context.bbDefaultCol); break; case SELECTION_FIT_BBOX: { ccGLMatrix trans; ccBBox box = getFitBB(trans); if (box.isValid()) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(trans.data()); box.draw(context.bbDefaultCol); glPopMatrix(); } } break; case SELECTION_IGNORED: break; default: assert(false); } } if (draw3D && m_glTransEnabled) glPopMatrix(); }
//override draw function void ccMouseCircle::draw(CC_DRAW_CONTEXT& context) { //only draw when visible if (!ccMouseCircle::isVisible()) return; //only draw in 2D foreground mode if (!MACRO_Foreground(context) || !MACRO_Draw2D(context)) return; //get the set of OpenGL functions (version 2.1) QOpenGLFunctions_2_1 *glFunc = context.glFunctions<QOpenGLFunctions_2_1>(); assert(glFunc != nullptr); if (glFunc == nullptr) return; //test viewport parameters const ccViewportParameters& params = context.display->getViewportParameters(); glFunc->glPushAttrib(GL_LINE_BIT); float relativeZoom = 1.0f; float dx = 0.0f; float dy = 0.0f; if (!m_params.perspectiveView) //ortho mode { //Screen pan & pivot compensation float totalZoom = m_params.zoom / m_params.pixelSize; m_winTotalZoom = params.zoom / params.pixelSize; relativeZoom = m_winTotalZoom / totalZoom; CCVector3d dC = m_params.cameraCenter - params.cameraCenter; CCVector3d P = m_params.pivotPoint - params.pivotPoint; m_params.viewMat.apply(P); static_cast<float>(dC.x + P.x); static_cast<float>(dC.y + P.y); dx *= m_winTotalZoom; dy *= m_winTotalZoom; } //thick dotted line glFunc->glLineWidth(2); glFunc->glLineStipple(1, 0xAAAA); glFunc->glEnable(GL_LINE_STIPPLE); const unsigned char* defaultColor = m_selected ? ccColor::red.rgba : context.textDefaultCol.rgb; glFunc->glColor3ubv(ccColor::red.rgba); //get height & width int halfW = static_cast<int>(context.glW / 2.0f); int halfH = static_cast<int>(context.glH / 2.0f); //get mouse position QPoint p = m_owner->asWidget()->mapFromGlobal(QCursor::pos()); int mx = p.x(); //mouse x-coord int my = 2*halfH - p.y(); //mouse y-coord in OpenGL coordinates (origin at bottom left, not top left) //calculate circle location int cx = dx+mx-halfW; int cy = dy+my-halfH; //draw circle glFunc->glBegin(GL_LINE_LOOP); for (int n = 0; n < ccMouseCircle::RESOLUTION; n++) { glFunc->glVertex2f(ccMouseCircle::UNIT_CIRCLE[n][0] * ccMouseCircle::RADIUS + cx, ccMouseCircle::UNIT_CIRCLE[n][1] * ccMouseCircle::RADIUS + cy); } glFunc->glEnd(); glFunc->glPopAttrib(); }
void ccSNECloud::drawMeOnly(CC_DRAW_CONTEXT& context) { if (!MACRO_Foreground(context)) //2D foreground only return; //do nothing //draw point cloud ccPointCloud::drawMeOnly(context); //draw normal vectors if (MACRO_Draw3D(context)) { if (size() == 0) //no points -> bail! return; //get the set of OpenGL functions (version 2.1) QOpenGLFunctions_2_1 *glFunc = context.glFunctions<QOpenGLFunctions_2_1>(); if (glFunc == nullptr) { assert(false); return; } //glDrawParams glParams; //getDrawingParameters(glParams); //get camera info ccGLCameraParameters camera; glFunc->glGetIntegerv(GL_VIEWPORT, camera.viewport); glFunc->glGetDoublev(GL_PROJECTION_MATRIX, camera.projectionMat.data()); glFunc->glGetDoublev(GL_MODELVIEW_MATRIX, camera.modelViewMat.data()); const ccViewportParameters& viewportParams = context.display->getViewportParameters(); //get point size for drawing float pSize; glFunc->glGetFloatv(GL_POINT_SIZE, &pSize); //draw normal vectors if highlighted //if ((m_isHighlighted | m_isAlternate | m_isActive)) //{ //setup if (pSize != 0) { glFunc->glPushAttrib(GL_LINE_BIT); glFunc->glLineWidth(static_cast<GLfloat>(pSize)); } glFunc->glMatrixMode(GL_MODELVIEW); glFunc->glPushMatrix(); glFunc->glEnable(GL_BLEND); //get normal vector properties int thickID = getScalarFieldIndexByName("Thickness"); //int weightID = getScalarFieldIndexByName("Weight"); //float weight; //float maxWeight = getScalarField( weightID )->getMax(); //draw normals glFunc->glBegin(GL_LINES); for (unsigned p = 0; p < size(); p++) { //get weight //weight = getScalarField(weightID)->getValue(p); //weight /= maxWeight; //push colour const ccColor::Rgb* col = m_currentDisplayedScalarField->getColor(m_currentDisplayedScalarField->getValue(p)); const ccColor::Rgba col4(col->r, col->g, col->b,200); glFunc->glColor4ubv(col4.rgba); //get length from thickness (if defined) float length = 1.0; if (thickID != -1) { length = getScalarField(thickID)->getValue(p); } //calculate start and end points of normal vector const CCVector3 start = *getPoint(p); CCVector3 end = start + (getPointNormal(p)*length); //push line to opengl ccGL::Vertex3v(glFunc, start.u); ccGL::Vertex3v(glFunc, end.u); } glFunc->glEnd(); //cleanup if (pSize != 0) { glFunc->glPopAttrib(); } glFunc->glPopMatrix(); } }
void ccHObject::draw(CC_DRAW_CONTEXT& context) { if (!isEnabled()) return; //get the set of OpenGL functions (version 2.1) QOpenGLFunctions_2_1 *glFunc = context.glFunctions<QOpenGLFunctions_2_1>(); assert( glFunc != nullptr ); if ( glFunc == nullptr ) 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.display); if (draw3D) { //apply 3D 'temporary' transformation (for display only) if (m_glTransEnabled) { glFunc->glMatrixMode(GL_MODELVIEW); glFunc->glPushMatrix(); glFunc->glMultMatrixf(m_glTrans.data()); } //LOD for clouds is enabled? if ( context.decimateCloudOnMove && context.currentLODLevel > 0) { //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(glFunc, context.pointsDefaultCol.rgb); //enable clipping planes (if any) bool useClipPlanes = (draw3D && !m_clipPlanes.empty()); if (useClipPlanes) { toggleClipPlanes(context, true); } drawMeOnly(context); //disable clipping planes (if any) if (useClipPlanes) { toggleClipPlanes(context, false); } //draw name in 3D (we display it in the 2D foreground layer in fact!) if (m_showNameIn3D && MACRO_Draw2D(context) && MACRO_Foreground(context) && !MACRO_DrawEntityNames(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_DrawEntityNames(context) && context.currentLODLevel == 0) { drawBB(context, context.bbDefaultCol); } if (draw3D && m_glTransEnabled) glFunc->glPopMatrix(); }
void cc2DViewportLabel::drawMeOnly(CC_DRAW_CONTEXT& context) { //2D foreground only if (!MACRO_Foreground(context) || !MACRO_Draw2D(context)) return; //get the set of OpenGL functions (version 2.1) QOpenGLFunctions_2_1 *glFunc = context.glFunctions<QOpenGLFunctions_2_1>(); assert( glFunc != nullptr ); if ( glFunc == nullptr ) return; //test viewport parameters const ccViewportParameters& params = context.display->getViewportParameters(); //general parameters if ( params.perspectiveView != m_params.perspectiveView || params.objectCenteredView != m_params.objectCenteredView || params.pixelSize != m_params.pixelSize) { return; } //test base view matrix for (unsigned i = 0; i < 12; ++i) if (fabs(params.viewMat.data()[i] - m_params.viewMat.data()[i]) > ZERO_TOLERANCE) return; if (m_params.perspectiveView) { if (params.fov != m_params.fov || params.perspectiveAspectRatio != m_params.perspectiveAspectRatio) return; if ((params.pivotPoint - m_params.pivotPoint).norm() > ZERO_TOLERANCE || (params.cameraCenter - m_params.cameraCenter).norm() > ZERO_TOLERANCE) return; } else { if (params.orthoAspectRatio != m_params.orthoAspectRatio) return; } glFunc->glPushAttrib(GL_LINE_BIT); float relativeZoom = 1.0f; float dx = 0, dy = 0; if (!m_params.perspectiveView) //ortho mode { //Screen pan & pivot compensation float totalZoom = m_params.zoom / m_params.pixelSize; float winTotalZoom = params.zoom / params.pixelSize; relativeZoom = winTotalZoom / totalZoom; CCVector3d dC = m_params.cameraCenter - params.cameraCenter; CCVector3d P = m_params.pivotPoint - params.pivotPoint; m_params.viewMat.apply(P); dx = static_cast<float>(dC.x + P.x); dy = static_cast<float>(dC.y + P.y); dx *= winTotalZoom; dy *= winTotalZoom; } //thick dotted line glFunc->glLineWidth(2); glFunc->glLineStipple(1, 0xAAAA); glFunc->glEnable(GL_LINE_STIPPLE); const unsigned char* defaultColor = m_selected ? ccColor::red.rgba : context.textDefaultCol.rgb; glFunc->glColor3ubv(defaultColor); glFunc->glBegin(GL_LINE_LOOP); glFunc->glVertex2f(dx + m_roi[0] * relativeZoom, dy + m_roi[1] * relativeZoom); glFunc->glVertex2f(dx + m_roi[2] * relativeZoom, dy + m_roi[1] * relativeZoom); glFunc->glVertex2f(dx + m_roi[2] * relativeZoom, dy + m_roi[3] * relativeZoom); glFunc->glVertex2f(dx + m_roi[0] * relativeZoom, dy + m_roi[3] * relativeZoom); glFunc->glEnd(); glFunc->glPopAttrib(); //title QString title(getName()); if (!title.isEmpty()) { QFont titleFont(context.display->getTextDisplayFont()); //takes rendering zoom into account! titleFont.setBold(true); QFontMetrics titleFontMetrics(titleFont); int titleHeight = titleFontMetrics.height(); int xStart = (int)(dx + 0.5f*(float)context.glW + std::min<float>(m_roi[0], m_roi[2])*relativeZoom); int yStart = (int)(dy + 0.5f*(float)context.glH + std::min<float>(m_roi[1], m_roi[3])*relativeZoom); context.display->displayText(title, xStart, yStart - 5 - titleHeight, ccGenericGLDisplay::ALIGN_DEFAULT, 0, defaultColor, &titleFont); } }