Qt Quick + OpenGL + Bullet初次測试

Qt Quick + OpenGL + Bullet初次測试

眼下Qt的Quick模块已经表现得很出色,并且可以预留接口来渲染OpenGL场景。一般来说,已经可以满足大部分编程须要了。这次呢。尝试使用结合一些技术,来做一些有趣儿的事情——将Bullet整合进来,并且进行測试。

蒋彩阳原创文章。首发地址:http://blog.csdn.net/gamesdev/article/details/44284317。欢迎同行前来探讨。

有关Bullet的选择,事实上也是有一番讲究的。眼下Bullet的2.82版本号,临时没有更新了,而Bullet 3.x。则是还少有应用。假设我们去看Bullet的新的代码库——github。就会发现,在“Requirementsfor Bullet 2”,作者表示差点儿不论什么编译器都可以编译它的代码,而在“Requirements
for Bullet 3”的介绍中,仅仅是说能在高端的显卡中执行,低端显卡或者是移动设备可能和Bullet 3无缘了。

所以在这样的情况下,我就选择Bullet 2.82来制作这个样例。

为了完毕这个样例,我參考了前辈们的一些样例,比方说Qt在诺基亚时期,就写了一个非常棒的Bullet + Qt的样例。叫做BulletDice。

它的github地址在这里。这边儿比較简单,easy上手。再加上Bullet有一份Manual,两者结合起来看。方便了很多。

花了一周的时间。最终模仿而且制作出来了这种效果:

一開始立方体在平面的上面位置,随后依据重力,呈自由落体速度,慢慢地往下落。

终于落在了地面上。下图表示落下来时候的样子:

怎么样?非常easy吧。

这里也是我对Bullet的初步认识。在编写这个样例的过程中,遇到了非常多困难,也有非常多地方值得推敲。

所以我在这里先作一个笔记。给以后作參考。

首先为了验证物理引擎可用,我在类中写了一个函数叫debugShow()。每次仿真採样的时候。输出立方体的位置。在验证这样是没有问题的基础上。開始研究如何让数据与渲染相结合。以下的代码片描写叙述了与Bullet相关的一些知识:

void DynamicsWorldPrivate::initializePhysics( void )
{
    // 初始化物理引擎
    m_broadPhase = new btDbvtBroadphase;
    m_conf = new btDefaultCollisionConfiguration;
    m_dispatcher = new btCollisionDispatcher( m_conf );
    m_solver = new btSequentialImpulseConstraintSolver;

    // 应用重力
    m_world = new btDiscreteDynamicsWorld( m_dispatcher,
                                           m_broadPhase,
                                           m_solver,
                                           m_conf );
    m_world->setGravity( btVector3( 0, -9.81, 0 ) );

    // 创建一个平面刚体
    createPlane( );

    // 创建一个立方体刚体
    createCube( );
}

void DynamicsWorldPrivate::releasePhysics( void )
{
    delete m_world; m_world = Q_NULLPTR;
    delete m_solver; m_solver = Q_NULLPTR;
    delete m_conf; m_conf = Q_NULLPTR;
    delete m_dispatcher; m_dispatcher = Q_NULLPTR;
    delete m_broadPhase; m_broadPhase = Q_NULLPTR;

    qDeleteAll( m_shapes );
    qDeleteAll( m_bodies );
    m_shapes.clear( );
    m_bodies.clear( );
}

void DynamicsWorldPrivate::createPlane( void )
{
    btStaticPlaneShape* planeShape = new btStaticPlaneShape(
                btVector3( 0, 1, 0 ),       // 平面法线
                0.0 );                      // 平面的相对原点的距离

    btTransform originTransform;
    originTransform.setFromOpenGLMatrix( m_planeModelMatrix->data( ) );
    btDefaultMotionState* motionState = new btDefaultMotionState(
                originTransform,                // 開始的变换
                btTransform::getIdentity( ) );  // 中心平移量

    btRigidBody::btRigidBodyConstructionInfo planeInfo(
                0,                          // 质量
                motionState,                // 运动状态
                planeShape,                 // 碰撞的形状
                btVector3( 0, 0, 0 ) );     // 本地的惯性
    m_planeBody = new btRigidBody( planeInfo );
    m_world->addRigidBody( m_planeBody );
    m_shapes.append( planeShape );
    m_bodies.append( m_planeBody );
}

void DynamicsWorldPrivate::createCube( void )
{
    qreal semi = m_cubeLength / 2.0;
    btBoxShape* cubeShape = new btBoxShape(
                btVector3( semi, semi, semi ) );// 半个立方体的大小

    btTransform originTransform;
    originTransform.setFromOpenGLMatrix( m_cubeModelMatrix->data( ) );

    btDefaultMotionState* motionState = new btDefaultMotionState(
                originTransform,                // 開始的变换
                btTransform::getIdentity( ) );  // 中心平移量

    btRigidBody::btRigidBodyConstructionInfo cubeInfo(
                0.8f,                       // 质量
                motionState,                // 运动状态
                cubeShape,                  // 碰撞的形状
                btVector3( 0, 0, 0 ) );     // 本地的惯性
    cubeInfo.m_friction = 0.3;              // 摩擦力
    cubeInfo.m_restitution = 0.1;           // 反弹力(恢复力)

    m_cubeBody = new btRigidBody( cubeInfo );
    m_world->addRigidBody( m_cubeBody );
    m_shapes.append( cubeShape );
    m_bodies.append( m_cubeBody );
}

void DynamicsWorldPrivate::simulate( void )
{
    QTime curTime = QTime::currentTime( );
    int stepTime = m_lastTime.msecsTo( curTime );
    m_lastTime = curTime;

    m_world->stepSimulation( btScalar( stepTime ) * 0.001 );
}

void DynamicsWorldPrivate::debugShow( void )
{
    btTransform worldTransform;
    m_cubeBody->getMotionState( )->getWorldTransform( worldTransform );
    btVector3 position = worldTransform * btVector3( 0, 0, 0 );
    qDebug( "position is: ( %.2f, %.2f, %.2f )",
            position.x( ), position.y( ), position.z( ) );
}

随后,可能要考虑,在这个模型中,仅仅有一个施力物体。也就是“地球”,它对立方体施以重力。让立方体做自由落体运动,运动过程中採样的轨迹通过body中motionState中的worldTransform来表述。假设和渲染引擎相结合的话,我这边的做法是物理引擎终于仅仅改动物体的modelMatrix,模型自己的形态则控制着本原位置,摄像机的參数控制着viewMatrix和projectionMatrix。

仅仅有这样。一切看起来概念才清晰。

这里可能有一个比較棘手的问题,有时候,须要对modelMatrix进行手动控制,来改变模型的变换信息。可是呢。modelMatrix又是受物理引擎控制的。所以对于modelMatrix受手动控制和物理引擎控制的切换,是比較难以处理的,下次我再看看随着学习的深入,能不能厘清他们之前的关系。

最后。我也在我的Android平板电脑上測试成功。

说明Bullet是全然能够做到结合Qt来跨平台的。

时间: 2024-10-12 19:21:35

Qt Quick + OpenGL + Bullet初次測试的相关文章

Qt Quick + OpenGL + Bullet初次测试

Qt Quick + OpenGL + Bullet初次测试 目前Qt的Quick模块已经表现得非常出色,而且可以预留接口来渲染OpenGL场景.一般来说,已经能够满足大部分编程需要了.这次呢,尝试使用结合一些技术,来做一些有趣儿的事情--将Bullet整合进来,并且进行测试. 蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/44284317.欢迎同行前来探讨. 有关Bullet的选择,其实也是有一番讲究的.目前Bullet的

Qt Quick应用开发介绍 1-5

Qt Quick应用开发介绍 Introduction to Application Development with Qt Quick Release 1.0 Chapter1 Introduction 介绍 1.1 谁应该阅读这份教程 本教程解释了Qt Quick应用开发的基础以及使用示例代码帮助全面了解; 教程包含标准Qt Quick文档和基础概念, API以及详细的源码信息; 本教程是为了新接触Qt Quick的你准备的, 虽然从基础开始, 但你还是要熟悉编程的概念, 有JavaScri

测试Qt Quick在各个平台上的3D渲染性能

测试Qt Quick在各个平台上的3D渲染性能 Qt是一个跨平台的GUI框架,它的QtQuick更是支持结合OpenGL原生的代码进行渲染.我想将我以前写的程序整合到QtQuick上来,看看渲染效果是否满意,于是写了一个小小的程序,来做一下渲染基准测试.运行结果出来,不容乐观呐. 蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/43842131.欢迎同行前来探讨. 首先为了描述最基本的情况,我制作了一个带有纹理的立方体.它使用

铁科院医保项目第一版測试

短短的一个多月的时间已经做出来一个简单版本号.能够完毕基本的医保流程.当中加上十月一以及周六日放假等,实际上做项目的时间也就是一个月的时间.这个系统是一个大的综合系统.我们做的仅仅是里面的一个小的子系统,到眼下为止这个系统能够执行了,里面一些关于统计分析.数据图等补充的内容没有加入外已经都昨晚.可能还会再第二版中把这些功能做上. 系统尽管已经提交測试.能够执行可是在做项目的还是有非常多感悟的,这个项目是从前期数据库设计到代码实现都參与了进来.考虑着哪里easy出问题怎么设计等等.有些问题非常ea

Qt Quick实现的涂鸦程序

之前一直以为 Qt Quick 里 Canvas 才可以自绘,后来发觉不是,原来还有好几种方式都可以绘图!可以使用原始的 OpenGL(Qt Quick 使用 OpenGL 渲染),可以构造QSGNode 来绘图,还可以使用 QPainter !哇, QPainter 我很熟悉啊.于是,我用 QPainter 结合 QML 实现了一个简单的涂鸦程序: PaintedItem .它有下列功能: 设置线条宽度 设置线条颜色 设置背景颜色 清除涂鸦 无限级undo 程序很简陋,效果如下: 图1 Pai

Qt Quick

Qt是一个跨平台的图形用户界面的框架. Qt quick是Qt提供的一种高级用户界面工具包. 在Android等移动设备上,Qt quick应用默认使用OpenGL ES,渲染效率很高. Qt Creator是针对Qt的集成开发环境. qmlscene是用来测试QML应用的,不要用于生产环境.qmlscene yourapp.qml QML是一种标记语言,实现并扩展了ECMAScript. 在centos7下编译时,说cannot find -lGL,解决办法:yum install libGL

ios測试框架的理解

关于ios的測试 Cedar .Specta .Kiwi  .  XCTest Specta和Kiwi的差别就是Kiwi包括了Specta和OCmock以及Expeata全部的功能 測试框架的作用: 因为行业中的干进度,所以我们一般都是不用TDD来測试,而是用BDD来測试. BDD是用来測试的"数据存取"的重要环节. "术语" 理解: BDD(Behavior Driven Development),也就是行为驱动开发.它旨在解决详细问题,帮助开发者确定应该測试些什

Qt Quick里的AnimatedSprite的用法

之前用 AnimatedImage 时一直对 AnimatedSprite 很奇怪,想试一下怎么用,一下子没试出来,放下了,后来一直没时间. OK ,今天想起来,又搞了一下. AnimatedSprite 说明 AnimatedSprite 元素用来播放精灵动画. 一些常见的属性解释: source 属性是 url 类型的,接受一个包含多帧的图片. frameWidth 和 frameHeight 指定帧大小. frameX 和 frameY 指定第一帧的左上角. frameCount 指定这个

《Qt Quick核心编程》上市了

我的第二本书<Qt Quick 核心编程>上市了,各个网站的预售链接已经上线: 淘宝惊喜价 china-pub 京东 亚马逊 我不是王婆,可有时也卖瓜:这是国内第一本专门讲述 Qt Quick 的书,系统.全面.实例丰富,值得拥有. 下面是图书封面,与<Qt on Android核心编程>同款式. 封底: 试读样章很快放出,敬请期待. 您也可点击我的Qt Quick专栏,里面很多文章都在本书中出现了. 图书目录,还请点击文前链接哦.