基于QT的CHAI3D开发框架搭建

    科技2022-07-11  105

    基于QT的CHAI3D开发框架搭建

    CHAI3D简介

    CHI3D(计算机触觉和主动界面)是一个开放的C++库,用于计算机触觉、可视化和交互式实时仿真。CHAI3D最初是在斯坦福大学的人工智能实验室开始的,它的开发目的是提供一个简单而紧凑的框架,将实验触觉引入研究领域。在瑞士EPFL和意大利锡耶纳大学的进一步贡献下,CHAI3D的第一个公开版本于2004年发布。CHAI3D完全是用C++编写的,它的设计是为了使开发者更容易和更直观地创建将3D建模与力反馈渲染能力相结合的应用。通过支持不同类型的力反馈设备,CHAI3D提供了一个独特的界面,可以轻松地设计和部署先进的计算机触觉应用程序。 多年来,CHAI3D已经成为最流行的开源多平台触觉绘制框架之一,并在游戏、模拟器、教育软件、交互艺术、科学可视化和医疗应用等多个领域得到了大量的研究和生产项目。 CHAI3D结合了大量的力渲染算法,包括手指代理模型、势场和基于隐式的模型,程序员可以轻松地开发具有集成触觉能力的复杂仿真。该框架还提供了创建包含静态、动态和铰接体的多级场景图所需的必要数据结构。基于OpenGL的轻量级图形引擎为使用专用3D图形加速硬件轻松渲染虚拟环境提供了基础。对象网格、隐式形状、体积、表面材质和纹理属性都用组织良好的类来表示,程序员可以轻松地扩展这些类来包含更高级或特定于应用程序的特性。CHAI3D还支持从专业应用程序(如Autodesk 3D Studio Max和Alias Wavefront)导入三维文件。 对第三方组件的支持是通过有组织的扩展模块实现的,这些模块独立地补充了CHAI3D核心元素的功能。扩展模块包括ODE和GEL dynamics引擎的包装器,使得实时模拟刚性和可变形物体成为可能。CHAI3D还支持各种商用的三自由度、六自由度和七自由度触觉设备,使支持新的定制力反馈设备变得简单。由于其轻量级和模块化的体系结构,CHAI3D可以很容易地与第三方库(包括图形或动态引擎)相结合。

    CHAI3D-3.2.0简介

    CHAI3D是一套基于OpenGL的3D仿真库,chai3d(Version3.2)是基于GLFW+GLEW进行的OpenGL扩展开发,熟悉OPENGL的读者应该知道这两个库。

    GLFW是一套专门针对OpenGL开发的窗口管理类库,同时也是目前进行OpenGL开发最流行的窗口管理库,它支持Linux和Windows。GLFW 主要用来处理特定操作系统下的特定任务,除了管理OpenGL窗体、还提供了分辨率切换、键盘、鼠标以及游戏手柄、定时器输入、线程创建等等功能。其替代品包括glut,freeglut等,另外在Windows上还可以直接使用包括MFC和QT来管理OpenGL窗体。

    GLEW是一个跨平台的C++扩展库,基于OpenGL图形接口。使用OpenGL的朋友都知道,window目前只支持OpenGL1.1的涵数,但OpenGL现在都发展到2.0以上了,要使用这些OpenGL的高级特性,就必须下载最新的扩展,另外,不同的显卡公司,也会发布一些只有自家显卡才支 持的扩展函数,你要想用这数涵数,不得不去寻找最新的glext.h,有了GLEW扩展库,你就再也不用为找不到函数的接口而烦恼,因为GLEW能自动识别你的平台所支持的全部OpenGL高级扩展涵数。也就是说,只要包含一个glew.h头文件,你就能使用gl,glu,glext,wgl,glx的全 部函数。GLEW支持目前流行的各种操作系统(包括Windows, Linux, Mac OS X, FreeBSD, Irix, and Solaris)。当前最新的用来访问OpenGL规范接口的第三方库是GLAD,但chai3d3.2中使用的还是GLEW。 注意: 目前GLEW不支持OpenGL 的核心渲染模式。如果我们使用GLEW来进行OpenGL开发(包括OpenGL),必须将OpenGL的上下文环境配置成为立即渲染模式。至于OpenGL核心渲染模式和立即渲染模式的不同,这里不做过多解释,感兴趣的读者可以自行百度。GLFW的配置方法如下:

    glfwInit(); //glfw初始化 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //设置OpenGL主版本号 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //OpenGL副版本号 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);//设置立即渲染模式 //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//核心渲染模式

    基于QT进行CHAI3D开发

    QT为我们提供了现成的OpenGL窗口管理类QOpenGLWidget类,QOpenGLExtraFunctions和QOpenGLFunctions_3_3_Core,在使用QT进行CHAI3D开发过程中我们直接使用QOpenGLWidget类代替GLFW,使用QT提供的QOpenGLExtraFunctions和QOpenGLFunctions_3_3_Core访问OpenGL规范接口(支持核心渲染),用以代替GLEW。因此使用QT开发CHAI3D十分方便。

    环境配置

    开发环境:VS2019+QT VS Tools2.6.0+QT5.12.6 msvc2017_64+CHAI3D_3.2.0

    步骤1:新建QT工程,这里我们直接选择的空项目,当然也可以直接选择新建一个QtWidget项目; 新建工程结束后为QT添加opengl支持模块,右键解决方案->属性->Qt Project Settings->Qt Modules,选择core,gui,opengl,openglextensions,widgets,也可以在新建Widget工程时直接选择这些模块。 步骤2:配置C/C++属性,进行这一步之前项目中必须有C/C++源文件。

    配置附加C/C++包含目录,其中F:\libs\chai3d-3.2.0为chai3d库所在的目录; 配置C/C++预处理器,x64平台下添加WIN64,32位平台下添加WIN32;这里我们使用的是Qt msvc2017_64版本,所以在预处理器中添加WIN64定义。

    下一步就是添加CHAI3D所需要的库,选择属性->链接器->附加库目录,添加chai3d.lib文件所在的目录; 添加附加依赖项,在链接器->输入中添加opengl32.lib;glu32.lib;chai3d.lib;

    Demo简介

    说明:使用Qt+CHAI3D渲染一个小球

    新建Qt Class,继承QOpenGLWidget类和QOpenGLFunctions_3_3_Core类

    注意:chai3d头文件必须放在最前面,不然会报gl.h included before glew.h 错误

    头文件

    #include <chai3d.h> //必须放在前面 #include <QOpenGLWidget> #include <QOpenGLExtraFunctions> #include <QOpenGLFunctions_3_3_Core>

    重写方法 initializeGL() //初始化OpenGL resizeGL(int w, int h) //处理OpenGL窗口大小改变事件 paintGL()//处理OpenGL的渲染工作,在这里添加CHAI3D渲染代码

    protected: virtual void initializeGL() override;//初始化OpenGL virtual void resizeGL(int w, int h) override;//处理OpenGL窗口大小改变事件 virtual void paintGL() override;//处理OpenGL的渲染工作,在这里添加CHAI3D渲染代码

    完整Demo源码:

    main.cpp

    #include <QApplication> #include "openglwidget.h" int main(int argc, char* argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }

    openglwidget.h

    #pragma once #include <chai3d.h> #include <QOpenGLWidget> #include <QOpenGLExtraFunctions> #include <QOpenGLFunctions_3_3_Core> using namespace chai3d; class Widget : public QOpenGLWidget,private QOpenGLFunctions_3_3_Core { Q_OBJECT public: Widget(QWidget *parent=nullptr); ~Widget(); protected: virtual void initializeGL() override;//初始化OpenGL virtual void resizeGL(int w, int h) override;//处理OpenGL窗口大小改变事件 virtual void paintGL() override;//处理OpenGL的渲染工作,在这里添加CHAI3D渲染代码 private: cWorld* world = nullptr; cCamera* camera = nullptr; cDirectionalLight* light = nullptr; cShapeSphere* sphere = nullptr; int w = 0;//窗口宽 int h = 0;//窗口高 };

    openglwidget.cpp

    #include "openglwidget.h" Widget::Widget(QWidget *parent) : QOpenGLWidget(parent) { QSurfaceFormat surfaceFormat;//抗锯齿 surfaceFormat.setSamples(4); setFormat(surfaceFormat); world = new cWorld(); world->m_backgroundColor.setBlack(); camera = new cCamera(world); camera->set(cVector3d(-5.0, 0, 0), cVector3d(0, 0, 0), cVector3d(0.0, 0.0, 1.0)); camera->setClippingPlanes(0.1, 10); world->addChild(camera); light = new cDirectionalLight(world); light->setLocalPos(-5.0, 0, -5.0); light->setDir(1, 0, -1); light->setEnabled(true); world->addChild(light); sphere = new cShapeSphere(1.0); sphere->m_material->setColorf(0.8,0.2,0.6); world->addChild(sphere); } Widget::~Widget() { } void Widget::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_MULTISAMPLE); } void Widget::resizeGL(int w, int h) { glViewport(0, 0, w, h); this->w = w; this->h = h; } void Widget::paintGL() { camera->renderView(w, h);//CHAI3D渲染 }

    运行结果

    大功告成了~

    Processed: 0.052, SQL: 8