CloudCompare源码_显示渲染的程序架构
这一讲介绍一下CloudCompare的大致绘制流程或者说绘图框架的结构。
根据前面一篇对CloudCompare读取PLY文件的介绍 ,很容易找出当cloudcompare读取到mesh文件(newGroup)后,会把这个文件通过addDB加载到根对象下面,
-
//ref. mainwindow.cpp
-
void MainWindow::addToDB( const QStringList& filenames,
-
QString fileFilter/*=QString()*/,
-
ccGLWindow* destWin/*=nullptr*/)
-
{
-
addToDB(newGroup, true, true, false);
-
....
-
}
-
-
-
-
void MainWindow::addToDB( ccHObject* obj,
-
bool updateZoom/*=true*/,
-
bool autoExpandDBTree/*=true*/,
-
bool checkDimensions/*=true*/,
-
bool autoRedraw/*=true*/)
-
{
-
......
-
//add object to DB root
-
if (m_ccRoot)
-
{
-
//force a 'global zoom' if the DB was emtpy!
-
if (!m_ccRoot->getRootEntity() || m_ccRoot->getRootEntity()->getChildrenNumber() == 0)
-
{
-
updateZoom = true;
-
}
-
m_ccRoot->addElement(obj, autoExpandDBTree);
-
}
-
......
-
}
这个根对象,就是ccDBRoot,
-
//ref. ccDBRoot.h
-
//! GUI database tree root
-
class ccDBRoot : public QAbstractItemModel
-
{
-
Q_OBJECT
-
-
//! Associated DB root
-
ccHObject* m_treeRoot;
-
-
//! Associated widget for DB tree
-
QTreeView* m_dbTreeWidget;
-
-
//! Associated widget for selected entity's properties tree
-
QTreeView* m_propertiesTreeWidget;
-
-
//! Selected entity's properties data model
-
QStandardItemModel* m_propertiesModel;
-
//! Selected entity's properties delegate
-
ccPropertiesTreeDelegate* m_ccPropDelegate;
-
......
-
}
其内部定义了一个ccHObject的指针,m_treeRoot,最终用来容纳子对像
-
void ccDBRoot::addElement(ccHObject* object, bool autoExpand/*=true*/)
-
{
-
......
-
//look for object's parent
-
ccHObject* parentObject = object->getParent();
-
if (!parentObject)
-
{
-
//if the object has no parent, it will be inserted at tree root
-
parentObject = m_treeRoot;
-
m_treeRoot->addChild(object);
-
}
-
-
......
-
}
当然,这些都不是重点。重点是:CloudCompare是如何完成3D渲染的,相关的OpenGL函数,或者是Qt的OpenGL相关函数又封装在哪里?
下面我们慢慢来看。
相关的OpenGL函数在哪里?
OpenGL扩展函数
首先我们来看OpenGLExtensions,这些函数也就是OpenGL的扩展函数。
比如我的目录是这样的,
C:\Qt\qt5\5.15.0\msvc2019_64\include\QtOpenGLExtensions\qopenglextensions.h
在这个头文件中,不同的类封装了大量的OpenGL函数,例如,
-
class QOpenGLExtension_ARB_framebuffer_object : public QAbstractOpenGLExtension
-
{
-
public:
-
QOpenGLExtension_ARB_framebuffer_object();
-
-
bool initializeOpenGLFunctions() final;
-
-
void glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
-
void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
-
void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
-
void glGenerateMipmap(GLenum target);
-
void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params);
-
void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
-
void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
-
void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-
void glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-
GLenum glCheckFramebufferStatus(GLenum target);
-
void glGenFramebuffers(GLsizei n, GLuint *framebuffers);
-
void glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
-
void glBindFramebuffer(GLenum target, GLuint framebuffer);
-
GLboolean glIsFramebuffer(GLuint framebuffer);
-
void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params);
-
void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-
void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers);
-
void glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers);
-
void glBindRenderbuffer(GLenum target, GLuint renderbuffer);
-
GLboolean glIsRenderbuffer(GLuint renderbuffer);
-
-
protected:
-
Q_DECLARE_PRIVATE(QOpenGLExtension_ARB_framebuffer_object)
-
};
又例如,
-
class QOpenGLExtension_ARB_gpu_shader_fp64 : public QAbstractOpenGLExtension
-
{
-
public:
-
QOpenGLExtension_ARB_gpu_shader_fp64();
-
-
bool initializeOpenGLFunctions() final;
-
-
void glGetUniformdv(GLuint program, GLint location, GLdouble *params);
-
void glUniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
-
void glUniform4dv(GLint location, GLsizei count, const GLdouble *value);
-
void glUniform3dv(GLint location, GLsizei count, const GLdouble *value);
-
void glUniform2dv(GLint location, GLsizei count, const GLdouble *value);
-
void glUniform1dv(GLint location, GLsizei count, const GLdouble *value);
-
void glUniform4d(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
-
void glUniform3d(GLint location, GLdouble x, GLdouble y, GLdouble z);
-
void glUniform2d(GLint location, GLdouble x, GLdouble y);
-
void glUniform1d(GLint location, GLdouble x);
-
-
protected:
-
Q_DECLARE_PRIVATE(QOpenGLExtension_ARB_gpu_shader_fp64)
-
};
这样的函数还有非常多,这里我就不一个一个地列举了。如果要详细了解的话,可以参考相关文档,例如,上面两个类的第一个函数分别可参考,
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
由于这些类中包含的函数体量过大,这里我只贴了部分源码,如下,
-
class Q_GUI_EXPORT QOpenGLFunctions_4_5_Core : public QAbstractOpenGLFunctions
-
{
-
public:
-
QOpenGLFunctions_4_5_Core();
-
~QOpenGLFunctions_4_5_Core();
-
-
bool initializeOpenGLFunctions() override;
-
-
// OpenGL 1.0 core functions
-
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
-
void glDepthRange(GLdouble nearVal, GLdouble farVal);
-
GLboolean glIsEnabled(GLenum cap);
-
void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params);
-
void glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params);
-
void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params);
-
void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
-
void glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
-
const GLubyte * glGetString(GLenum name);
-
void glGetIntegerv(GLenum pname, GLint *data);
-
void glGetFloatv(GLenum pname, GLfloat *data);
-
GLenum glGetError();
-
void glGetDoublev(GLenum pname, GLdouble *data);
-
void glGetBooleanv(GLenum pname, GLboolean *data);
-
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
-
void glReadBuffer(GLenum src);
-
void glPixelStorei(GLenum pname, GLint param);
-
void glPixelStoref(GLenum pname, GLfloat param);
-
void glDepthFunc(GLenum func);
-
void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
-
void glStencilFunc(GLenum func, GLint ref, GLuint mask);
-
void glLogicOp(GLenum opcode);
-
void glBlendFunc(GLenum sfactor, GLenum dfactor);
-
void glFlush();
-
void glFinish();
-
void glEnable(GLenum cap);
-
void glDisable(GLenum cap);
-
void glDepthMask(GLboolean flag);
-
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
-
void glStencilMask(GLuint mask);
-
void glClearDepth(GLdouble depth);
-
void glClearStencil(GLint s);
-
void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
-
void glClear(GLbitfield mask);
-
void glDrawBuffer(GLenum buf);
-
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
-
void glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels);
-
void glTexParameteriv(GLenum target, GLenum pname, const GLint *params);
-
void glTexParameteri(GLenum target, GLenum pname, GLint param);
-
void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params);
-
void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
-
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
-
void glPolygonMode(GLenum face, GLenum mode);
-
void glPointSize(GLfloat size);
-
void glLineWidth(GLfloat width);
-
void glHint(GLenum target, GLenum mode);
-
void glFrontFace(GLenum mode);
-
void glCullFace(GLenum mode);
-
......
-
}
以
libs\qCC_glWindow\src\ccGLUtils.cpp
中了函数
DisplayTexture2DPosition
为例,其中通过QOpenGLFunctions_2_1调用了OpenGLES2.1中的函数完成相关功能,
-
void ccGLUtils::DisplayTexture2DPosition(GLuint texID, int x, int y, int w, int h, unsigned char alpha/*=255*/)
-
{
-
QOpenGLContext* context = QOpenGLContext::currentContext();
-
if (!context)
-
{
-
assert(false);
-
return;
-
}
-
QOpenGLFunctions_2_1* glFunc = context->versionFunctions<QOpenGLFunctions_2_1>();
-
if (glFunc)
-
{
-
glFunc->glBindTexture(GL_TEXTURE_2D, texID);
-
-
glFunc->glPushAttrib(GL_ENABLE_BIT);
-
glFunc->glEnable(GL_TEXTURE_2D);
-
-
glFunc->glColor4ub(255, 255, 255, alpha);
-
glFunc->glBegin(GL_QUADS);
-
glFunc->glTexCoord2f(0.0, 1.0);
-
glFunc->glVertex2i(x, y h);
-
glFunc->glTexCoord2f(0.0, 0.0);
-
glFunc->glVertex2i(x, y);
-
glFunc->glTexCoord2f(1.0, 0.0);
-
glFunc->glVertex2i(x w, y);
-
glFunc->glTexCoord2f(1.0, 1.0);
-
glFunc->glVertex2i(x w, y h);
-
glFunc->glEnd();
-
-
glFunc->glPopAttrib();
-
-
glFunc->glBindTexture(GL_TEXTURE_2D, 0);
-
}
-
}
同样,在
.\libs\qCC_glWindow\src\ccGLWindow.cpp
中,对3D的渲染使用的也是QOpenGLFunctions_2_1,源码如下,
-
//Default OpenGL functions set
-
using ccQOpenGLFunctions = QOpenGLFunctions_2_1;
-
-
void ccGLWindow::draw3D(CC_DRAW_CONTEXT& CONTEXT, RenderingParams& renderingParams)
-
{
-
ccQOpenGLFunctions* glFunc = functions();
-
assert(glFunc);
-
-
glFunc->glPointSize(m_viewportParams.defaultPointSize);
-
glFunc->glLineWidth(m_viewportParams.defaultLineWidth);
-
-
glFunc->glEnable(GL_DEPTH_TEST);
-
......
-
-
}
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中,
-
//Definition
-
-
class QCC_DB_LIB_API ccHObject : public ccObject, public ccDrawableObject
-
{
-
public: //construction
-
......
-
//! Standard instances container (for children, etc.)
-
using Container = std::vector<ccHObject *>;
-
......
-
//! Children
-
Container m_children;
-
......
-
}
所以在ccHObject中,绘制函数是
-
void ccHObject::draw(CC_DRAW_CONTEXT& context)
-
{
-
......
-
//draw entity
-
if (m_visible && drawInThisContext)
-
{
-
if (( !m_selected || !MACRO_SkipSelected(context) ) &&
-
( m_selected || !MACRO_SkipUnselected(context) ))
-
{
-
//apply default color (in case of)
-
ccGL::Color4v(glFunc, context.pointsDefaultCol.rgba);
-
-
//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 entity's children
-
for (auto child : m_children)
-
{
-
child->draw(context);
-
}
-
......
-
}
这是一个递归调用函数,当要对mesh进行绘制的时候,会调用下面的这个drawMeOnly函数,这也就是Mesh的最终绘制函数,顶点和面的计算都在这里进行。
void ccMesh::drawMeOnly(CC_DRAW_CONTEXT& context)
该函数因为内容比较多,这里就不展开了,有兴趣的读者不妨自己打开看看源码。
好了,到现在为止,我们对CloudCompare的大致绘制流程或者说框架已经有了 一个初略的了解,后面有机会我们进一步深入。
本文结束。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfejbb
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01