diff --git a/cocos/3d/CCBundle3DData.h b/cocos/3d/CCBundle3DData.h index f5cc5d3d1c..63c5916c89 100644 --- a/cocos/3d/CCBundle3DData.h +++ b/cocos/3d/CCBundle3DData.h @@ -127,6 +127,15 @@ struct MeshData int attribCount; public: + int getPerVertexSize() const + { + int vertexsize = 0; + for(const auto& attrib : attribs) + { + vertexsize += attrib.attribSizeBytes; + } + return vertexsize; + } void resetData() { vertex.clear(); diff --git a/cocos/3d/CCMesh.cpp b/cocos/3d/CCMesh.cpp index 364f92aca9..165a26fab6 100644 --- a/cocos/3d/CCMesh.cpp +++ b/cocos/3d/CCMesh.cpp @@ -47,356 +47,356 @@ using namespace std; NS_CC_BEGIN -bool RenderMeshData::hasVertexAttrib(int attrib) -{ - for (auto itr = _vertexAttribs.begin(); itr != _vertexAttribs.end(); itr++) - { - if ((*itr).vertexAttrib == attrib) - return true; //already has - } - return false; -} - -bool RenderMeshData::init(const std::vector& positions, - const std::vector& normals, - const std::vector& texs, - const std::vector& indices) -{ - CC_ASSERT(positions.size()<65536 * 3 && "index may out of bound"); - - _vertexAttribs.clear(); - - _vertexNum = positions.size() / 3; //number of vertex - if (_vertexNum == 0) - return false; - - if ((normals.size() != 0 && _vertexNum * 3 != normals.size()) || (texs.size() != 0 && _vertexNum * 2 != texs.size())) - return false; - - MeshVertexAttrib meshvertexattrib; - meshvertexattrib.size = 3; - meshvertexattrib.type = GL_FLOAT; - meshvertexattrib.attribSizeBytes = meshvertexattrib.size * sizeof(float); - meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_POSITION; - _vertexAttribs.push_back(meshvertexattrib); - - //normal - if (normals.size()) - { - //add normal flag - meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_NORMAL; - _vertexAttribs.push_back(meshvertexattrib); - } - // - if (texs.size()) - { - meshvertexattrib.size = 2; - meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_TEX_COORD; - meshvertexattrib.attribSizeBytes = meshvertexattrib.size * sizeof(float); - _vertexAttribs.push_back(meshvertexattrib); - } - - _vertexs.clear(); - _vertexsizeBytes = calVertexSizeBytes(); - _vertexs.reserve(_vertexNum * _vertexsizeBytes / sizeof(float)); - - bool hasNormal = hasVertexAttrib(GLProgram::VERTEX_ATTRIB_NORMAL); - bool hasTexCoord = hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD); - //position, normal, texCoordinate into _vertexs - for(int i = 0; i < _vertexNum; i++) - { - _vertexs.push_back(positions[i * 3]); - _vertexs.push_back(positions[i * 3 + 1]); - _vertexs.push_back(positions[i * 3 + 2]); - - if (hasNormal) - { - _vertexs.push_back(normals[i * 3]); - _vertexs.push_back(normals[i * 3 + 1]); - _vertexs.push_back(normals[i * 3 + 2]); - } - - if (hasTexCoord) - { - _vertexs.push_back(texs[i * 2]); - _vertexs.push_back(texs[i * 2 + 1]); - } - } - _subMeshIndices = indices; - - return true; -} - -bool RenderMeshData::init(const std::vector& vertices, int vertexSizeInFloat, const std::vector& indices, const std::vector& attribs) -{ - _vertexs = vertices; - _subMeshIndices = indices; - _vertexAttribs = attribs; - - _vertexsizeBytes = calVertexSizeBytes(); - - return true; -} - -int RenderMeshData::calVertexSizeBytes() -{ - int sizeBytes = 0; - for (auto it = _vertexAttribs.begin(); it != _vertexAttribs.end(); it++) { - sizeBytes += (*it).size; - CCASSERT((*it).type == GL_FLOAT, "use float"); - } - sizeBytes *= sizeof(float); - - return sizeBytes; -} - -Mesh::Mesh() -:_vertexBuffer(0) -{ -} - -Mesh::~Mesh() -{ - _subMeshes.clear(); - cleanAndFreeBuffers(); -} - -Mesh* Mesh::create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const IndexArray& indices) -{ - std::vector submeshIndices; - submeshIndices.push_back(indices); - return create(positions, normals, texs, submeshIndices); -} - -Mesh* Mesh::create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& indices) -{ - auto mesh = new Mesh(); - if(mesh && mesh->init(positions, normals, texs, indices)) - { - mesh->autorelease(); - return mesh; - } - CC_SAFE_DELETE(mesh); - return nullptr; -} - -Mesh* Mesh::create(const std::vector& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector& attribs) -{ - std::vector submeshIndices; - submeshIndices.push_back(indices); - return create(vertices, vertexSizeInFloat, submeshIndices, attribs); -} - -Mesh* Mesh::create(const std::vector &vertices, int vertexSizeInFloat, const std::vector &indices, const std::vector &attribs) -{ - auto mesh = new Mesh(); - if (mesh && mesh->init(vertices, vertexSizeInFloat, indices, attribs)) - { - mesh->autorelease(); - return mesh; - } - CC_SAFE_DELETE(mesh); - return nullptr; -} - -Mesh* Mesh::create(const MeshData& meshdata) -{ - auto mesh = new Mesh(); - if (mesh && mesh->init(meshdata.vertex, meshdata.vertexSizeInFloat, meshdata.subMeshIndices, meshdata.attribs)) - { - for (int i = 0; i < (int)mesh->getSubMeshCount(); i++) { - auto submesh = mesh->getSubMesh(i); - if (meshdata.subMeshIds.size()) - submesh->_id = meshdata.subMeshIds[i]; - submesh->_mesh = mesh; - } - } - mesh->autorelease(); - return mesh; -} - -bool Mesh::init(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& indices) -{ - bool bRet = _renderdata.init(positions, normals, texs, indices); - if (!bRet) - return false; - - buildSubMeshes(); - - buildBuffer(); - - return true; -} - - -bool Mesh::init(const std::vector& vertices, int vertexSizeInFloat, const std::vector& indices, const std::vector& attribs) -{ - bool bRet = _renderdata.init(vertices, vertexSizeInFloat, indices, attribs); - if (!bRet) - return false; - - buildSubMeshes(); - - buildBuffer(); - - return true; -} - -void Mesh::buildSubMeshes() -{ - _subMeshes.clear(); - for (auto& it : _renderdata._subMeshIndices) { - auto subMesh = SubMesh::create(PrimitiveType::TRIANGLES, IndexFormat::INDEX16, it); - _subMeshes.pushBack(subMesh); - - //calculate aabb for sub mesh - AABB aabb; - int stride = _renderdata._vertexsizeBytes / sizeof(float); - for(const auto& index : it) - { - Vec3 point = Vec3(_renderdata._vertexs[index * stride ], _renderdata._vertexs[ index * stride + 1], _renderdata._vertexs[index * stride + 2 ]); - aabb.updateMinMax(&point, 1); - } - subMesh->_aabb = aabb; - } -} - -void Mesh::cleanAndFreeBuffers() -{ - if(glIsBuffer(_vertexBuffer)) - { - glDeleteBuffers(1, &_vertexBuffer); - _vertexBuffer = 0; - } - - for (auto& it : _subMeshes) { - (*it).cleanAndFreeBuffers(); - } -} - -void Mesh::buildBuffer() -{ - cleanAndFreeBuffers(); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - - glBufferData(GL_ARRAY_BUFFER, - _renderdata._vertexs.size() * sizeof(_renderdata._vertexs[0]), - &_renderdata._vertexs[0], - GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - for (size_t i = 0; i < _subMeshes.size(); i++) { - _subMeshes.at(i)->buildBuffer(_renderdata._subMeshIndices[i]); - } -} - -void Mesh::restore() -{ - _vertexBuffer = 0; - for (auto& it : _subMeshes) { - it->_indexBuffer = 0; - } - - buildBuffer(); -} - -SubMesh* Mesh::getSubMeshById(const std::string& subMeshId) const -{ - for (auto it : _subMeshes) { - if (it->getSubMeshId() == subMeshId) - return it; - } - return nullptr; -} - -/** - * MeshCache - */ -MeshCache* MeshCache::_cacheInstance = nullptr; - -MeshCache* MeshCache::getInstance() -{ - if (_cacheInstance == nullptr) - _cacheInstance = new MeshCache(); - - return _cacheInstance; -} -void MeshCache::destroyInstance() -{ - if (_cacheInstance) - CC_SAFE_DELETE(_cacheInstance); -} - -Mesh* MeshCache::getMesh(const std::string& key) const -{ - auto it = _meshes.find(key); - if (it != _meshes.end()) - return it->second; - - return nullptr; -} - -bool MeshCache::addMesh(const std::string& key, Mesh* mesh) -{ - auto it = _meshes.find(key); - if (it == _meshes.end()) - { - mesh->retain(); - _meshes[key] = mesh; - - return true; - } - return false; -} - -void MeshCache::removeAllMeshes() -{ - for (auto it : _meshes) { - CC_SAFE_RELEASE(it.second); - } - _meshes.clear(); -} - -void MeshCache::removeUnusedMesh() -{ - for( auto it=_meshes.cbegin(); it!=_meshes.cend(); /* nothing */) { - if(it->second->getReferenceCount() == 1) - { - it->second->release(); - _meshes.erase(it++); - } - else - ++it; - } -} - -MeshCache::MeshCache() -{ -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) - // listen the event that renderer was recreated on Android/WP8 - _rendererRecreatedListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, CC_CALLBACK_1(MeshCache::listenRendererRecreated, this)); - Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_rendererRecreatedListener, -1); -#endif -} -MeshCache::~MeshCache() -{ - removeAllMeshes(); -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) - Director::getInstance()->getEventDispatcher()->removeEventListener(_rendererRecreatedListener); -#endif -} - -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) -void MeshCache::listenRendererRecreated(EventCustom* event) -{ - for (auto iter = _meshes.begin(); iter != _meshes.end(); ++iter) - { - auto mesh = iter->second; - mesh->restore(); - } -} -#endif +//bool RenderMeshData::hasVertexAttrib(int attrib) +//{ +// for (auto itr = _vertexAttribs.begin(); itr != _vertexAttribs.end(); itr++) +// { +// if ((*itr).vertexAttrib == attrib) +// return true; //already has +// } +// return false; +//} +// +//bool RenderMeshData::init(const std::vector& positions, +// const std::vector& normals, +// const std::vector& texs, +// const std::vector& indices) +//{ +// CC_ASSERT(positions.size()<65536 * 3 && "index may out of bound"); +// +// _vertexAttribs.clear(); +// +// _vertexNum = positions.size() / 3; //number of vertex +// if (_vertexNum == 0) +// return false; +// +// if ((normals.size() != 0 && _vertexNum * 3 != normals.size()) || (texs.size() != 0 && _vertexNum * 2 != texs.size())) +// return false; +// +// MeshVertexAttrib meshvertexattrib; +// meshvertexattrib.size = 3; +// meshvertexattrib.type = GL_FLOAT; +// meshvertexattrib.attribSizeBytes = meshvertexattrib.size * sizeof(float); +// meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_POSITION; +// _vertexAttribs.push_back(meshvertexattrib); +// +// //normal +// if (normals.size()) +// { +// //add normal flag +// meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_NORMAL; +// _vertexAttribs.push_back(meshvertexattrib); +// } +// // +// if (texs.size()) +// { +// meshvertexattrib.size = 2; +// meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_TEX_COORD; +// meshvertexattrib.attribSizeBytes = meshvertexattrib.size * sizeof(float); +// _vertexAttribs.push_back(meshvertexattrib); +// } +// +// _vertexs.clear(); +// _vertexsizeBytes = calVertexSizeBytes(); +// _vertexs.reserve(_vertexNum * _vertexsizeBytes / sizeof(float)); +// +// bool hasNormal = hasVertexAttrib(GLProgram::VERTEX_ATTRIB_NORMAL); +// bool hasTexCoord = hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD); +// //position, normal, texCoordinate into _vertexs +// for(int i = 0; i < _vertexNum; i++) +// { +// _vertexs.push_back(positions[i * 3]); +// _vertexs.push_back(positions[i * 3 + 1]); +// _vertexs.push_back(positions[i * 3 + 2]); +// +// if (hasNormal) +// { +// _vertexs.push_back(normals[i * 3]); +// _vertexs.push_back(normals[i * 3 + 1]); +// _vertexs.push_back(normals[i * 3 + 2]); +// } +// +// if (hasTexCoord) +// { +// _vertexs.push_back(texs[i * 2]); +// _vertexs.push_back(texs[i * 2 + 1]); +// } +// } +// _subMeshIndices = indices; +// +// return true; +//} +// +//bool RenderMeshData::init(const std::vector& vertices, int vertexSizeInFloat, const std::vector& indices, const std::vector& attribs) +//{ +// _vertexs = vertices; +// _subMeshIndices = indices; +// _vertexAttribs = attribs; +// +// _vertexsizeBytes = calVertexSizeBytes(); +// +// return true; +//} +// +//int RenderMeshData::calVertexSizeBytes() +//{ +// int sizeBytes = 0; +// for (auto it = _vertexAttribs.begin(); it != _vertexAttribs.end(); it++) { +// sizeBytes += (*it).size; +// CCASSERT((*it).type == GL_FLOAT, "use float"); +// } +// sizeBytes *= sizeof(float); +// +// return sizeBytes; +//} +// +//Mesh::Mesh() +//:_vertexBuffer(0) +//{ +//} +// +//Mesh::~Mesh() +//{ +// _subMeshes.clear(); +// cleanAndFreeBuffers(); +//} +// +//Mesh* Mesh::create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const IndexArray& indices) +//{ +// std::vector submeshIndices; +// submeshIndices.push_back(indices); +// return create(positions, normals, texs, submeshIndices); +//} +// +//Mesh* Mesh::create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& indices) +//{ +// auto mesh = new Mesh(); +// if(mesh && mesh->init(positions, normals, texs, indices)) +// { +// mesh->autorelease(); +// return mesh; +// } +// CC_SAFE_DELETE(mesh); +// return nullptr; +//} +// +//Mesh* Mesh::create(const std::vector& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector& attribs) +//{ +// std::vector submeshIndices; +// submeshIndices.push_back(indices); +// return create(vertices, vertexSizeInFloat, submeshIndices, attribs); +//} +// +//Mesh* Mesh::create(const std::vector &vertices, int vertexSizeInFloat, const std::vector &indices, const std::vector &attribs) +//{ +// auto mesh = new Mesh(); +// if (mesh && mesh->init(vertices, vertexSizeInFloat, indices, attribs)) +// { +// mesh->autorelease(); +// return mesh; +// } +// CC_SAFE_DELETE(mesh); +// return nullptr; +//} +// +//Mesh* Mesh::create(const MeshData& meshdata) +//{ +// auto mesh = new Mesh(); +// if (mesh && mesh->init(meshdata.vertex, meshdata.vertexSizeInFloat, meshdata.subMeshIndices, meshdata.attribs)) +// { +// for (int i = 0; i < (int)mesh->getSubMeshCount(); i++) { +// auto submesh = mesh->getSubMesh(i); +// if (meshdata.subMeshIds.size()) +// submesh->_id = meshdata.subMeshIds[i]; +// submesh->_mesh = mesh; +// } +// } +// mesh->autorelease(); +// return mesh; +//} +// +//bool Mesh::init(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& indices) +//{ +// bool bRet = _renderdata.init(positions, normals, texs, indices); +// if (!bRet) +// return false; +// +// buildSubMeshes(); +// +// buildBuffer(); +// +// return true; +//} +// +// +//bool Mesh::init(const std::vector& vertices, int vertexSizeInFloat, const std::vector& indices, const std::vector& attribs) +//{ +// bool bRet = _renderdata.init(vertices, vertexSizeInFloat, indices, attribs); +// if (!bRet) +// return false; +// +// buildSubMeshes(); +// +// buildBuffer(); +// +// return true; +//} +// +//void Mesh::buildSubMeshes() +//{ +// _subMeshes.clear(); +// for (auto& it : _renderdata._subMeshIndices) { +// auto subMesh = SubMesh::create(PrimitiveType::TRIANGLES, IndexFormat::INDEX16, it); +// _subMeshes.pushBack(subMesh); +// +// //calculate aabb for sub mesh +// AABB aabb; +// int stride = _renderdata._vertexsizeBytes / sizeof(float); +// for(const auto& index : it) +// { +// Vec3 point = Vec3(_renderdata._vertexs[index * stride ], _renderdata._vertexs[ index * stride + 1], _renderdata._vertexs[index * stride + 2 ]); +// aabb.updateMinMax(&point, 1); +// } +// subMesh->_aabb = aabb; +// } +//} +// +//void Mesh::cleanAndFreeBuffers() +//{ +// if(glIsBuffer(_vertexBuffer)) +// { +// glDeleteBuffers(1, &_vertexBuffer); +// _vertexBuffer = 0; +// } +// +// for (auto& it : _subMeshes) { +// (*it).cleanAndFreeBuffers(); +// } +//} +// +//void Mesh::buildBuffer() +//{ +// cleanAndFreeBuffers(); +// +// glGenBuffers(1, &_vertexBuffer); +// glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); +// +// glBufferData(GL_ARRAY_BUFFER, +// _renderdata._vertexs.size() * sizeof(_renderdata._vertexs[0]), +// &_renderdata._vertexs[0], +// GL_STATIC_DRAW); +// glBindBuffer(GL_ARRAY_BUFFER, 0); +// +// for (size_t i = 0; i < _subMeshes.size(); i++) { +// _subMeshes.at(i)->buildBuffer(_renderdata._subMeshIndices[i]); +// } +//} +// +//void Mesh::restore() +//{ +// _vertexBuffer = 0; +// for (auto& it : _subMeshes) { +// it->_indexBuffer = 0; +// } +// +// buildBuffer(); +//} +// +//SubMesh* Mesh::getSubMeshById(const std::string& subMeshId) const +//{ +// for (auto it : _subMeshes) { +// if (it->getSubMeshId() == subMeshId) +// return it; +// } +// return nullptr; +//} +// +///** +// * MeshCache +// */ +//MeshCache* MeshCache::_cacheInstance = nullptr; +// +//MeshCache* MeshCache::getInstance() +//{ +// if (_cacheInstance == nullptr) +// _cacheInstance = new MeshCache(); +// +// return _cacheInstance; +//} +//void MeshCache::destroyInstance() +//{ +// if (_cacheInstance) +// CC_SAFE_DELETE(_cacheInstance); +//} +// +//Mesh* MeshCache::getMesh(const std::string& key) const +//{ +// auto it = _meshes.find(key); +// if (it != _meshes.end()) +// return it->second; +// +// return nullptr; +//} +// +//bool MeshCache::addMesh(const std::string& key, Mesh* mesh) +//{ +// auto it = _meshes.find(key); +// if (it == _meshes.end()) +// { +// mesh->retain(); +// _meshes[key] = mesh; +// +// return true; +// } +// return false; +//} +// +//void MeshCache::removeAllMeshes() +//{ +// for (auto it : _meshes) { +// CC_SAFE_RELEASE(it.second); +// } +// _meshes.clear(); +//} +// +//void MeshCache::removeUnusedMesh() +//{ +// for( auto it=_meshes.cbegin(); it!=_meshes.cend(); /* nothing */) { +// if(it->second->getReferenceCount() == 1) +// { +// it->second->release(); +// _meshes.erase(it++); +// } +// else +// ++it; +// } +//} +// +//MeshCache::MeshCache() +//{ +//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +// // listen the event that renderer was recreated on Android/WP8 +// _rendererRecreatedListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, CC_CALLBACK_1(MeshCache::listenRendererRecreated, this)); +// Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_rendererRecreatedListener, -1); +//#endif +//} +//MeshCache::~MeshCache() +//{ +// removeAllMeshes(); +//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +// Director::getInstance()->getEventDispatcher()->removeEventListener(_rendererRecreatedListener); +//#endif +//} +// +//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +//void MeshCache::listenRendererRecreated(EventCustom* event) +//{ +// for (auto iter = _meshes.begin(); iter != _meshes.end(); ++iter) +// { +// auto mesh = iter->second; +// mesh->restore(); +// } +//} +//#endif NS_CC_END diff --git a/cocos/3d/CCMesh.h b/cocos/3d/CCMesh.h index dafaceb54e..0a20a1a7be 100644 --- a/cocos/3d/CCMesh.h +++ b/cocos/3d/CCMesh.h @@ -46,165 +46,165 @@ NS_CC_BEGIN class EventListenerCustom; class EventCustom; -class CC_3D_DLL RenderMeshData -{ - typedef std::vector IndexArray; - friend class Mesh; -public: - RenderMeshData(): _vertexsizeBytes(0) - { - } - bool hasVertexAttrib(int attrib); - bool init(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& subMeshIndices); - bool init(const std::vector& vertices, int vertexSizeInFloat, const std::vector& subMeshIndices, const std::vector& attribs); - -protected: - - int calVertexSizeBytes(); - - int _vertexsizeBytes; - ssize_t _vertexNum; - std::vector _vertexs; - std::vector _subMeshIndices; - std::vector _vertexAttribs; -}; - -/** - * Mesh: Geometry with a collection of vertex. - * Supporting various vertex formats. - */ -class CC_3D_DLL Mesh : public Ref -{ - typedef std::vector IndexArray; -public: - /**create mesh from positions, normals, and so on, sigle SubMesh*/ - static Mesh* create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const IndexArray& indices); - - /**create mesh from positions, normals, and so on, multi-SubMesh*/ - static Mesh* create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& subMeshIndices); - - /**create mesh with vertex attributes*/ - CC_DEPRECATED_ATTRIBUTE static Mesh* create(const std::vector& vertices, int vertexSizeInFloat, const IndexArray& indices, int numIndex, const std::vector& attribs, int attribCount) { return create(vertices, vertexSizeInFloat, indices, attribs); } - - /** - * create Mesh - * @param vertices vertices buffer data - * @param vertexSizeInFloat size of each vertex - * @param indices index buffer data that denotes how to connect the vertex, sigle SubMesh - * @param attribs vertex attributes - */ - static Mesh* create(const std::vector& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector& attribs); - - /** - * create Mesh - * @param vertices vertices buffer data - * @param vertexSizeInFloat size of each vertex - * @param subMeshIndices index buffer data that denotes how to connect the vertex, multi-SubMesh - * @param attribs vertex attributes - */ - static Mesh* create(const std::vector& vertices, int vertexSizeInFloat, const std::vector& subMeshIndices, const std::vector& attribs); - - static Mesh* create(const MeshData& meshdata); - - /**get vertex buffer*/ - inline GLuint getVertexBuffer() const { return _vertexBuffer; } - - /**get mesh vertex attribute count*/ - ssize_t getMeshVertexAttribCount() const { return _renderdata._vertexAttribs.size(); } - /**get MeshVertexAttribute by index*/ - const MeshVertexAttrib& getMeshVertexAttribute(int idx) const { return _renderdata._vertexAttribs[idx]; } - /**has vertex attribute?*/ - bool hasVertexAttrib(int attrib) { return _renderdata.hasVertexAttrib(attrib); } - /**get per vertex size in bytes*/ - int getVertexSizeInBytes() const { return _renderdata._vertexsizeBytes; } - - /**get sub mesh count*/ - ssize_t getSubMeshCount() const { return _subMeshes.size(); } - - /**get sub mesh by index*/ - SubMesh* getSubMesh(int index) const { return _subMeshes.at(index); } - - /**build vertex buffer from renderdata*/ - void restore(); - - /** get submesh by id */ - SubMesh* getSubMeshById(const std::string& subMeshId) const; - - /**to be deprecated, those functions have been moved to SubMesh*/ - /** get primitive type*/ - CC_DEPRECATED_ATTRIBUTE PrimitiveType getPrimitiveType() const { return _subMeshes.at(0)->getPrimitiveType(); } - /**get index count*/ - CC_DEPRECATED_ATTRIBUTE ssize_t getIndexCount() const { return _subMeshes.at(0)->getIndexCount(); } - /**get index format*/ - CC_DEPRECATED_ATTRIBUTE IndexFormat getIndexFormat() const { return _subMeshes.at(0)->getIndexFormat(); } - /**get index buffer*/ - CC_DEPRECATED_ATTRIBUTE GLuint getIndexBuffer() const {return _subMeshes.at(0)->getIndexBuffer(); } - -CC_CONSTRUCTOR_ACCESS: - - Mesh(); - virtual ~Mesh(); - /**init mesh*/ - bool init(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& indices); - - /**init mesh*/ - bool init(const std::vector& vertices, int vertexSizeInFloat, const std::vector& indices, const std::vector& attribs); - - /**build sub meshes*/ - void buildSubMeshes(); - /**build buffer*/ - void buildBuffer(); - /**free buffer*/ - void cleanAndFreeBuffers(); - -protected: - GLuint _vertexBuffer; - Vector _subMeshes; - - RenderMeshData _renderdata; -}; - -/** - * Mesh Cache - */ -class MeshCache -{ -public: - /**get & destroy*/ - static MeshCache* getInstance(); - static void destroyInstance(); - - /**get mesh from cache*/ - Mesh* getMesh(const std::string& key) const; - - /**add mesh to cache*/ - bool addMesh(const std::string& key, Mesh* mesh); - - /**remove all meshes*/ - void removeAllMeshes(); - - /**remove unused meshes*/ - void removeUnusedMesh(); - -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) - void listenRendererRecreated(EventCustom* event); -#endif - -CC_CONSTRUCTOR_ACCESS: - - MeshCache(); - ~MeshCache(); - -protected: - - static MeshCache* _cacheInstance;//instance - - std::unordered_map _meshes; //cached meshes - -#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) - EventListenerCustom* _rendererRecreatedListener; -#endif -}; +//class CC_3D_DLL RenderMeshData +//{ +// typedef std::vector IndexArray; +// friend class Mesh; +//public: +// RenderMeshData(): _vertexsizeBytes(0) +// { +// } +// bool hasVertexAttrib(int attrib); +// bool init(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& subMeshIndices); +// bool init(const std::vector& vertices, int vertexSizeInFloat, const std::vector& subMeshIndices, const std::vector& attribs); +// +//protected: +// +// int calVertexSizeBytes(); +// +// int _vertexsizeBytes; +// ssize_t _vertexNum; +// std::vector _vertexs; +// std::vector _subMeshIndices; +// std::vector _vertexAttribs; +//}; +// +///** +// * Mesh: Geometry with a collection of vertex. +// * Supporting various vertex formats. +// */ +//class CC_3D_DLL Mesh : public Ref +//{ +// typedef std::vector IndexArray; +//public: +// /**create mesh from positions, normals, and so on, sigle SubMesh*/ +// static Mesh* create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const IndexArray& indices); +// +// /**create mesh from positions, normals, and so on, multi-SubMesh*/ +// static Mesh* create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& subMeshIndices); +// +// /**create mesh with vertex attributes*/ +// CC_DEPRECATED_ATTRIBUTE static Mesh* create(const std::vector& vertices, int vertexSizeInFloat, const IndexArray& indices, int numIndex, const std::vector& attribs, int attribCount) { return create(vertices, vertexSizeInFloat, indices, attribs); } +// +// /** +// * create Mesh +// * @param vertices vertices buffer data +// * @param vertexSizeInFloat size of each vertex +// * @param indices index buffer data that denotes how to connect the vertex, sigle SubMesh +// * @param attribs vertex attributes +// */ +// static Mesh* create(const std::vector& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector& attribs); +// +// /** +// * create Mesh +// * @param vertices vertices buffer data +// * @param vertexSizeInFloat size of each vertex +// * @param subMeshIndices index buffer data that denotes how to connect the vertex, multi-SubMesh +// * @param attribs vertex attributes +// */ +// static Mesh* create(const std::vector& vertices, int vertexSizeInFloat, const std::vector& subMeshIndices, const std::vector& attribs); +// +// static Mesh* create(const MeshData& meshdata); +// +// /**get vertex buffer*/ +// inline GLuint getVertexBuffer() const { return _vertexBuffer; } +// +// /**get mesh vertex attribute count*/ +// ssize_t getMeshVertexAttribCount() const { return _renderdata._vertexAttribs.size(); } +// /**get MeshVertexAttribute by index*/ +// const MeshVertexAttrib& getMeshVertexAttribute(int idx) const { return _renderdata._vertexAttribs[idx]; } +// /**has vertex attribute?*/ +// bool hasVertexAttrib(int attrib) { return _renderdata.hasVertexAttrib(attrib); } +// /**get per vertex size in bytes*/ +// int getVertexSizeInBytes() const { return _renderdata._vertexsizeBytes; } +// +// /**get sub mesh count*/ +// ssize_t getSubMeshCount() const { return _subMeshes.size(); } +// +// /**get sub mesh by index*/ +// SubMesh* getSubMesh(int index) const { return _subMeshes.at(index); } +// +// /**build vertex buffer from renderdata*/ +// void restore(); +// +// /** get submesh by id */ +// SubMesh* getSubMeshById(const std::string& subMeshId) const; +// +// /**to be deprecated, those functions have been moved to SubMesh*/ +// /** get primitive type*/ +// CC_DEPRECATED_ATTRIBUTE PrimitiveType getPrimitiveType() const { return _subMeshes.at(0)->getPrimitiveType(); } +// /**get index count*/ +// CC_DEPRECATED_ATTRIBUTE ssize_t getIndexCount() const { return _subMeshes.at(0)->getIndexCount(); } +// /**get index format*/ +// CC_DEPRECATED_ATTRIBUTE IndexFormat getIndexFormat() const { return _subMeshes.at(0)->getIndexFormat(); } +// /**get index buffer*/ +// CC_DEPRECATED_ATTRIBUTE GLuint getIndexBuffer() const {return _subMeshes.at(0)->getIndexBuffer(); } +// +//CC_CONSTRUCTOR_ACCESS: +// +// Mesh(); +// virtual ~Mesh(); +// /**init mesh*/ +// bool init(const std::vector& positions, const std::vector& normals, const std::vector& texs, const std::vector& indices); +// +// /**init mesh*/ +// bool init(const std::vector& vertices, int vertexSizeInFloat, const std::vector& indices, const std::vector& attribs); +// +// /**build sub meshes*/ +// void buildSubMeshes(); +// /**build buffer*/ +// void buildBuffer(); +// /**free buffer*/ +// void cleanAndFreeBuffers(); +// +//protected: +// GLuint _vertexBuffer; +// Vector _subMeshes; +// +// RenderMeshData _renderdata; +//}; +// +///** +// * Mesh Cache +// */ +//class MeshCache +//{ +//public: +// /**get & destroy*/ +// static MeshCache* getInstance(); +// static void destroyInstance(); +// +// /**get mesh from cache*/ +// Mesh* getMesh(const std::string& key) const; +// +// /**add mesh to cache*/ +// bool addMesh(const std::string& key, Mesh* mesh); +// +// /**remove all meshes*/ +// void removeAllMeshes(); +// +// /**remove unused meshes*/ +// void removeUnusedMesh(); +// +//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +// void listenRendererRecreated(EventCustom* event); +//#endif +// +//CC_CONSTRUCTOR_ACCESS: +// +// MeshCache(); +// ~MeshCache(); +// +//protected: +// +// static MeshCache* _cacheInstance;//instance +// +// std::unordered_map _meshes; //cached meshes +// +//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8) +// EventListenerCustom* _rendererRecreatedListener; +//#endif +//}; NS_CC_END diff --git a/cocos/3d/CCSprite3D.cpp b/cocos/3d/CCSprite3D.cpp index da17f67db0..9fd77bea89 100644 --- a/cocos/3d/CCSprite3D.cpp +++ b/cocos/3d/CCSprite3D.cpp @@ -78,8 +78,8 @@ bool Sprite3D::loadFromCache(const std::string& path) auto spritedata = Sprite3DCache::getInstance()->getSpriteData(path); if (spritedata) { - for (auto it : spritedata->meshes) { - _meshes.pushBack(it); + for (auto it : spritedata->meshVertexDatas) { + _meshVertexDatas.pushBack(it); } _skeleton = Skeleton3D::create(spritedata->nodedatas->skeleton); CC_SAFE_RETAIN(_skeleton); @@ -114,7 +114,7 @@ bool Sprite3D::loadFromObj(const std::string& path) auto data = new Sprite3DCache::Sprite3DData(); data->materialdatas = materialdatas; data->nodedatas = nodeDatas; - data->meshes = _meshes; + data->meshVertexDatas = _meshVertexDatas; Sprite3DCache::getInstance()->addSprite3DData(path, data); return true; } @@ -144,7 +144,7 @@ bool Sprite3D::loadFromC3x(const std::string& path) auto data = new Sprite3DCache::Sprite3DData(); data->materialdatas = materialdatas; data->nodedatas = nodeDatas; - data->meshes = _meshes; + data->meshVertexDatas = _meshVertexDatas; Sprite3DCache::getInstance()->addSprite3DData(path, data); return true; } @@ -164,18 +164,18 @@ Sprite3D::Sprite3D() Sprite3D::~Sprite3D() { - _subMeshStates.clear(); _glProgramStates.clear(); _meshes.clear(); + _meshVertexDatas.clear(); CC_SAFE_RELEASE_NULL(_skeleton); removeAllAttachNode(); } bool Sprite3D::initWithFile(const std::string &path) { - _subMeshStates.clear(); _meshes.clear(); _glProgramStates.clear(); + _meshVertexDatas.clear(); CC_SAFE_RELEASE_NULL(_skeleton); removeAllAttachNode(); @@ -204,8 +204,10 @@ bool Sprite3D::initFrom(const NodeDatas& nodeDatas, const MeshDatas& meshdatas, { if(it) { - Mesh* mesh = Mesh::create(*it); - _meshes.pushBack(mesh); +// Mesh* mesh = Mesh::create(*it); +// _meshes.pushBack(mesh); + auto meshvertex = MeshVertexData::create(*it); + _meshVertexDatas.pushBack(meshvertex); } } _skeleton = Skeleton3D::create(nodeDatas.skeleton); @@ -234,12 +236,11 @@ Sprite3D* Sprite3D::createSprite3DNode(NodeData* nodedata,ModelData* modeldata,c auto sprite = new Sprite3D(); if (sprite) { - auto subMeshState = SubMeshState::create(nodedata->id); - subMeshState->setSubMesh(getSubMesh(modeldata->subMeshId)); + auto mesh = Mesh::create(nodedata->id, getMeshIndexData(modeldata->subMeshId)); if (modeldata->matrialId == "" && matrialdatas.materials.size()) { const NTextureData* textureData = matrialdatas.materials[0].getTextureData(NTextureData::Usage::Diffuse); - subMeshState->setTexture(textureData->filename); + mesh->setTexture(textureData->filename); } else { @@ -258,14 +259,14 @@ Sprite3D* Sprite3D::createSprite3DNode(NodeData* nodedata,ModelData* modeldata,c texParams.wrapS = textureData->wrapS; texParams.wrapT = textureData->wrapT; tex->setTexParameters(texParams); - subMeshState->setTexture(tex); + mesh->setTexture(tex); } } } } sprite->setAdditionalTransform(&nodedata->transform); - sprite->addSubMeshState(subMeshState); + sprite->addMesh(mesh); sprite->autorelease(); sprite->genGLProgramState(); } @@ -291,8 +292,8 @@ void Sprite3D::createAttachSprite3DNode(NodeData* nodedata,const MaterialDatas& } void Sprite3D::genGLProgramState() { - std::unordered_map glProgramestates; - for(auto& mesh : _meshes) + std::unordered_map glProgramestates; + for(auto& mesh : _meshVertexDatas) { bool textured = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD); bool hasSkin = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_INDEX) @@ -315,12 +316,12 @@ void Sprite3D::genGLProgramState() long offset = 0; auto attributeCount = mesh->getMeshVertexAttribCount(); for (auto k = 0; k < attributeCount; k++) { - auto meshattribute = mesh->getMeshVertexAttribute(k); + auto meshattribute = mesh->getMeshVertexAttrib(k); programstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib], meshattribute.size, meshattribute.type, GL_FALSE, - mesh->getVertexSizeInBytes(), + mesh->getVertexBuffer()->getSizePerVertex(), (GLvoid*)offset); offset += meshattribute.attribSizeBytes; } @@ -329,8 +330,9 @@ void Sprite3D::genGLProgramState() glProgramestates[mesh] = programstate; } - for (auto& it : _subMeshStates) { - it->setGLProgramState(glProgramestates[it->getSubMesh()->getMesh()]); + for (auto& it : _meshes) { + auto glProgramState = glProgramestates[it->getMeshIndexData()->getMeshVertexData()]; + it->setGLProgramState(glProgramState); } } @@ -343,22 +345,21 @@ void Sprite3D::createNode(NodeData* nodedata, Node* root, const MaterialDatas& m { if(it->bones.size() > 0 || singleSprite) { - auto subMeshState = SubMeshState::create(nodedata->id); - if(subMeshState) + auto mesh = Mesh::create(nodedata->id, getMeshIndexData(it->subMeshId)); + if(mesh) { - _subMeshStates.pushBack(subMeshState); - subMeshState->setSubMesh(getSubMesh(it->subMeshId)); + _meshes.pushBack(mesh); if (_skeleton && it->bones.size()) { auto skin = MeshSkin::create(_skeleton, it->bones, it->invBindPose); - subMeshState->setSkin(skin); + mesh->setSkin(skin); } - subMeshState->_visibleChanged = std::bind(&Sprite3D::onAABBDirty, this); + mesh->_visibleChanged = std::bind(&Sprite3D::onAABBDirty, this); if (it->matrialId == "" && matrialdatas.materials.size()) { const NTextureData* textureData = matrialdatas.materials[0].getTextureData(NTextureData::Usage::Diffuse); - subMeshState->setTexture(textureData->filename); + mesh->setTexture(textureData->filename); } else { @@ -377,7 +378,7 @@ void Sprite3D::createNode(NodeData* nodedata, Node* root, const MaterialDatas& m texParams.wrapS = textureData->wrapS; texParams.wrapT = textureData->wrapT; tex->setTexParameters(texParams); - subMeshState->setTexture(tex); + mesh->setTexture(tex); } } @@ -417,20 +418,21 @@ void Sprite3D::createNode(NodeData* nodedata, Node* root, const MaterialDatas& m } } -SubMesh* Sprite3D::getSubMesh(const std::string& subMeshId) const +MeshIndexData* Sprite3D::getMeshIndexData(const std::string& indexId) const { - for (auto it : _meshes) { - auto subMesh = it->getSubMeshById(subMeshId); - if (subMesh) - return subMesh; + for (auto it : _meshVertexDatas) { + auto index = it->getMeshIndexDataById(indexId); + if (index) + return index; } return nullptr; } -void Sprite3D::addSubMeshState(SubMeshState* subMeshState) +void Sprite3D::addMesh(Mesh* mesh) { - _meshes.pushBack(subMeshState->getSubMesh()->getMesh()); - _subMeshStates.pushBack(subMeshState); + auto meshVertex = mesh->getMeshIndexData()->_vertexData; + _meshVertexDatas.pushBack(meshVertex); + _meshes.pushBack(mesh); } void Sprite3D::setTexture(const std::string& texFile) @@ -441,7 +443,7 @@ void Sprite3D::setTexture(const std::string& texFile) void Sprite3D::setTexture(Texture2D* texture) { - for (auto& state : _subMeshStates) { + for (auto& state : _meshes) { state->setTexture(texture); } } @@ -490,20 +492,20 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) color.a = getDisplayedOpacity() / 255.0f; int i = 0; - for (auto& submeshstate : _subMeshStates) { - if (!submeshstate->isVisible()) + for (auto& mesh : _meshes) { + if (!mesh->isVisible()) { i++; continue; } - auto programstate = submeshstate->getGLProgramState(); - auto& meshCommand = submeshstate->getMeshCommand(); + auto programstate = mesh->getGLProgramState(); + auto& meshCommand = mesh->getMeshCommand(); - GLuint textureID = submeshstate->getTexture() ? submeshstate->getTexture()->getName() : 0; - auto submesh = submeshstate->getSubMesh(); - meshCommand.init(_globalZOrder, textureID, programstate, _blend, submesh->getMesh()->getVertexBuffer(), submesh->getIndexBuffer(), (GLenum)submesh->getPrimitiveType(), (GLenum)submesh->getIndexFormat(), submesh->getIndexCount(), transform); + GLuint textureID = mesh->getTexture() ? mesh->getTexture()->getName() : 0; - auto skin = submeshstate->getSkin(); + meshCommand.init(_globalZOrder, textureID, programstate, _blend, mesh->getVertexBuffer(), mesh->getIndexBuffer(), mesh->getPrimitiveType(), mesh->getIndexFormat(), mesh->getIndexCount(), transform); + + auto skin = mesh->getSkin(); if (skin) { meshCommand.setMatrixPaletteSize((int)skin->getMatrixPaletteSize()); @@ -518,7 +520,7 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) void Sprite3D::setGLProgramState(GLProgramState *glProgramState) { Node::setGLProgramState(glProgramState); - for (auto& state : _subMeshStates) { + for (auto& state : _meshes) { state->setGLProgramState(glProgramState); } } @@ -533,7 +535,7 @@ void Sprite3D::setBlendFunc(const BlendFunc &blendFunc) if(_blend.src != blendFunc.src || _blend.dst != blendFunc.dst) { _blend = blendFunc; - for(auto& state : _subMeshStates) + for(auto& state : _meshes) { state->setBlendFunc(blendFunc); } @@ -558,7 +560,7 @@ const AABB& Sprite3D::getAABB() const { _aabb.reset(); Mat4 transform(nodeToWorldTransform); - for (const auto& it : _subMeshStates) { + for (const auto& it : _meshes) { if (it->isVisible()) _aabb.merge(it->getAABB()); } @@ -579,28 +581,28 @@ Rect Sprite3D::getBoundingBox() const void Sprite3D::setCullFace(GLenum cullFace) { - for (auto& it : _subMeshStates) { + for (auto& it : _meshes) { it->getMeshCommand().setCullFace(cullFace); } } void Sprite3D::setCullFaceEnabled(bool enable) { - for (auto& it : _subMeshStates) { + for (auto& it : _meshes) { it->getMeshCommand().setCullFaceEnabled(enable); } } -SubMeshState* Sprite3D::getSubMeshState(int index) const +Mesh* Sprite3D::getMeshByIndex(int index) const { - CCASSERT(index < _subMeshStates.size(), "invald index"); - return _subMeshStates.at(index); + CCASSERT(index < _meshes.size(), "invald index"); + return _meshes.at(index); } /**get SubMeshState by Name */ -SubMeshState* Sprite3D::getSubMeshStateByName(const std::string& name) const +Mesh* Sprite3D::getMeshByName(const std::string& name) const { - for (const auto& it : _subMeshStates) { + for (const auto& it : _meshes) { if (it->getName() == name) return it; } @@ -609,7 +611,7 @@ SubMeshState* Sprite3D::getSubMeshStateByName(const std::string& name) const MeshSkin* Sprite3D::getSkin() const { - for (const auto& it : _subMeshStates) { + for (const auto& it : _meshes) { if (it->getSkin()) return it->getSkin(); } diff --git a/cocos/3d/CCSprite3D.h b/cocos/3d/CCSprite3D.h index b035aa9f0e..a617e40696 100644 --- a/cocos/3d/CCSprite3D.h +++ b/cocos/3d/CCSprite3D.h @@ -36,6 +36,8 @@ #include "3d/CCAABB.h" #include "3d/CCBundle3DData.h" #include "3d/CCMesh.h" +#include "3d/CCSubMeshState.h" +#include "3d/CCSubMesh.h" #include "3d/3dExport.h" @@ -65,10 +67,10 @@ public: void setTexture(Texture2D* texture); /**get SubMeshState by index*/ - SubMeshState* getSubMeshState(int index) const; + Mesh* getMeshByIndex(int index) const; /**get SubMeshState by Name */ - SubMeshState* getSubMeshStateByName(const std::string& name) const; + Mesh* getMeshByName(const std::string& name) const; /**get mesh*/ Mesh* getMesh() const { return _meshes.at(0); } @@ -142,9 +144,11 @@ CC_CONSTRUCTOR_ACCESS: void createNode(NodeData* nodedata, Node* root, const MaterialDatas& matrialdatas, bool singleSprite); void createAttachSprite3DNode(NodeData* nodedata,const MaterialDatas& matrialdatas); Sprite3D* createSprite3DNode(NodeData* nodedata,ModelData* modeldata,const MaterialDatas& matrialdatas); - /**get SubMesh by Id*/ - SubMesh* getSubMesh(const std::string& subMeshId) const; - void addSubMeshState(SubMeshState* subMeshState); + + /**get MeshIndexData by Id*/ + MeshIndexData* getMeshIndexData(const std::string& indexId) const; + + void addMesh(Mesh* mesh); void onAABBDirty() { _aabbDirty = true; } @@ -152,7 +156,7 @@ protected: Skeleton3D* _skeleton; //skeleton - Vector _subMeshStates; // SubMeshStates + Vector _meshVertexDatas; std::unordered_map _attachments; @@ -173,7 +177,7 @@ class Sprite3DCache public: struct Sprite3DData { - Vector meshes; + Vector meshVertexDatas; NodeDatas* nodedatas; MaterialDatas* materialdatas; ~Sprite3DData() @@ -182,7 +186,7 @@ public: delete nodedatas; if (materialdatas) delete materialdatas; - meshes.clear(); + meshVertexDatas.clear(); } }; diff --git a/cocos/3d/CCSubMesh.cpp b/cocos/3d/CCSubMesh.cpp index 693d8d37d3..0794e2d561 100644 --- a/cocos/3d/CCSubMesh.cpp +++ b/cocos/3d/CCSubMesh.cpp @@ -46,66 +46,124 @@ using namespace std; NS_CC_BEGIN -SubMesh::SubMesh() -: _indexBuffer(0) -, _primitiveType(PrimitiveType::TRIANGLES) -, _indexFormat(IndexFormat::INDEX16) -, _indexCount(0) -, _mesh(nullptr) -{ -} -SubMesh::~SubMesh() +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +MeshIndexData* MeshIndexData::create(const std::string& id, MeshVertexData* vertexData, IndexBuffer* indexbuffer, const AABB& aabb) { - cleanAndFreeBuffers(); -} - -SubMesh* SubMesh::create(PrimitiveType primitivetype, IndexFormat indexformat, const std::vector& indices) -{ - auto submesh = new SubMesh(); - submesh->_primitiveType = primitivetype; - submesh->_indexFormat = indexformat; - submesh->autorelease(); + auto meshindex = new MeshIndexData(); - return submesh; -} - -SubMesh* SubMesh::create(const std::string& submeshId, Mesh* mesh, PrimitiveType primitivetype, IndexFormat indexformat, const std::vector& indices) -{ - auto submesh = new SubMesh(); - submesh->_primitiveType = primitivetype; - submesh->_indexFormat = indexformat; - submesh->_mesh = mesh; - submesh->_id = submeshId; - submesh->autorelease(); + meshindex->_id = id; + meshindex->_indexBuffer = indexbuffer; + meshindex->_vertexData = vertexData; + indexbuffer->retain(); + vertexData->retain(); + meshindex->_aabb = aabb; - return submesh; + meshindex->autorelease(); + return meshindex; } -void SubMesh::cleanAndFreeBuffers() +const VertexBuffer* MeshIndexData::getVertexBuffer() const { - if(glIsBuffer(_indexBuffer)) + return _vertexData->getVertexBuffer(); +} + +MeshIndexData::MeshIndexData() +: _indexBuffer(nullptr) +, _vertexData(nullptr) +, _primitiveType(GL_TRIANGLES) +{ + +} +MeshIndexData::~MeshIndexData() +{ + CC_SAFE_RELEASE(_indexBuffer); + CC_SAFE_RELEASE(_vertexData); +} + +MeshVertexData* MeshVertexData::create(const MeshData& meshdata) +{ + auto vertexdata = new MeshVertexData(); + int pervertexsize = meshdata.getPerVertexSize(); + vertexdata->_vertexBuffer = VertexBuffer::create(pervertexsize, (int)(meshdata.vertex.size() / (pervertexsize / 4))); + vertexdata->_vertexData = VertexData::create(); + CC_SAFE_RETAIN(vertexdata->_vertexData); + CC_SAFE_RETAIN(vertexdata->_vertexBuffer); + + int offset = 0; + for (const auto& it : meshdata.attribs) { + vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(offset, it.vertexAttrib, it.type, it.size)); + offset += it.attribSizeBytes; + } + vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(0, GLProgram::VERTEX_ATTRIB_POSITION, GL_FLOAT, 3)); + vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(offsetof(V3F_C4B_T2F, colors), GLProgram::VERTEX_ATTRIB_COLOR, GL_UNSIGNED_BYTE, 4, true)); + vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(offsetof(V3F_C4B_T2F, texCoords), GLProgram::VERTEX_ATTRIB_TEX_COORD, GL_FLOAT, 2)); + + vertexdata->_attribs = meshdata.attribs; + + if(vertexdata->_vertexBuffer) { - glDeleteBuffers(1, &_indexBuffer); - _indexBuffer = 0; + vertexdata->_vertexBuffer->updateVertices((void*)&meshdata.vertex[0], (int)meshdata.vertex.size() * 4, 0); } - _indexCount = 0; + AABB aabb; + for (size_t i = 0; i < meshdata.subMeshIndices.size(); i++) { + + auto& index = meshdata.subMeshIndices[i]; + auto indexBuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, (int)(index.size())); + indexBuffer->updateIndices(&index[0], (int)index.size(), 0); + aabb = MeshVertexData::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), index); + std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds[i] : ""); + MeshIndexData* indexdata = MeshIndexData::create(id, vertexdata, indexBuffer, aabb); + vertexdata->_indexs.pushBack(indexdata); + } + + vertexdata->autorelease(); + return vertexdata; } -void SubMesh::buildBuffer(const std::vector& indices) +const AABB& MeshVertexData::calculateAABB(const std::vector& vertex, int stride, const std::vector& index) +{ + static AABB aabb; + stride /= 4; + for(const auto& it : index) + { + Vec3 point = Vec3(vertex[it * stride ], vertex[ it * stride + 1], vertex[it * stride + 2 ]); + aabb.updateMinMax(&point, 1); + } + return aabb; +} + +MeshIndexData* MeshVertexData::getMeshIndexDataById(const std::string& id) const +{ + for (auto it : _indexs) { + if (it->getId() == id) + return it; + } + return nullptr; +} + +bool MeshVertexData::hasVertexAttrib(int attrib) const +{ + for (const auto& it : _attribs) { + if (it.vertexAttrib == attrib) + return true; + } + return false; +} + +MeshVertexData::MeshVertexData() +: _vertexData(nullptr) +, _vertexBuffer(nullptr) +, _vertexCount(0) { - glGenBuffers(1, &_indexBuffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); - - unsigned int indexSize = 2; - - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * indices.size(), &indices[0], GL_STATIC_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - _indexCount = indices.size(); +} +MeshVertexData::~MeshVertexData() +{ + CC_SAFE_RELEASE(_vertexData); + CC_SAFE_RELEASE(_vertexBuffer); + _indexs.clear(); } NS_CC_END diff --git a/cocos/3d/CCSubMesh.h b/cocos/3d/CCSubMesh.h index 546320b9bd..b3e70f107d 100644 --- a/cocos/3d/CCSubMesh.h +++ b/cocos/3d/CCSubMesh.h @@ -35,79 +35,93 @@ #include "base/ccTypes.h" #include "math/CCMath.h" #include "renderer/CCGLProgram.h" +#include "renderer/CCVertexIndexData.h" +#include "renderer/CCVertexIndexBuffer.h" #include "3d/3dExport.h" NS_CC_BEGIN -/** Defines supported index formats. */ -enum class IndexFormat -{ - INDEX8 = GL_UNSIGNED_BYTE, - INDEX16 = GL_UNSIGNED_SHORT, -}; +class MeshVertexData; -/** Defines supported primitive types. */ -enum class PrimitiveType +class MeshIndexData : public Ref { - TRIANGLES = GL_TRIANGLES, - TRIANGLE_STRIP = GL_TRIANGLE_STRIP, - LINES = GL_LINES, - LINE_STRIP = GL_LINE_STRIP, - POINTS = GL_POINTS -}; - -class Mesh; - -/** - * SubMesh: Defines the way the mesh's vertices how to be connected together. - */ -class CC_3D_DLL SubMesh : public Ref -{ - friend class Mesh; - friend class SubMeshState; public: - - /**create submesh from primitivetype indexformat and indices*/ - static SubMesh* create(PrimitiveType primitivetype, IndexFormat indexformat, const std::vector& indices); + /** create */ + static MeshIndexData* create(const std::string& id, MeshVertexData* vertexData, IndexBuffer* indexbuffer, const AABB& aabb); - static SubMesh* create(const std::string& submeshId, Mesh* mesh, PrimitiveType primitivetype, IndexFormat indexformat, const std::vector& indices); - - /** get primitive type*/ - PrimitiveType getPrimitiveType() const { return _primitiveType; } - /**get index count*/ - ssize_t getIndexCount() const { return _indexCount; } - /**get index format*/ - IndexFormat getIndexFormat() const { return _indexFormat; } /**get index buffer*/ - GLuint getIndexBuffer() const {return _indexBuffer; } + const IndexBuffer* getIndexBuffer() const { return _indexBuffer; } + /**get vertex buffer*/ + const VertexBuffer* getVertexBuffer() const; - /** get mesh */ - Mesh* getMesh() const { return _mesh; } + /**get vertex data*/ + const MeshVertexData* getMeshVertexData() const { return _vertexData; } - /** get submesh id */ - const std::string& getSubMeshId() const { return _id; } - -CC_CONSTRUCTOR_ACCESS: - - SubMesh(); - virtual ~SubMesh(); - - /**build buffer*/ - void buildBuffer(const std::vector& indices); - /**free buffer*/ - void cleanAndFreeBuffers(); - + /** aabb getter and setter */ + void setAABB(const AABB& aabb) { _aabb = aabb; } const AABB& getAABB() const { return _aabb; } -protected: - PrimitiveType _primitiveType; - IndexFormat _indexFormat; - - GLuint _indexBuffer; - ssize_t _indexCount; - Mesh* _mesh; //parent mesh, weak ref - std::string _id; //submeshid - AABB _aabb; //original aabb of the submesh + /** id setter and getter */ + void setId(const std::string& id) { _id = id; } + const std::string& getId() const { return _id; } + + GLenum getPrimitiveType() const { return _primitiveType; } + void setPrimitiveType(GLenum primitive) { _primitiveType = primitive; } + +CC_CONSTRUCTOR_ACCESS: + MeshIndexData(); + virtual ~MeshIndexData(); + +protected: + IndexBuffer* _indexBuffer; //index buffer + MeshVertexData* _vertexData; //vertex buffer + AABB _aabb; // original aabb of the submesh + std::string _id; //id + GLenum _primitiveType; + + friend class MeshVertexData; + friend class Sprite3D; +}; + +class MeshVertexData : public Ref +{ + friend class Sprite3D; + friend class Mesh; +public: + /**create*/ + static MeshVertexData* create(const MeshData& meshdata); + + /** get vertexbuffer */ + const VertexBuffer* getVertexBuffer() const { return _vertexBuffer; } + + /** get attributes count */ + ssize_t getMeshVertexAttribCount() const { return _attribs.size(); } + + /** get attribute by index */ + const MeshVertexAttrib& getMeshVertexAttrib(ssize_t index) const { return _attribs[index]; } + + /** get index data count */ + ssize_t getMeshIndexDataCount() const { return _indexs.size(); } + /** get index data by index */ + MeshIndexData* getMeshIndexDataByIndex(int index) const { return _indexs.at(index); } + /** get index data by id */ + MeshIndexData* getMeshIndexDataById(const std::string& id) const; + + /**has vertex attribute?*/ + bool hasVertexAttrib(int attrib) const; + +CC_CONSTRUCTOR_ACCESS: + MeshVertexData(); + virtual ~MeshVertexData(); + + static const AABB& calculateAABB(const std::vector& vertex, int stride, const std::vector& index); +protected: + VertexData* _vertexData; //mesh vertex data + VertexBuffer* _vertexBuffer; // vertex buffer + Vector _indexs; //index data + std::vector _attribs; + + int _vertexCount; //vertex count }; NS_CC_END diff --git a/cocos/3d/CCSubMeshState.cpp b/cocos/3d/CCSubMeshState.cpp index 99819279d5..da495a8a61 100644 --- a/cocos/3d/CCSubMeshState.cpp +++ b/cocos/3d/CCSubMeshState.cpp @@ -48,45 +48,136 @@ using namespace std; NS_CC_BEGIN -SubMeshState::SubMeshState() +Mesh::Mesh() : _visible(true) , _texture(nullptr) , _skin(nullptr) -, _subMesh(nullptr) +, _meshIndexData(nullptr) , _visibleChanged(nullptr) , _glProgramState(nullptr) , _blend(BlendFunc::ALPHA_NON_PREMULTIPLIED) { } -SubMeshState::~SubMeshState() +Mesh::~Mesh() { CC_SAFE_RELEASE(_texture); CC_SAFE_RELEASE(_skin); - CC_SAFE_RELEASE(_subMesh); + CC_SAFE_RELEASE(_meshIndexData); CC_SAFE_RELEASE(_glProgramState); } -SubMeshState* SubMeshState::create() +GLuint Mesh::getVertexBuffer() const { - auto state = new SubMeshState(); - state->autorelease(); - state->bindMeshCommand(); - - return state; + return _meshIndexData->getVertexBuffer()->getVBO(); } -SubMeshState* SubMeshState::create(const std::string& name) +bool Mesh::hasVertexAttrib(int attrib) const { - auto state = new SubMeshState(); + return _meshIndexData->getMeshVertexData()->hasVertexAttrib(attrib); +} + +ssize_t Mesh::getMeshVertexAttribCount() const +{ + return _meshIndexData->getMeshVertexData()->getMeshVertexAttribCount(); +} + +const MeshVertexAttrib& Mesh::getMeshVertexAttribute(int idx) +{ + return _meshIndexData->getMeshVertexData()->getMeshVertexAttrib(idx); +} + +int Mesh::getVertexSizeInBytes() const +{ + return _meshIndexData->getVertexBuffer()->getSizePerVertex(); +} + +Mesh* Mesh::create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const IndexArray& indices) +{ + int perVertexSizeInFloat = 0; + std::vector vertices; + std::vector attribs; + MeshVertexAttrib att; + att.size = 3; + att.type = GL_FLOAT; + att.attribSizeBytes = att.size * sizeof(float); + + if (positions.size()) + { + perVertexSizeInFloat += 3; + att.vertexAttrib = GLProgram::VERTEX_ATTRIB_POSITION; + attribs.push_back(att); + } + if (normals.size()) + { + perVertexSizeInFloat += 3; + att.vertexAttrib = GLProgram::VERTEX_ATTRIB_NORMAL; + attribs.push_back(att); + } + if (texs.size()) + { + perVertexSizeInFloat += 2; + att.vertexAttrib = GLProgram::VERTEX_ATTRIB_TEX_COORD; + att.size = 2; + att.attribSizeBytes = att.size * sizeof(float); + attribs.push_back(att); + } + + bool hasNormal = (normals.size() != 0); + bool hasTexCoord = (texs.size() != 0); + //position, normal, texCoordinate into _vertexs + size_t vertexNum = positions.size() / 3; + for(size_t i = 0; i < vertexNum; i++) + { + vertices.push_back(positions[i * 3]); + vertices.push_back(positions[i * 3 + 1]); + vertices.push_back(positions[i * 3 + 2]); + + if (hasNormal) + { + vertices.push_back(normals[i * 3]); + vertices.push_back(normals[i * 3 + 1]); + vertices.push_back(normals[i * 3 + 2]); + } + + if (hasTexCoord) + { + vertices.push_back(texs[i * 2]); + vertices.push_back(texs[i * 2 + 1]); + } + } + return create(vertices, perVertexSizeInFloat, indices, attribs); +} + +Mesh* Mesh::create(const std::vector& vertices, int perVertexSizeInFloat, const IndexArray& indices, const std::vector& attribs) +{ + MeshData meshdata; + meshdata.attribs = attribs; + meshdata.vertex = vertices; + meshdata.subMeshIndices.push_back(indices); + meshdata.subMeshIds.push_back(""); + auto meshvertexdata = MeshVertexData::create(meshdata); + auto indexbuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, (int)indices.size()); + + AABB aabb = MeshVertexData::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), indices); + auto indexData = MeshIndexData::create("", meshvertexdata, indexbuffer, aabb); + + return create("", indexData); +} + +Mesh* Mesh::create(const std::string& name, MeshIndexData* indexData, MeshSkin* skin) +{ + auto state = new Mesh(); state->autorelease(); state->bindMeshCommand(); state->_name = name; + state->setMeshIndexData(indexData); + state->setSkin(skin); return state; } -void SubMeshState::setVisible(bool visible) +void Mesh::setVisible(bool visible) { if (_visible != visible) { @@ -96,13 +187,13 @@ void SubMeshState::setVisible(bool visible) } } -void SubMeshState::setTexture(const std::string& texPath) +void Mesh::setTexture(const std::string& texPath) { auto tex = Director::getInstance()->getTextureCache()->addImage(texPath); setTexture(tex); } -void SubMeshState::setTexture(Texture2D* tex) +void Mesh::setTexture(Texture2D* tex) { if (tex != _texture) { @@ -113,7 +204,7 @@ void SubMeshState::setTexture(Texture2D* tex) } } -void SubMeshState::setSkin(MeshSkin* skin) +void Mesh::setSkin(MeshSkin* skin) { if (_skin != skin) { @@ -124,19 +215,19 @@ void SubMeshState::setSkin(MeshSkin* skin) } } -void SubMeshState::setSubMesh(SubMesh* subMesh) +void Mesh::setMeshIndexData(MeshIndexData* subMesh) { - if (_subMesh != subMesh) + if (_meshIndexData != subMesh) { CC_SAFE_RETAIN(subMesh); - CC_SAFE_RELEASE(_subMesh); - _subMesh = subMesh; + CC_SAFE_RELEASE(_meshIndexData); + _meshIndexData = subMesh; calcuateAABB(); bindMeshCommand(); } } -void SubMeshState::setGLProgramState(GLProgramState* glProgramState) +void Mesh::setGLProgramState(GLProgramState* glProgramState) { if (_glProgramState != glProgramState) { @@ -147,11 +238,11 @@ void SubMeshState::setGLProgramState(GLProgramState* glProgramState) } } -void SubMeshState::calcuateAABB() +void Mesh::calcuateAABB() { - if (_subMesh) + if (_meshIndexData) { - _aabb = _subMesh->getAABB(); + _aabb = _meshIndexData->getAABB(); if (_skin) { Bone3D* root = _skin->getRootBone(); @@ -163,18 +254,18 @@ void SubMeshState::calcuateAABB() } } -void SubMeshState::bindMeshCommand() +void Mesh::bindMeshCommand() { - if (_glProgramState && _subMesh && _texture) + if (_glProgramState && _meshIndexData && _texture) { GLuint texID = _texture ? _texture->getName() : 0; - _meshCommand.genMaterialID(texID, _glProgramState, _subMesh->getMesh()->getVertexBuffer(), _subMesh->getIndexBuffer(), _blend); + _meshCommand.genMaterialID(texID, _glProgramState, _meshIndexData->getVertexBuffer()->getVBO(), _meshIndexData->getIndexBuffer()->getVBO(), _blend); _meshCommand.setCullFaceEnabled(true); _meshCommand.setDepthTestEnabled(true); } } -void SubMeshState::setBlendFunc(const BlendFunc &blendFunc) +void Mesh::setBlendFunc(const BlendFunc &blendFunc) { if(_blend.src != blendFunc.src || _blend.dst != blendFunc.dst) { @@ -182,9 +273,29 @@ void SubMeshState::setBlendFunc(const BlendFunc &blendFunc) bindMeshCommand(); } } -const BlendFunc &SubMeshState::getBlendFunc() const +const BlendFunc &Mesh::getBlendFunc() const { return _blend; } +GLenum Mesh::getPrimitiveType() const +{ + return _meshIndexData->getPrimitiveType(); +} + +ssize_t Mesh::getIndexCount() const +{ + return _meshIndexData->getIndexBuffer()->getIndexNumber(); +} + +GLenum Mesh::getIndexFormat() const +{ + return GL_UNSIGNED_SHORT; +} + +GLuint Mesh::getIndexBuffer() const +{ + return _meshIndexData->getIndexBuffer()->getVBO(); +} + NS_CC_END diff --git a/cocos/3d/CCSubMeshState.h b/cocos/3d/CCSubMeshState.h index f453220ec5..7962e9339c 100644 --- a/cocos/3d/CCSubMeshState.h +++ b/cocos/3d/CCSubMeshState.h @@ -43,19 +43,35 @@ NS_CC_BEGIN class Texture2D; class MeshSkin; -class SubMesh; +class MeshIndexData; /** * SubMeshState: visibility and apperence of submesh */ -class CC_3D_DLL SubMeshState : public Ref +class CC_3D_DLL Mesh : public Ref { friend class Sprite3D; public: - - /**create submesh from primitivetype indexformat and indices*/ - static SubMeshState* create(); + typedef std::vector IndexArray; + /**create mesh from positions, normals, and so on, sigle SubMesh*/ + static Mesh* create(const std::vector& positions, const std::vector& normals, const std::vector& texs, const IndexArray& indices); + /**create mesh with vertex attributes*/ + CC_DEPRECATED_ATTRIBUTE static Mesh* create(const std::vector& vertices, int perVertexSizeInFloat, const IndexArray& indices, int numIndex, const std::vector& attribs, int attribCount){ return create(vertices, perVertexSizeInFloat, indices, attribs); } - static SubMeshState* create(const std::string& name); + static Mesh* create(const std::vector& vertices, int perVertexSizeInFloat, const IndexArray& indices, const std::vector& attribs); + + /** create mesh */ + static Mesh* create(const std::string& name, MeshIndexData* indexData, MeshSkin* skin = nullptr); + + /**get vertex buffer*/ + GLuint getVertexBuffer() const; + /**has vertex attribute?*/ + bool hasVertexAttrib(int attrib) const; + /**get mesh vertex attribute count*/ + ssize_t getMeshVertexAttribCount() const; + /**get MeshVertexAttribute by index*/ + const MeshVertexAttrib& getMeshVertexAttribute(int idx); + /**get per vertex size in bytes*/ + int getVertexSizeInBytes() const; /**texture getter and setter*/ void setTexture(const std::string& texPath); @@ -69,8 +85,8 @@ public: /**skin getter */ MeshSkin* getSkin() const { return _skin; } - /**sub mesh getter */ - SubMesh* getSubMesh() const { return _subMesh; } + /**mesh index data getter */ + MeshIndexData* getMeshIndexData() const { return _meshIndexData; } /**get GLProgramState*/ GLProgramState* getGLProgramState() const { return _glProgramState; } @@ -80,11 +96,20 @@ public: void setBlendFunc(const BlendFunc &blendFunc); const BlendFunc &getBlendFunc() const; + + /** get primitive type*/ + GLenum getPrimitiveType() const; + /**get index count*/ + ssize_t getIndexCount() const; + /**get index format*/ + GLenum getIndexFormat() const; + /**get index buffer*/ + GLuint getIndexBuffer() const; CC_CONSTRUCTOR_ACCESS: - SubMeshState(); - virtual ~SubMeshState(); + Mesh(); + virtual ~Mesh(); GLProgram* getDefaultGLProgram(bool textured); @@ -94,8 +119,8 @@ CC_CONSTRUCTOR_ACCESS: /**skin setter*/ void setSkin(MeshSkin* skin); - /**submesh setter*/ - void setSubMesh(SubMesh* subMesh); + /**Mesh index data setter*/ + void setMeshIndexData(MeshIndexData* indexdata); /**name setter*/ void setName(const std::string& name) { _name = name; } @@ -111,7 +136,7 @@ protected: //since 3.3 std::string _name; - SubMesh* _subMesh; + MeshIndexData* _meshIndexData; GLProgramState* _glProgramState; MeshCommand _meshCommand; BlendFunc _blend; diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index 0047a49e98..f1812c5a6c 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -30,6 +30,7 @@ #include "3d/CCAttachNode.h" #include "3d/CCRay.h" #include "3d/CCSprite3D.h" +#include "renderer/CCVertexIndexBuffer.h" #include "DrawNode3D.h" #include @@ -489,7 +490,7 @@ void Effect3DOutline::setTarget(EffectSprite3D *sprite) if(sprite != _sprite) { GLProgram* glprogram; - if(!sprite->getSkin()) + if(!sprite->getMesh()->getSkin()) glprogram = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile); else glprogram = GLProgram::createWithFilenames(_vertSkinnedShaderFile, _fragSkinnedShaderFile); @@ -545,22 +546,21 @@ void Effect3DOutline::draw(const Mat4 &transform) auto mesh = _sprite->getMesh(); glBindBuffer(GL_ARRAY_BUFFER, mesh->getVertexBuffer()); - if(_sprite && _sprite->getSkin()) + auto skin = _sprite->getMesh()->getSkin(); + if(_sprite && skin) { auto function = std::bind(MatrixPalleteCallBack, std::placeholders::_1, std::placeholders::_2, - _sprite->getSkin()->getMatrixPaletteSize(), (float*)_sprite->getSkin()->getMatrixPalette()); + skin->getMatrixPaletteSize(), (float*)skin->getMatrixPalette()); _glProgramState->setUniformCallback("u_matrixPalette", function); } if(_sprite) _glProgramState->apply(transform); - for (ssize_t i = 0; i < mesh->getSubMeshCount(); i++) { - auto submesh = mesh->getSubMesh((int)i); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, submesh->getIndexBuffer()); - glDrawElements((GLenum)submesh->getPrimitiveType(), (GLsizei)submesh->getIndexCount(), (GLenum)submesh->getIndexFormat(), 0); - CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, submesh->getIndexCount()); - } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->getIndexBuffer()); + glDrawElements(mesh->getPrimitiveType(), mesh->getIndexCount(), mesh->getIndexFormat(), 0); + CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, mesh->getIndexCount()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisable(GL_DEPTH_TEST); @@ -1040,7 +1040,7 @@ void Sprite3DReskinTest::menuCallback_switchHair(Ref* sender) { for(int i = 0; i < 2; i++ ) { - SubMeshState* subMesh = _sprite->getSubMeshStateByName(_girlHair[i]); + auto subMesh = _sprite->getMeshByName(_girlHair[i]); if(subMesh) { if(i == _useHairId ) @@ -1057,7 +1057,7 @@ void Sprite3DReskinTest::menuCallback_switchHair(Ref* sender) } void Sprite3DReskinTest::menuCallback_switchGlasses(Ref* sender) { - SubMeshState* subMesh = _sprite->getSubMeshStateByName("Girl_Yanjing_01"); + auto subMesh = _sprite->getMeshByName("Girl_Yanjing_01"); if(subMesh) { if(subMesh->isVisible()) @@ -1081,7 +1081,7 @@ void Sprite3DReskinTest::menuCallback_switchCoat(Ref* sender) { for(int i = 0; i < 2; i++ ) { - SubMeshState* subMesh = _sprite->getSubMeshStateByName(_girlUpperBody[i]); + auto subMesh = _sprite->getMeshByName(_girlUpperBody[i]); if(subMesh) { if(i == _useUpBodyId ) @@ -1107,7 +1107,7 @@ void Sprite3DReskinTest::menuCallback_switchPants(Ref* sender) { for(int i = 0; i < 2; i++ ) { - SubMeshState* subMesh = _sprite->getSubMeshStateByName(_girlPants[i]); + auto subMesh = _sprite->getMeshByName(_girlPants[i]); if(subMesh) { if(i == _usePantsId ) @@ -1133,7 +1133,7 @@ void Sprite3DReskinTest::menuCallback_switchShoes(Ref* sender) { for(int i = 0; i < 2; i++ ) { - SubMeshState* subMesh = _sprite->getSubMeshStateByName(_girlShoes[i]); + auto subMesh = _sprite->getMeshByName(_girlShoes[i]); if(subMesh) { if(i == _useShoesId ) @@ -1177,22 +1177,22 @@ void Sprite3DReskinTest::addNewSpriteWithCoords(Vec2 p) auto sprite = Sprite3D::create(fileName); sprite->setScale(4); sprite->setRotation3D(Vec3(0,0,0)); - auto girlPants = sprite->getSubMeshStateByName(_girlPants[1]); + auto girlPants = sprite->getMeshByName(_girlPants[1]); if(girlPants) { girlPants->setVisible(false); } - auto girlShoes = sprite->getSubMeshStateByName(_girlShoes[1]); + auto girlShoes = sprite->getMeshByName(_girlShoes[1]); if(girlShoes) { girlShoes->setVisible(false); } - auto girlHair = sprite->getSubMeshStateByName(_girlHair[1]); + auto girlHair = sprite->getMeshByName(_girlHair[1]); if(girlHair) { girlHair->setVisible(false); } - auto girlUpBody = sprite->getSubMeshStateByName( _girlUpperBody[1]); + auto girlUpBody = sprite->getMeshByName( _girlUpperBody[1]); if(girlUpBody) { girlUpBody->setVisible(false); diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Lian.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Lian.png new file mode 100644 index 0000000000..9dc0b7634d Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Lian.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Maozi_01.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Maozi_01.png new file mode 100644 index 0000000000..d7d47ac29f Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Maozi_01.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_01.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_01.png new file mode 100644 index 0000000000..3b8233a4b7 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_01.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_02.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_02.png new file mode 100644 index 0000000000..ec01cd6806 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_02.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_03.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_03.png new file mode 100644 index 0000000000..0e8821b78d Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shangshen_03.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shou_01.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shou_01.png new file mode 100644 index 0000000000..f95fecae54 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Shou_01.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Toufa_01.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Toufa_01.png new file mode 100644 index 0000000000..05d3f1b060 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Toufa_01.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Toufa_02.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Toufa_02.png new file mode 100644 index 0000000000..c86e87ba27 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Toufa_02.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xiashen_01.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xiashen_01.png new file mode 100644 index 0000000000..3b8ee9c27d Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xiashen_01.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xiashen_02.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xiashen_02.png new file mode 100644 index 0000000000..8815077867 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xiashen_02.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xie_01.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xie_01.png new file mode 100644 index 0000000000..42d35215c2 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xie_01.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xie_02.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xie_02.png new file mode 100644 index 0000000000..9e9f9d2899 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Xie_02.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Girl_Yanjing_01.png b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Yanjing_01.png new file mode 100644 index 0000000000..0754928550 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Girl_Yanjing_01.png differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/ReskinGirl.c3b b/tests/cpp-tests/Resources/Sprite3DTest/ReskinGirl.c3b new file mode 100644 index 0000000000..001818417f Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/ReskinGirl.c3b differ diff --git a/tests/cpp-tests/Resources/Sprite3DTest/Xie_01.png b/tests/cpp-tests/Resources/Sprite3DTest/Xie_01.png new file mode 100644 index 0000000000..42d35215c2 Binary files /dev/null and b/tests/cpp-tests/Resources/Sprite3DTest/Xie_01.png differ