Cocos2d-x 3.x 图形学渲染系列十
来源:互联网 发布:如何忘记前任知乎 编辑:程序博客网 时间:2024/05/01 15:05
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
每个3D引擎都有对外提供的接口类,这个类主要是用于创建挂接场景中的所有物体,形成场景的树状结构。在Cocos2D-x引擎中,2d使用的是Sprite类,在3D模块中为了区分2D的Sprite类,新增加了Sprite3D类。该类是用于挂接场景中的3D物体,3D游戏场景中物体组织是树状结构,在逻辑编写中使用的非常多。首先开发者要用Sprite3D类对象创建场景中的物体,3D场景中的物体都是Sprite3D精灵,引擎要做的第一件事情是创建精灵,实现的函数内容如下所示:
Sprite3D* Sprite3D::create(const std::string& modelPath){CCASSERT(modelPath.length() >= 4, "invalid filename for Sprite3D");auto sprite = new (std::nothrow) Sprite3D();if (sprite && sprite->initWithFile(modelPath)) { sprite->_contentSize = sprite->getBoundingBox().size; sprite->autorelease();return sprite; }CC_SAFE_DELETE(sprite);return nullptr;}Sprite3D* Sprite3D::create(const std::string& modelPath, const std::string& texturePath){auto sprite = create(modelPath);if (sprite) { sprite->setTexture(texturePath); }return sprite;}
create函数在创建模型时经常用到,创建出可显示的模型,第一个函数的参数是模型的加载路径,第二个函数是模型的加载路径和纹理贴图名字,可更换模型贴图材质。后面会用案例给读者介绍,在上面的函数中提供了初始化模型文件信息函数initWithFile如下所示:
bool Sprite3D::initWithFile(const std::string& path){_aabbDirty = true;_meshes.clear();_meshVertexDatas.clear();CC_SAFE_RELEASE_NULL(_skeleton);removeAllAttachNode();if (loadFromCache(path))return true;MeshDatas* meshdatas = new (std::nothrow) MeshDatas();MaterialDatas* materialdatas = new (std::nothrow) MaterialDatas();NodeDatas* nodeDatas = new (std::nothrow) NodeDatas();if (loadFromFile(path, nodeDatas, meshdatas, materialdatas)){if (initFrom(*nodeDatas, *meshdatas, *materialdatas)) {//加到缓存auto data = new (std::nothrow) Sprite3DCache::Sprite3DData(); data->materialdatas = materialdatas; data->nodedatas = nodeDatas; data->meshVertexDatas = _meshVertexDatas;for (const auto mesh :_meshes) { data->glProgramStates.pushBack(mesh->getGLProgramState()); }Sprite3DCache::getInstance()->addSprite3DData(path, data);CC_SAFE_DELETE(meshdatas);_contentSize = getBoundingBox().size;return true; } }CC_SAFE_DELETE(meshdatas);CC_SAFE_DELETE(materialdatas);CC_SAFE_DELETE(nodeDatas);return false;}
initWithFile函数是引擎提供的加载模型对外接口,函数功能是实现了加载模型信息比如:材质信息,模型数据信息等。在加载模型之前需要先申请存放模型顶点数据信息,材质信息,模型的结点信息,这些信息具体实现是在loadFromFile函数中实现的,函数如下所示:
bool Sprite3D::loadFromFile(const std::string& path, NodeDatas* nodedatas, MeshDatas* meshdatas, MaterialDatas* materialdatas){std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path);std::string ext = FileUtils::getInstance()->getFileExtension(path);if (ext == ".obj") {return Bundle3D::loadObj(*meshdatas, *materialdatas, *nodedatas, fullPath); }else if (ext == ".c3b" || ext == ".c3t") {//加载模型文件 .c3b 或者 .c3tauto bundle = Bundle3D::createBundle();if(!bundle->load(fullPath)) {Bundle3D::destroyBundle(bundle);return false; }auto ret = bundle->loadMeshDatas(*meshdatas)&& bundle->loadMaterials(*materialdatas) &&bundle->loadNodes(*nodedatas);Bundle3D::destroyBundle(bundle);return ret; }return false;}
loadFromFile函数提供了加载Cocos2d-x引擎支持的三类模型:obj模型,c3t模型,c3b模型,以c3b或者c3t为例,模型文件是二进制和json文件,数据的加载是在Bundle3D类实现的,调用的接口是load函数,函数接口实现如下:
bool Bundle3D::load(const std::string& path){if (path.empty())return false;if (_path == path)return true;getModelRelativePath(path);bool ret = false;std::string ext = FileUtils::getInstance()->getFileExtension(path);if (ext == ".c3t") {_isBinary = false; ret = loadJson(path); }else if (ext == ".c3b") {_isBinary = true; ret = loadBinary(path); }else {CCLOG("warning: %s is invalid file formate", path.c_str()); } ret?(_path = path):(_path = "");return ret;}
load函数实现的是利用Bundle3D类提供的加载函数读取模型文件内容,这样利用Sprite3D类提供的接口就可以把模型加载显示出来。
以上展示的函数,开发者在编写逻辑时经常调用到,当然Sprite3D类不仅只是提供这几个函数接口。在后面的章节中会详细给读者讲解。下面通过案例给读者展示如何使用Sprite3D类的接口加载模型的代码片段:
Sprite3DForceDepthTest::Sprite3DForceDepthTest(){auto orc = cocos2d::Sprite3D::create("Sprite3DTest/orc.c3b"); orc->setScale(5); orc->setNormalizedPosition(Vec2(.5f,.3f)); orc->setPositionZ(40); orc->setRotation3D(Vec3(0,180,0)); orc->setGlobalZOrder(-1);addChild(orc);auto ship = Sprite3D::create("Sprite3DTest/boss1.obj"); ship->setScale(5); ship->setTexture("Sprite3DTest/boss.png"); ship->setNormalizedPosition(Vec2(.5,.5)); ship->setRotation3D(Vec3(90,0,0)); ship->setForceDepthWrite(true);addChild(ship);}
在Sprite3DForceDepthTest函数中首先调用Sprite3D类的接口create函数创建出模型,创建出的模型在场景中是无法显示出来的,接下来设置它的大小、位置、旋转角度以及设置它的Z深度值,目的是设置场景中的模型层次关系或者说是遮挡关系,这样多个模型显示时才有会有前后关系。这些参数设置好了后,最后的工作是将模型在场景中显示出来,显示模型需要将模型挂接到场景中作为场景的孩子结点,换句话说就是将模型结点加入到场景树中,调用函数addchild既可实现。在场景中实现的效果如下图:
在Cocos2D-x引擎中凡是涉及到创建模型对象都会与Sprite3D精灵有关系。
- Cocos2d-x 3.x 图形学渲染系列十
- Cocos2d-x 3.x 图形学渲染系列二十
- Cocos2d-x 3.x 图形学渲染系列一
- Cocos2d-x 3.x 图形学渲染系列二
- Cocos2d-x 3.x 图形学渲染系列三
- Cocos2d-x 3.x 图形学渲染系列四
- Cocos2d-x 3.x 图形学渲染系列五
- cocos2d-x 3.x 图形学渲染系列六
- Cocos2d-x 3.x 图形学渲染系列七
- Cocos2d-x 3.x 图形学渲染系列八
- Cocos2d-x 3.x 图形学渲染系列九
- Cocos2d-x 3.x 图形学渲染系列十一
- Cocos2d-x 3.x 图形学渲染系列十二
- Cocos2d-x 3.x 图形学渲染系列十三
- Cocos2d-x 3.x 图形学渲染系列十四
- Cocos2d-x 3.x 图形学渲染系列十五
- Cocos2d-x 3.x 图形学渲染系列十六
- Cocos2d-x 3.x 图形学渲染系列十七
- Linux系统中‘dmesg’命令处理故障和收集系统信息的7种用法
- 【B2B】【Hotel】Hotel TV应用框架分析和评价
- RecyclerView下拉刷新、上拉加载框架<一>
- 截取车辆正样本
- Objective-c - 当属性的类型是oc对象的时候,setter方法的写法
- Cocos2d-x 3.x 图形学渲染系列十
- Windows 配置PHP7开发环境
- RecyclerView布局的点击(并非item的点击)
- unity 2D游戏开发 制作帧动画的两种方法
- Android studio中git使用及git配置路径
- 4个垃圾收集算法
- Android RRO机制的运用-----google开机向导客制化
- 查询SQL相关信息
- Navicat Premium相关注册码