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来跨平台的。

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

  1. 局域网网络性能測试方法HDtune 64K有缓存測速法,让你得知你的网络性能

    该方法能够有效測试出您的网络传输性能究竟有多高,该方法通用于有盘,无盘(系统虚拟盘) ,游戏虚拟盘,以及其它带有缓存功能的虚拟盘软件,可是由于每款软件的工作方式和原理都不仅同样,所以每款软件的測试结果 ...

  2. OpenGL学习脚印:深度測试(depth testing)

    写在前面 上一节我们使用AssImp载入了3d模型,效果已经令人激动了.可是绘制效率和场景真实感还存在不足,接下来我们还是要保持耐心,继续学习一些高级主题,等学完后面的高级主题,我们再次来改进我们载入 ...

  3. Mali GPU OpenGL ES 应用性能优化--測试+定位+优化流程

    1. 使用DS-5 Streamline定位瓶颈 DS-5 Streamline要求GPU驱动启用性能測试,在Mali GPU驱动中激活性能測试对性能影响微不足道. 1.1 DS-5 Streamli ...

  4. Android +NDK+eclipse+opengl ES2.0 开启深度測试

    參考:https://www.opengl.org/discussion_boards/showthread.php/172736-OpenGL-ES-Depth-Buffer-Problem 环境: ...

  5. 浏览器上的Qt Quick

    你想不想在浏览器上运行你的Qt Quick程序呢?在Qt 5.12之前,唯一的方法是使用Qt WebGL Streaming技术把界面镜像到浏览器上.但该方法有不少缺陷,下文会说.前不久随着Qt 5. ...

  6. 从头学Qt Quick(1) --体验快速构建动态效果界面

    自2005年Qt4发布以来,Qt已经为成千上万的应用程序提供了框架服务,现在Qt已经基本上支持所有的开发平台了,这里面既包含了桌面.嵌入式领域,也包括了Android.IOS.WP等移动操作平台,甚至 ...

  7. Qt Quick实现的涂鸦程序

    之前一直以为 Qt Quick 里 Canvas 才干够自绘.后来发觉不是,原来还有好几种方式都能够画图! 能够使用原始的 OpenGL(Qt Quick 使用 OpenGL 渲染).能够构造QSGN ...

  8. Qt Quick 与 QML语言(初学笔记1)

    Qt Quick Qt Quick是一些新的UI技术的集合,用来帮助开发者创建一种现在越来越多用于手机.多媒体播放器.机顶盒以及其他便携式设备上的直观的.现代的.流畅的用户界面.简单来说,Qt Qui ...

  9. Qt Quick 布局演示

    于 Qt Widgets 于,我们经常使用许多布局管理器来管理界面 widgets . 于 Qt Quick 实际上,有两个相关的管理和布局库,所谓集 Item Positioner ,所谓集 Ite ...

随机推荐

  1. Jmeter-Maven-Plugin高级应用:Configuring the jvm that the jmeter process runs in

    Configuring the jvm that the jmeter process runs in The JMeter Maven plugin will run the JMeter proc ...

  2. JSP基本的语法、3个编译指令、7个动作指令、9个内置对象

    一.jsp概述 JSP是java server page的缩写,其本质是一个简化的servlet,是一种动态网页技术标准.jsp页面是在HTML页面中嵌入java程序段.使用jsp开发的应用程序能够跨 ...

  3. ArcGIS放射状流向地图

    今年百度推出了一个百度迁徙,在其他人看是好像是还挺专业的,其实不复杂.下面是百度的迁徙图示例:从图中可以看出从一个城市到另一个城市迁徙的直线路径,多个路径可以反映城市是否为热点城市,即人口流动比较大. ...

  4. Android 之数据传递小结

    Android开发中,在不同模块(如Activity)间经常会有各种各样的数据需要相互传递,常用的的有五种传递方式.它们各有利弊,有各自的应用场景.下面分别介绍一下: 1. Intent对象传递简单数 ...

  5. remote: ERROR: missing Change-Id in commit message footer

    remote: ERROR: missing Change-Id in commit message footer [摘要:git 提交到近程版本库失足:remote: ERROR: missing ...

  6. HTML5 坦克大战

    代码 点击打开链接

  7. 与AQS有关的并发类

    ReetrantLock与Condition: 參考 在java.util.concurrent包中.有两个非常特殊的工具类.Condition和ReentrantLock,使用过的人都知道,Reen ...

  8. maven 配置 Java Servlet API

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency> ...

  9. 安装ubuntu后不能从ubuntu引导修复方法

    sudo fdisk -l sudo -i mkdir /media/tempdir mount /dev/sda7 /media/tempdir grub-install --root-direct ...

  10. MySQL-关于并发下的mysql_insert_id()

    我们在写数据库程序的时候, 经常会需要获取某个表中的最大序号数, 或者刚插入的数据的ID值, 一般情况下获取刚插入的数据的id, 使用select max(id) from table 是可以的, 但 ...