• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

CloudCompare源码_显示渲染的程序架构

武飞扬头像
高精度计算机视觉
帮助1

这一讲介绍一下CloudCompare的大致绘制流程或者说绘图框架的结构。

根据前面一篇对CloudCompare读取PLY文件的介绍 ,很容易找出当cloudcompare读取到mesh文件(newGroup)后,会把这个文件通过addDB加载到根对象下面,

  1.  
    //ref. mainwindow.cpp
  2.  
    void MainWindow::addToDB( const QStringList& filenames,
  3.  
    QString fileFilter/*=QString()*/,
  4.  
    ccGLWindow* destWin/*=nullptr*/)
  5.  
    {
  6.  
    addToDB(newGroup, true, true, false);
  7.  
    ....
  8.  
    }
  9.  
     
  10.  
     
  11.  
     
  12.  
    void MainWindow::addToDB( ccHObject* obj,
  13.  
    bool updateZoom/*=true*/,
  14.  
    bool autoExpandDBTree/*=true*/,
  15.  
    bool checkDimensions/*=true*/,
  16.  
    bool autoRedraw/*=true*/)
  17.  
    {
  18.  
    ......
  19.  
    //add object to DB root
  20.  
    if (m_ccRoot)
  21.  
    {
  22.  
    //force a 'global zoom' if the DB was emtpy!
  23.  
    if (!m_ccRoot->getRootEntity() || m_ccRoot->getRootEntity()->getChildrenNumber() == 0)
  24.  
    {
  25.  
    updateZoom = true;
  26.  
    }
  27.  
    m_ccRoot->addElement(obj, autoExpandDBTree);
  28.  
    }
  29.  
    ......
  30.  
    }

这个根对象,就是ccDBRoot,

  1.  
    //ref. ccDBRoot.h
  2.  
    //! GUI database tree root
  3.  
    class ccDBRoot : public QAbstractItemModel
  4.  
    {
  5.  
    Q_OBJECT
  6.  
     
  7.  
    //! Associated DB root
  8.  
    ccHObject* m_treeRoot;
  9.  
     
  10.  
    //! Associated widget for DB tree
  11.  
    QTreeView* m_dbTreeWidget;
  12.  
     
  13.  
    //! Associated widget for selected entity's properties tree
  14.  
    QTreeView* m_propertiesTreeWidget;
  15.  
     
  16.  
    //! Selected entity's properties data model
  17.  
    QStandardItemModel* m_propertiesModel;
  18.  
    //! Selected entity's properties delegate
  19.  
    ccPropertiesTreeDelegate* m_ccPropDelegate;
  20.  
    ......
  21.  
    }

其内部定义了一个ccHObject的指针,m_treeRoot,最终用来容纳子对像

  1.  
    void ccDBRoot::addElement(ccHObject* object, bool autoExpand/*=true*/)
  2.  
    {
  3.  
    ......
  4.  
    //look for object's parent
  5.  
    ccHObject* parentObject = object->getParent();
  6.  
    if (!parentObject)
  7.  
    {
  8.  
    //if the object has no parent, it will be inserted at tree root
  9.  
    parentObject = m_treeRoot;
  10.  
    m_treeRoot->addChild(object);
  11.  
    }
  12.  
     
  13.  
    ......
  14.  
    }

当然,这些都不是重点。重点是:CloudCompare是如何完成3D渲染的,相关的OpenGL函数,或者是Qt的OpenGL相关函数又封装在哪里?

下面我们慢慢来看。

相关的OpenGL函数在哪里?

OpenGL扩展函数

首先我们来看OpenGLExtensions,这些函数也就是OpenGL的扩展函数。

比如我的目录是这样的,

C:\Qt\qt5\5.15.0\msvc2019_64\include\QtOpenGLExtensions\qopenglextensions.h

在这个头文件中,不同的类封装了大量的OpenGL函数,例如,

  1.  
    class QOpenGLExtension_ARB_framebuffer_object : public QAbstractOpenGLExtension
  2.  
    {
  3.  
    public:
  4.  
    QOpenGLExtension_ARB_framebuffer_object();
  5.  
     
  6.  
    bool initializeOpenGLFunctions() final;
  7.  
     
  8.  
    void glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
  9.  
    void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
  10.  
    void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
  11.  
    void glGenerateMipmap(GLenum target);
  12.  
    void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params);
  13.  
    void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
  14.  
    void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
  15.  
    void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
  16.  
    void glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
  17.  
    GLenum glCheckFramebufferStatus(GLenum target);
  18.  
    void glGenFramebuffers(GLsizei n, GLuint *framebuffers);
  19.  
    void glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
  20.  
    void glBindFramebuffer(GLenum target, GLuint framebuffer);
  21.  
    GLboolean glIsFramebuffer(GLuint framebuffer);
  22.  
    void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params);
  23.  
    void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
  24.  
    void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers);
  25.  
    void glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers);
  26.  
    void glBindRenderbuffer(GLenum target, GLuint renderbuffer);
  27.  
    GLboolean glIsRenderbuffer(GLuint renderbuffer);
  28.  
     
  29.  
    protected:
  30.  
    Q_DECLARE_PRIVATE(QOpenGLExtension_ARB_framebuffer_object)
  31.  
    };

又例如,

  1.  
    class QOpenGLExtension_ARB_gpu_shader_fp64 : public QAbstractOpenGLExtension
  2.  
    {
  3.  
    public:
  4.  
    QOpenGLExtension_ARB_gpu_shader_fp64();
  5.  
     
  6.  
    bool initializeOpenGLFunctions() final;
  7.  
     
  8.  
    void glGetUniformdv(GLuint program, GLint location, GLdouble *params);
  9.  
    void glUniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  10.  
    void glUniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  11.  
    void glUniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  12.  
    void glUniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  13.  
    void glUniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  14.  
    void glUniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  15.  
    void glUniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  16.  
    void glUniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  17.  
    void glUniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
  18.  
    void glUniform4dv(GLint location, GLsizei count, const GLdouble *value);
  19.  
    void glUniform3dv(GLint location, GLsizei count, const GLdouble *value);
  20.  
    void glUniform2dv(GLint location, GLsizei count, const GLdouble *value);
  21.  
    void glUniform1dv(GLint location, GLsizei count, const GLdouble *value);
  22.  
    void glUniform4d(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
  23.  
    void glUniform3d(GLint location, GLdouble x, GLdouble y, GLdouble z);
  24.  
    void glUniform2d(GLint location, GLdouble x, GLdouble y);
  25.  
    void glUniform1d(GLint location, GLdouble x);
  26.  
     
  27.  
    protected:
  28.  
    Q_DECLARE_PRIVATE(QOpenGLExtension_ARB_gpu_shader_fp64)
  29.  
    };

这样的函数还有非常多,这里我就不一个一个地列举了。如果要详细了解的话,可以参考相关文档,例如,上面两个类的第一个函数分别可参考,

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glFramebufferTextureLayer.xhtml

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetUniform.xhtml

相关的函数在QCC_GL_LIB项目中用到,我们可以在CloudCompare的子项目中找到,目录地址是

libs\CCFbo\include

OpenGL各版本的函数

在Qt的源码中,这些函数的目录地址是,

qt5\5.15.0\msvc2019_64\include\QtGui\

例如我的本地地址,对应OpenGL4.5版本的函数地址是,

C:\Qt\qt5\5.15.0\msvc2019_64\include\QtGui\qopenglfunctions_4_5_core.h

由于这些类中包含的函数体量过大,这里我只贴了部分源码,如下,

  1.  
    class Q_GUI_EXPORT QOpenGLFunctions_4_5_Core : public QAbstractOpenGLFunctions
  2.  
    {
  3.  
    public:
  4.  
    QOpenGLFunctions_4_5_Core();
  5.  
    ~QOpenGLFunctions_4_5_Core();
  6.  
     
  7.  
    bool initializeOpenGLFunctions() override;
  8.  
     
  9.  
    // OpenGL 1.0 core functions
  10.  
    void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
  11.  
    void glDepthRange(GLdouble nearVal, GLdouble farVal);
  12.  
    GLboolean glIsEnabled(GLenum cap);
  13.  
    void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params);
  14.  
    void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params);
  15.  
    void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params);
  16.  
    void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
  17.  
    void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
  18.  
    const GLubyte * glGetString(GLenum name);
  19.  
    void glGetIntegerv(GLenum pname, GLint *data);
  20.  
    void glGetFloatv(GLenum pname, GLfloat *data);
  21.  
    GLenum glGetError();
  22.  
    void glGetDoublev(GLenum pname, GLdouble *data);
  23.  
    void glGetBooleanv(GLenum pname, GLboolean *data);
  24.  
    void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
  25.  
    void glReadBuffer(GLenum src);
  26.  
    void glPixelStorei(GLenum pname, GLint param);
  27.  
    void glPixelStoref(GLenum pname, GLfloat param);
  28.  
    void glDepthFunc(GLenum func);
  29.  
    void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
  30.  
    void glStencilFunc(GLenum func, GLint ref, GLuint mask);
  31.  
    void glLogicOp(GLenum opcode);
  32.  
    void glBlendFunc(GLenum sfactor, GLenum dfactor);
  33.  
    void glFlush();
  34.  
    void glFinish();
  35.  
    void glEnable(GLenum cap);
  36.  
    void glDisable(GLenum cap);
  37.  
    void glDepthMask(GLboolean flag);
  38.  
    void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
  39.  
    void glStencilMask(GLuint mask);
  40.  
    void glClearDepth(GLdouble depth);
  41.  
    void glClearStencil(GLint s);
  42.  
    void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
  43.  
    void glClear(GLbitfield mask);
  44.  
    void glDrawBuffer(GLenum buf);
  45.  
    void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
  46.  
    void glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);
  47.  
    void glTexParameteriv(GLenum target, GLenum pname, const GLint *params);
  48.  
    void glTexParameteri(GLenum target, GLenum pname, GLint param);
  49.  
    void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params);
  50.  
    void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
  51.  
    void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
  52.  
    void glPolygonMode(GLenum face, GLenum mode);
  53.  
    void glPointSize(GLfloat size);
  54.  
    void glLineWidth(GLfloat width);
  55.  
    void glHint(GLenum target, GLenum mode);
  56.  
    void glFrontFace(GLenum mode);
  57.  
    void glCullFace(GLenum mode);
  58.  
    ......
  59.  
    }

libs\qCC_glWindow\src\ccGLUtils.cpp中了函数

DisplayTexture2DPosition

为例,其中通过QOpenGLFunctions_2_1调用了OpenGLES2.1中的函数完成相关功能,

  1.  
    void ccGLUtils::DisplayTexture2DPosition(GLuint texID, int x, int y, int w, int h, unsigned char alpha/*=255*/)
  2.  
    {
  3.  
    QOpenGLContext* context = QOpenGLContext::currentContext();
  4.  
    if (!context)
  5.  
    {
  6.  
    assert(false);
  7.  
    return;
  8.  
    }
  9.  
    QOpenGLFunctions_2_1* glFunc = context->versionFunctions<QOpenGLFunctions_2_1>();
  10.  
    if (glFunc)
  11.  
    {
  12.  
    glFunc->glBindTexture(GL_TEXTURE_2D, texID);
  13.  
     
  14.  
    glFunc->glPushAttrib(GL_ENABLE_BIT);
  15.  
    glFunc->glEnable(GL_TEXTURE_2D);
  16.  
     
  17.  
    glFunc->glColor4ub(255, 255, 255, alpha);
  18.  
    glFunc->glBegin(GL_QUADS);
  19.  
    glFunc->glTexCoord2f(0.0, 1.0);
  20.  
    glFunc->glVertex2i(x, y h);
  21.  
    glFunc->glTexCoord2f(0.0, 0.0);
  22.  
    glFunc->glVertex2i(x, y);
  23.  
    glFunc->glTexCoord2f(1.0, 0.0);
  24.  
    glFunc->glVertex2i(x w, y);
  25.  
    glFunc->glTexCoord2f(1.0, 1.0);
  26.  
    glFunc->glVertex2i(x w, y h);
  27.  
    glFunc->glEnd();
  28.  
     
  29.  
    glFunc->glPopAttrib();
  30.  
     
  31.  
    glFunc->glBindTexture(GL_TEXTURE_2D, 0);
  32.  
    }
  33.  
    }

同样,在

.\libs\qCC_glWindow\src\ccGLWindow.cpp

中,对3D的渲染使用的也是QOpenGLFunctions_2_1,源码如下,

  1.  
    //Default OpenGL functions set
  2.  
    using ccQOpenGLFunctions = QOpenGLFunctions_2_1;
  3.  
     
  4.  
    void ccGLWindow::draw3D(CC_DRAW_CONTEXT& CONTEXT, RenderingParams& renderingParams)
  5.  
    {
  6.  
    ccQOpenGLFunctions* glFunc = functions();
  7.  
    assert(glFunc);
  8.  
     
  9.  
    glFunc->glPointSize(m_viewportParams.defaultPointSize);
  10.  
    glFunc->glLineWidth(m_viewportParams.defaultLineWidth);
  11.  
     
  12.  
    glFunc->glEnable(GL_DEPTH_TEST);
  13.  
    ......
  14.  
     
  15.  
    }

CloudCompare是如何完成3D渲染的

在cloudcompare中,有一个轻量级的项目,ccViewer,如果想了解渲染的话,单看这个就够了。

渲染的函数路线如下,

ccGLWindow:

void ccGLWindow::paintGL() -->

ccGLWindow::fullRenderingPass(CONTEXT, renderingParams); -->

ccGLWindow::draw3D(CONTEXT, renderingParams); -->

ccGLWindow::drawCross()

这里,主体的绘图函数其实就是

void ccGLWindow::draw3D(CC_DRAW_CONTEXT& context, RenderingParams& params);

在该函数中,最终会调用ccHObject::draw进行绘制,

ccHObject:

ccGLWindow::draw3D(CONTEXT, renderingParams); -->

void ccHObject::draw(CC_DRAW_CONTEXT& context)

前一讲已经介绍过,打开一个mesh的时候,最终是加入到ccHObject中的container,因为打开的mesh本身也是一个ccHObject,所以实际上就是放在其m_children中,

  1.  
    //Definition
  2.  
     
  3.  
    class QCC_DB_LIB_API ccHObject : public ccObject, public ccDrawableObject
  4.  
    {
  5.  
    public: //construction
  6.  
    ......
  7.  
    //! Standard instances container (for children, etc.)
  8.  
    using Container = std::vector<ccHObject *>;
  9.  
    ......
  10.  
    //! Children
  11.  
    Container m_children;
  12.  
    ......
  13.  
    }

所以在ccHObject中,绘制函数是

  1.  
    void ccHObject::draw(CC_DRAW_CONTEXT& context)
  2.  
    {
  3.  
    ......
  4.  
    //draw entity
  5.  
    if (m_visible && drawInThisContext)
  6.  
    {
  7.  
    if (( !m_selected || !MACRO_SkipSelected(context) ) &&
  8.  
    ( m_selected || !MACRO_SkipUnselected(context) ))
  9.  
    {
  10.  
    //apply default color (in case of)
  11.  
    ccGL::Color4v(glFunc, context.pointsDefaultCol.rgba);
  12.  
     
  13.  
    //enable clipping planes (if any)
  14.  
    bool useClipPlanes = (draw3D && !m_clipPlanes.empty());
  15.  
    if (useClipPlanes)
  16.  
    {
  17.  
    toggleClipPlanes(context, true);
  18.  
    }
  19.  
     
  20.  
    drawMeOnly(context);
  21.  
     
  22.  
    //disable clipping planes (if any)
  23.  
    if (useClipPlanes)
  24.  
    {
  25.  
    toggleClipPlanes(context, false);
  26.  
    }
  27.  
    }
  28.  
    }
  29.  
    ......
  30.  
    //draw entity's children
  31.  
    for (auto child : m_children)
  32.  
    {
  33.  
    child->draw(context);
  34.  
    }
  35.  
    ......
  36.  
    }

这是一个递归调用函数,当要对mesh进行绘制的时候,会调用下面的这个drawMeOnly函数,这也就是Mesh的最终绘制函数,顶点和面的计算都在这里进行。

void ccMesh::drawMeOnly(CC_DRAW_CONTEXT& context)

该函数因为内容比较多,这里就不展开了,有兴趣的读者不妨自己打开看看源码。

好了,到现在为止,我们对CloudCompare的大致绘制流程或者说框架已经有了 一个初略的了解,后面有机会我们进一步深入。

本文结束。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfejbb
系列文章
更多 icon
同类精品
更多 icon
继续加载