engine adjust
|
@ -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();
|
||||
|
|
|
@ -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<float>& positions,
|
||||
const std::vector<float>& normals,
|
||||
const std::vector<float>& texs,
|
||||
const std::vector<IndexArray>& 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<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& 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<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const IndexArray& indices)
|
||||
{
|
||||
std::vector<IndexArray> submeshIndices;
|
||||
submeshIndices.push_back(indices);
|
||||
return create(positions, normals, texs, submeshIndices);
|
||||
}
|
||||
|
||||
Mesh* Mesh::create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& 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<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& attribs)
|
||||
{
|
||||
std::vector<IndexArray> submeshIndices;
|
||||
submeshIndices.push_back(indices);
|
||||
return create(vertices, vertexSizeInFloat, submeshIndices, attribs);
|
||||
}
|
||||
|
||||
Mesh* Mesh::create(const std::vector<float> &vertices, int vertexSizeInFloat, const std::vector<IndexArray> &indices, const std::vector<MeshVertexAttrib> &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<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& indices)
|
||||
{
|
||||
bool bRet = _renderdata.init(positions, normals, texs, indices);
|
||||
if (!bRet)
|
||||
return false;
|
||||
|
||||
buildSubMeshes();
|
||||
|
||||
buildBuffer();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Mesh::init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& 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<float>& positions,
|
||||
// const std::vector<float>& normals,
|
||||
// const std::vector<float>& texs,
|
||||
// const std::vector<IndexArray>& 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<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& 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<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const IndexArray& indices)
|
||||
//{
|
||||
// std::vector<IndexArray> submeshIndices;
|
||||
// submeshIndices.push_back(indices);
|
||||
// return create(positions, normals, texs, submeshIndices);
|
||||
//}
|
||||
//
|
||||
//Mesh* Mesh::create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& 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<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& attribs)
|
||||
//{
|
||||
// std::vector<IndexArray> submeshIndices;
|
||||
// submeshIndices.push_back(indices);
|
||||
// return create(vertices, vertexSizeInFloat, submeshIndices, attribs);
|
||||
//}
|
||||
//
|
||||
//Mesh* Mesh::create(const std::vector<float> &vertices, int vertexSizeInFloat, const std::vector<IndexArray> &indices, const std::vector<MeshVertexAttrib> &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<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& indices)
|
||||
//{
|
||||
// bool bRet = _renderdata.init(positions, normals, texs, indices);
|
||||
// if (!bRet)
|
||||
// return false;
|
||||
//
|
||||
// buildSubMeshes();
|
||||
//
|
||||
// buildBuffer();
|
||||
//
|
||||
// return true;
|
||||
//}
|
||||
//
|
||||
//
|
||||
//bool Mesh::init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& 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
|
||||
|
|
|
@ -46,165 +46,165 @@ NS_CC_BEGIN
|
|||
class EventListenerCustom;
|
||||
class EventCustom;
|
||||
|
||||
class CC_3D_DLL RenderMeshData
|
||||
{
|
||||
typedef std::vector<unsigned short> IndexArray;
|
||||
friend class Mesh;
|
||||
public:
|
||||
RenderMeshData(): _vertexsizeBytes(0)
|
||||
{
|
||||
}
|
||||
bool hasVertexAttrib(int attrib);
|
||||
bool init(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& subMeshIndices);
|
||||
bool init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& subMeshIndices, const std::vector<MeshVertexAttrib>& attribs);
|
||||
|
||||
protected:
|
||||
|
||||
int calVertexSizeBytes();
|
||||
|
||||
int _vertexsizeBytes;
|
||||
ssize_t _vertexNum;
|
||||
std::vector<float> _vertexs;
|
||||
std::vector<IndexArray> _subMeshIndices;
|
||||
std::vector<MeshVertexAttrib> _vertexAttribs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mesh: Geometry with a collection of vertex.
|
||||
* Supporting various vertex formats.
|
||||
*/
|
||||
class CC_3D_DLL Mesh : public Ref
|
||||
{
|
||||
typedef std::vector<unsigned short> IndexArray;
|
||||
public:
|
||||
/**create mesh from positions, normals, and so on, sigle SubMesh*/
|
||||
static Mesh* create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const IndexArray& indices);
|
||||
|
||||
/**create mesh from positions, normals, and so on, multi-SubMesh*/
|
||||
static Mesh* create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& subMeshIndices);
|
||||
|
||||
/**create mesh with vertex attributes*/
|
||||
CC_DEPRECATED_ATTRIBUTE static Mesh* create(const std::vector<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, int numIndex, const std::vector<MeshVertexAttrib>& 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<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& 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<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& subMeshIndices, const std::vector<MeshVertexAttrib>& 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<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& indices);
|
||||
|
||||
/**init mesh*/
|
||||
bool init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& attribs);
|
||||
|
||||
/**build sub meshes*/
|
||||
void buildSubMeshes();
|
||||
/**build buffer*/
|
||||
void buildBuffer();
|
||||
/**free buffer*/
|
||||
void cleanAndFreeBuffers();
|
||||
|
||||
protected:
|
||||
GLuint _vertexBuffer;
|
||||
Vector<SubMesh*> _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<std::string, Mesh*> _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<unsigned short> IndexArray;
|
||||
// friend class Mesh;
|
||||
//public:
|
||||
// RenderMeshData(): _vertexsizeBytes(0)
|
||||
// {
|
||||
// }
|
||||
// bool hasVertexAttrib(int attrib);
|
||||
// bool init(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& subMeshIndices);
|
||||
// bool init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& subMeshIndices, const std::vector<MeshVertexAttrib>& attribs);
|
||||
//
|
||||
//protected:
|
||||
//
|
||||
// int calVertexSizeBytes();
|
||||
//
|
||||
// int _vertexsizeBytes;
|
||||
// ssize_t _vertexNum;
|
||||
// std::vector<float> _vertexs;
|
||||
// std::vector<IndexArray> _subMeshIndices;
|
||||
// std::vector<MeshVertexAttrib> _vertexAttribs;
|
||||
//};
|
||||
//
|
||||
///**
|
||||
// * Mesh: Geometry with a collection of vertex.
|
||||
// * Supporting various vertex formats.
|
||||
// */
|
||||
//class CC_3D_DLL Mesh : public Ref
|
||||
//{
|
||||
// typedef std::vector<unsigned short> IndexArray;
|
||||
//public:
|
||||
// /**create mesh from positions, normals, and so on, sigle SubMesh*/
|
||||
// static Mesh* create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const IndexArray& indices);
|
||||
//
|
||||
// /**create mesh from positions, normals, and so on, multi-SubMesh*/
|
||||
// static Mesh* create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& subMeshIndices);
|
||||
//
|
||||
// /**create mesh with vertex attributes*/
|
||||
// CC_DEPRECATED_ATTRIBUTE static Mesh* create(const std::vector<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, int numIndex, const std::vector<MeshVertexAttrib>& 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<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& 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<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& subMeshIndices, const std::vector<MeshVertexAttrib>& 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<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& indices);
|
||||
//
|
||||
// /**init mesh*/
|
||||
// bool init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& attribs);
|
||||
//
|
||||
// /**build sub meshes*/
|
||||
// void buildSubMeshes();
|
||||
// /**build buffer*/
|
||||
// void buildBuffer();
|
||||
// /**free buffer*/
|
||||
// void cleanAndFreeBuffers();
|
||||
//
|
||||
//protected:
|
||||
// GLuint _vertexBuffer;
|
||||
// Vector<SubMesh*> _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<std::string, Mesh*> _meshes; //cached meshes
|
||||
//
|
||||
//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
|
||||
// EventListenerCustom* _rendererRecreatedListener;
|
||||
//#endif
|
||||
//};
|
||||
|
||||
NS_CC_END
|
||||
|
||||
|
|
|
@ -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<Mesh*, GLProgramState*> glProgramestates;
|
||||
for(auto& mesh : _meshes)
|
||||
std::unordered_map<const MeshVertexData*, GLProgramState*> 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();
|
||||
}
|
||||
|
|
|
@ -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<SubMeshState*> _subMeshStates; // SubMeshStates
|
||||
Vector<MeshVertexData*> _meshVertexDatas;
|
||||
|
||||
std::unordered_map<std::string, AttachNode*> _attachments;
|
||||
|
||||
|
@ -173,7 +177,7 @@ class Sprite3DCache
|
|||
public:
|
||||
struct Sprite3DData
|
||||
{
|
||||
Vector<Mesh*> meshes;
|
||||
Vector<MeshVertexData*> meshVertexDatas;
|
||||
NodeDatas* nodedatas;
|
||||
MaterialDatas* materialdatas;
|
||||
~Sprite3DData()
|
||||
|
@ -182,7 +186,7 @@ public:
|
|||
delete nodedatas;
|
||||
if (materialdatas)
|
||||
delete materialdatas;
|
||||
meshes.clear();
|
||||
meshVertexDatas.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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<unsigned short>& 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<unsigned short>& 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<unsigned short>& indices)
|
||||
const AABB& MeshVertexData::calculateAABB(const std::vector<float>& vertex, int stride, const std::vector<unsigned short>& 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
|
||||
|
|
|
@ -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<unsigned short>& 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<unsigned short>& 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<unsigned short>& 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<float>& vertex, int stride, const std::vector<unsigned short>& index);
|
||||
protected:
|
||||
VertexData* _vertexData; //mesh vertex data
|
||||
VertexBuffer* _vertexBuffer; // vertex buffer
|
||||
Vector<MeshIndexData*> _indexs; //index data
|
||||
std::vector<MeshVertexAttrib> _attribs;
|
||||
|
||||
int _vertexCount; //vertex count
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -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<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const IndexArray& indices)
|
||||
{
|
||||
int perVertexSizeInFloat = 0;
|
||||
std::vector<float> vertices;
|
||||
std::vector<MeshVertexAttrib> 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<float>& vertices, int perVertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& 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
|
||||
|
|
|
@ -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<unsigned short> IndexArray;
|
||||
/**create mesh from positions, normals, and so on, sigle SubMesh*/
|
||||
static Mesh* create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const IndexArray& indices);
|
||||
/**create mesh with vertex attributes*/
|
||||
CC_DEPRECATED_ATTRIBUTE static Mesh* create(const std::vector<float>& vertices, int perVertexSizeInFloat, const IndexArray& indices, int numIndex, const std::vector<MeshVertexAttrib>& attribs, int attribCount){ return create(vertices, perVertexSizeInFloat, indices, attribs); }
|
||||
|
||||
static SubMeshState* create(const std::string& name);
|
||||
static Mesh* create(const std::vector<float>& vertices, int perVertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& 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;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "3d/CCAttachNode.h"
|
||||
#include "3d/CCRay.h"
|
||||
#include "3d/CCSprite3D.h"
|
||||
#include "renderer/CCVertexIndexBuffer.h"
|
||||
#include "DrawNode3D.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -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);
|
||||
|
|
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 23 KiB |