Bullet(Cocos2dx)之优化PhysicsDraw3D

Bullet(Cocos2dx)之优化PhysicsDraw3D,第1张

概述Bullet(Cocos2dx)之优化PhysicsDraw3D 分类: cocos2d-x 物理引擎 2015-01-06 20:01 168人阅读 评论(0) 收藏 举报 cocos2dx bullet 物理引擎 为了测试bullet物体的大小,匆匆写完的PhysicsDraw3D的效率低的要命,这也是为什么cocos2dx弃用了DrawPrimitives,而去使用DrawNode Draw Bullet(Cocos2dx)之优化PhysicsDraw3D 分类: cocos2d-x 物理引擎 2015-01-06 20:01 168人阅读 评论(0) 收藏 举报 cocos2dx bullet 物理引擎

为了测试bullet物体的大小,匆匆写完的PhysicsDraw3D的效率低的要命,这也是为什么cocos2dx弃用了DrawPrimitives,而去使用DrawNode

DrawPrimitives每次绘制都去调用glDrawElements,假如每帧绘制10000条线段,那么就要调用10000次glDrawElements,可见效率之低。

而DrawNode采取的是批处理的方式,当drawline的时候不是立即绘制,而是将线段的信息添加到数组里,当draw时统一调用gl的绘制函数

10000/1可不是一个小数目啊。

下图使用DrawPrimitives方法


加入40Sphere帧率就掉到4070的帧率更是惨不忍睹


下图使用DrawNode方法


为了解决这个问题就要参照DrawNode实现一个简单的DrawNode3D

不管三七二十一,将DrawNode的头文件代码copy,删去一些不需要的,

1.修改V2F_C4B_T2FV3F_C4B_T2F

2.修改Vec2为Vec3,要绘制3D

3.保留drawPoint,drawPoints,drawline,其他的绘制函数不要

[cpp] view plain copy #ifndef__DRAW_NODE_3D_H__ #define__DRAW_NODE_3D_H__ #include"cocos2d.h" USING_NS_CC; classDrawNode3D:publicNode { public: staticDrawNode3D*create(); voIDdrawPoint(constVec3&point,constfloatpointSize,constcolor4F&color); voIDdrawPoints(constVec3*position,unsignedintnumberOfPoints,constcolor4F&color); voIDdrawline(constVec3&origin,constVec3&destination,constcolor4F&color); //OverrIDes virtualvoIDdraw(Renderer*renderer,constMat4&transform,uint32_tflags)overrIDe; voIDclear(); constBlendFunc&getBlendFunc()const; voIDsetBlendFunc(constBlendFunc&blendFunc); voIDonDraw(constMat4&transform,uint32_tflags); voIDonDrawGLline(constMat4&transform,uint32_tflags); voIDonDrawGLPoint(constMat4&transform,uint32_tflags); CC_CONSTRUCTOR_ACCESS: DrawNode3D(); virtual~DrawNode3D(); virtualboolinit(); protected: voIDensureCapacity(intcount); voIDensureCapacityGLPoint(intcount); voIDensureCapacityGLline(intcount); gluint_vao; gluint_vbo; gluint_vaoGLPoint; gluint_vboGLPoint; gluint_vaoGLline; gluint_vboGLline; int_bufferCapacity; GLsizei_bufferCount; V3F_C4B_T2F*_buffer; int_bufferCapacityGLPoint; GLsizei_bufferCountGLPoint; V3F_C4B_T2F*_bufferGLPoint; color4F_pointcolor; int_pointSize; int_bufferCapacityGLline; GLsizei_bufferCountGLline; V3F_C4B_T2F*_bufferGLline; BlendFunc_blendFunc; CustomCommand_customCommand; CustomCommand_customCommandGLPoint; CustomCommand_customCommandGLline; bool_dirty; bool_dirtyGLPoint; bool_dirtyGLline; private: CC_disALLOW_copY_AND_ASSIGN(DrawNode3D); }; #endif

对于DrawNode.cpp按照上面所说同样修改

要记住

[cpp] view plain copy glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_position,3,GL_float,GL_FALSE,sizeof(V3F_C4B_T2F),(GLvoID*)offsetof(V3F_C4B_T2F,vertices)); 要将GLProgram::VERTEX_ATTRIB_position,2改为GLProgram::VERTEX_ATTRIB_position,3

因为顶点有三个元素,.cpp代码过多,请在文章最后下载源码,要注意的是绘制时开启深度测试

修改PhysicsDraw3D

删除成员变量,添加DrawNode3D*_drawNode,由于DrawNode3D继承自Node所以创建时要将其添加到父节点上,

修改create,init为如下

staticPhysicsDraw3D*createWithLayer(Node*layer);

boolinitWithLayer(Node*layer);

同时添加

voIDclearDraw();

我们知道DrawNode如果不执行clear,那么就不会清空上一帧的绘制数据

具体修改如下:

[cpp] view plain copy PhysicsDraw3D*PhysicsDraw3D::createWithLayer(Node*layer) { autodraw=newPhysicsDraw3D; if(draw&&draw->initWithLayer(layer)) { returndraw; } returnnullptr; } boolPhysicsDraw3D::initWithLayer(Node*layer) { _drawNode=DrawNode3D::create(); layer->addChild(_drawNode); _deBUGDrawMode=btIDeBUGDraw::DBG_MAX_DEBUG_DRAW_MODE; returntrue; } voIDPhysicsDraw3D::clearDraw() { _drawNode->clear(); }

销毁时也要将_drawNode从Parent中移除

[cpp] view plain copy voIDPhysicsDraw3D::destroy() { _drawNode->removeFromParent(); deletethis; } drawline也就简化了 voIDPhysicsDraw3D::drawline(constbtVector3&from,constbtVector3&to,constbtVector3&color) { Vec3vertices[2]={ Vec3(from.x(),from.y(),from.z()), Vec3(to.x(),to.y(),to.z()) }; _color.r=color.x(); _color.g=color.y(); _color.b=color.z(); _color.a=1.f; _drawNode->drawline(vertices[0],vertices[1],_color); }

PhysicsWorld3D创建的静态函数添加

[cpp] view plain copy staticPhysicsWorld3D*createWithDeBUG(Node*layer,constbtVector3&gravity=btVector3(0,-10,0));

为的就是创建调试绘制

[cpp] view plain copy boolPhysicsWorld3D::initWorlDWithDeBUG(Node*layer,constbtVector3&gravity) { if(!this->initWorld(gravity)) { returnfalse; } _deBUGDraw=PhysicsDraw3D::createWithLayer(layer); _world->setDeBUGDrawer(_deBUGDraw); returntrue; }

同时删除initWorld对_deBUGDraw的创建,每次绘制时需要判断是否为deBUG

[cpp] view plain copy voIDPhysicsWorld3D::deBUGDraw() { if(_deBUGDraw) { _deBUGDraw->clearDraw(); _world->deBUGDrawWorld(); } }

完整源码

csdn

github

总结

以上是内存溢出为你收集整理的Bullet(Cocos2dx)之优化PhysicsDraw3D全部内容,希望文章能够帮你解决Bullet(Cocos2dx)之优化PhysicsDraw3D所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1033691.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存