mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2026-01-10 20:26:52 +00:00
初始化
This commit is contained in:
179
cocos2d-x/cocos/renderer/scene/MemPool.cpp
Normal file
179
cocos2d-x/cocos/renderer/scene/MemPool.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MemPool.hpp"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
UnitBase::UnitBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnitBase::~UnitBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UnitBase::set(se::Object** dataObj, uint8_t** data, std::size_t* dataLen, se::Object* jsData)
|
||||
{
|
||||
if (*dataObj == jsData) return;
|
||||
|
||||
if (*dataObj)
|
||||
{
|
||||
(*dataObj)->unroot();
|
||||
(*dataObj)->decRef();
|
||||
*dataObj = nullptr;
|
||||
}
|
||||
|
||||
if (jsData == nullptr) return;
|
||||
|
||||
*dataObj = jsData;
|
||||
(*dataObj)->root();
|
||||
(*dataObj)->incRef();
|
||||
*data = nullptr;
|
||||
*dataLen = 0;
|
||||
(*dataObj)->getTypedArrayData(data, dataLen);
|
||||
}
|
||||
|
||||
void UnitBase::unset(se::Object** dataObj, uint8_t** data, std::size_t* dataLen)
|
||||
{
|
||||
if (*dataObj)
|
||||
{
|
||||
(*dataObj)->unroot();
|
||||
(*dataObj)->decRef();
|
||||
*dataObj = nullptr;
|
||||
}
|
||||
|
||||
*data = nullptr;
|
||||
*dataLen = 0;
|
||||
}
|
||||
|
||||
UnitCommon::UnitCommon()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnitCommon::~UnitCommon()
|
||||
{
|
||||
unset(&dataObj, (uint8_t**)&data, &dataLen);
|
||||
unset(&signDataObj, (uint8_t**)&signData, &signDataLen);
|
||||
}
|
||||
|
||||
void UnitCommon::setData(se::Object* jsData)
|
||||
{
|
||||
set(&dataObj, (uint8_t**)&data, &dataLen, jsData);
|
||||
}
|
||||
|
||||
void UnitCommon::setSignData(se::Object* jsSignData)
|
||||
{
|
||||
set(&signDataObj, (uint8_t**)&signData, &signDataLen, jsSignData);
|
||||
}
|
||||
|
||||
MemPool::MemPool()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MemPool::~MemPool()
|
||||
{
|
||||
for(auto it = _commonPool.begin(); it != _commonPool.end(); it++)
|
||||
{
|
||||
if (*it)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
_commonPool.clear();
|
||||
}
|
||||
|
||||
void MemPool::removeCommonData(std::size_t unitID)
|
||||
{
|
||||
CCASSERT(unitID < _commonPool.size(), "MemPool removeCommonData unitID can not be rather than pool size");
|
||||
auto unit = _commonPool[unitID];
|
||||
if (unit)
|
||||
{
|
||||
for (auto it = _commonList.begin(); it != _commonList.end(); it++)
|
||||
{
|
||||
if ((*it)->unitID == unitID)
|
||||
{
|
||||
_commonList.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete unit;
|
||||
_commonPool[unitID] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MemPool::updateCommonData(std::size_t unitID, se_object_ptr dataObj, se_object_ptr signDataObj)
|
||||
{
|
||||
CCASSERT(unitID <= _commonPool.size(), "MemPool updateData unitID can not be rather than pool size");
|
||||
|
||||
UnitCommon* unit = nullptr;
|
||||
if (unitID == _commonPool.size())
|
||||
{
|
||||
unit = new UnitCommon;
|
||||
_commonPool.push_back(unit);
|
||||
_commonList.push_back(unit);
|
||||
}
|
||||
else if (unitID < _commonPool.size())
|
||||
{
|
||||
unit = _commonPool[unitID];
|
||||
if (!unit)
|
||||
{
|
||||
unit = new UnitCommon;
|
||||
_commonPool[unitID] = unit;
|
||||
_commonList.push_back(unit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit->unitID = unitID;
|
||||
unit->setData(dataObj);
|
||||
unit->setSignData(signDataObj);
|
||||
}
|
||||
|
||||
const std::vector<UnitCommon*>& MemPool::getCommonPool() const
|
||||
{
|
||||
return _commonPool;
|
||||
}
|
||||
|
||||
const std::vector<UnitCommon*>& MemPool::getCommonList() const
|
||||
{
|
||||
return _commonList;
|
||||
}
|
||||
|
||||
UnitCommon* MemPool::getCommonUnit(std::size_t unitID)
|
||||
{
|
||||
CCASSERT(unitID < _commonPool.size(), "MemPool getCommonUnit unitID can not be rather than pool size");
|
||||
return _commonPool[unitID];
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
99
cocos2d-x/cocos/renderer/scene/MemPool.hpp
Normal file
99
cocos2d-x/cocos/renderer/scene/MemPool.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include <vector>
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class UnitBase
|
||||
{
|
||||
public:
|
||||
UnitBase();
|
||||
virtual ~UnitBase();
|
||||
|
||||
void set(se::Object** dataObj, uint8_t** data, std::size_t* dataLen, se::Object* jsData);
|
||||
void unset(se::Object** dataObj, uint8_t** data, std::size_t* dataLen);
|
||||
|
||||
std::size_t unitID = 0;
|
||||
};
|
||||
|
||||
struct Sign
|
||||
{
|
||||
uint16_t nextFreeIndex;
|
||||
uint16_t freeFlag;
|
||||
};
|
||||
|
||||
class UnitCommon: public UnitBase
|
||||
{
|
||||
public:
|
||||
UnitCommon();
|
||||
virtual ~UnitCommon();
|
||||
|
||||
void setData(se::Object* jsData);
|
||||
void setSignData(se::Object* jsSignData);
|
||||
|
||||
uint16_t getUsingNum()
|
||||
{
|
||||
return data[1];
|
||||
}
|
||||
|
||||
Sign* getSignData(std::size_t index)
|
||||
{
|
||||
return (Sign*)signData + index;
|
||||
}
|
||||
|
||||
std::size_t getContentNum()
|
||||
{
|
||||
return signDataLen / (sizeof(uint16_t) * 2);
|
||||
}
|
||||
protected:
|
||||
se::Object* dataObj = nullptr;
|
||||
uint16_t* data = nullptr;
|
||||
std::size_t dataLen = 0;
|
||||
|
||||
se::Object* signDataObj = nullptr;
|
||||
uint16_t* signData = nullptr;
|
||||
std::size_t signDataLen = 0;
|
||||
};
|
||||
|
||||
class MemPool {
|
||||
public:
|
||||
MemPool();
|
||||
virtual ~MemPool();
|
||||
|
||||
void removeCommonData(std::size_t unitID);
|
||||
void updateCommonData(std::size_t unitID, se_object_ptr dataObj, se_object_ptr signDataObj);
|
||||
UnitCommon* getCommonUnit(std::size_t unitID);
|
||||
const std::vector<UnitCommon*>& getCommonPool() const;
|
||||
const std::vector<UnitCommon*>& getCommonList() const;
|
||||
private:
|
||||
std::vector<UnitCommon*> _commonPool;
|
||||
std::vector<UnitCommon*> _commonList;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
227
cocos2d-x/cocos/renderer/scene/MeshBuffer.cpp
Normal file
227
cocos2d-x/cocos/renderer/scene/MeshBuffer.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MeshBuffer.hpp"
|
||||
#include "../Types.h"
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "RenderFlow.hpp"
|
||||
#include "../gfx/DeviceGraphics.h"
|
||||
|
||||
#define MAX_VERTEX_COUNT 65535
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
MeshBuffer::MeshBuffer(ModelBatcher* batcher, VertexFormat* fmt)
|
||||
: _vertexFmt(fmt)
|
||||
, _batcher(batcher)
|
||||
{
|
||||
_bytesPerVertex = _vertexFmt->getBytes();
|
||||
|
||||
DeviceGraphics* device = _batcher->getFlow()->getDevice();
|
||||
_vb = VertexBuffer::create(device, _vertexFmt, Usage::DYNAMIC, nullptr, 0, 0);
|
||||
_vbArr.pushBack(_vb);
|
||||
|
||||
_ib = IndexBuffer::create(device, IndexFormat::UINT16, Usage::STATIC, nullptr, 0, 0);
|
||||
_ibArr.pushBack(_ib);
|
||||
|
||||
_vDataCount = MeshBuffer::INIT_VERTEX_COUNT * 4 * _bytesPerVertex / sizeof(float);
|
||||
_iDataCount = MeshBuffer::INIT_VERTEX_COUNT * 6;
|
||||
|
||||
reallocVBuffer();
|
||||
reallocIBuffer();
|
||||
}
|
||||
|
||||
MeshBuffer::~MeshBuffer()
|
||||
{
|
||||
for (std::size_t i = 0, n = _vbArr.size(); i < n; i++)
|
||||
{
|
||||
_vbArr.at(i)->destroy();
|
||||
}
|
||||
_vbArr.clear();
|
||||
|
||||
for (std::size_t i = 0, n = _ibArr.size(); i < n; i++)
|
||||
{
|
||||
_ibArr.at(i)->destroy();
|
||||
}
|
||||
_ibArr.clear();
|
||||
|
||||
if (iData)
|
||||
{
|
||||
delete[] iData;
|
||||
iData = nullptr;
|
||||
}
|
||||
|
||||
if (vData)
|
||||
{
|
||||
delete[] vData;
|
||||
vData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MeshBuffer::reallocVBuffer()
|
||||
{
|
||||
auto oldVData = vData;
|
||||
vData = new float[_vDataCount];
|
||||
if (oldVData)
|
||||
{
|
||||
memcpy(vData, oldVData, sizeof(float) * _oldVDataCount);
|
||||
delete[] oldVData;
|
||||
oldVData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MeshBuffer::reallocIBuffer()
|
||||
{
|
||||
auto oldIData = iData;
|
||||
iData = new uint16_t[_iDataCount];
|
||||
if (oldIData)
|
||||
{
|
||||
memcpy(iData, oldIData, sizeof(uint16_t) * _oldIDataCount);
|
||||
delete[] oldIData;
|
||||
oldIData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const MeshBuffer::OffsetInfo& MeshBuffer::request(uint32_t vertexCount, uint32_t indexCount)
|
||||
{
|
||||
if (_batcher->getCurrentBuffer() != this)
|
||||
{
|
||||
_batcher->flush();
|
||||
_batcher->setCurrentBuffer(this);
|
||||
}
|
||||
_offsetInfo.vByte = _byteOffset;
|
||||
_offsetInfo.index = _indexOffset;
|
||||
_offsetInfo.vertex = _vertexOffset;
|
||||
return requestStatic(vertexCount, indexCount);
|
||||
}
|
||||
|
||||
const MeshBuffer::OffsetInfo& MeshBuffer::requestStatic(uint32_t vertexCount, uint32_t indexCount)
|
||||
{
|
||||
checkAndSwitchBuffer(vertexCount);
|
||||
|
||||
uint32_t byteOffset = _byteOffset + vertexCount * _bytesPerVertex;
|
||||
uint32_t indexOffset = _indexOffset + indexCount;
|
||||
uint32_t vBytes = _vDataCount * VDATA_BYTE;
|
||||
|
||||
if (byteOffset > vBytes)
|
||||
{
|
||||
_oldVDataCount = _vDataCount;
|
||||
|
||||
while (vBytes < byteOffset)
|
||||
{
|
||||
_vDataCount *= 2;
|
||||
vBytes = _vDataCount * VDATA_BYTE;
|
||||
}
|
||||
|
||||
reallocVBuffer();
|
||||
}
|
||||
|
||||
if (indexOffset > _iDataCount)
|
||||
{
|
||||
_oldIDataCount = _iDataCount;
|
||||
|
||||
while (_iDataCount < indexOffset)
|
||||
{
|
||||
_iDataCount *= 2;
|
||||
}
|
||||
|
||||
reallocIBuffer();
|
||||
}
|
||||
|
||||
updateOffset(vertexCount, indexCount, byteOffset);
|
||||
|
||||
return _offsetInfo;
|
||||
}
|
||||
|
||||
void MeshBuffer::uploadData()
|
||||
{
|
||||
_vb->update(0, vData, _byteOffset);
|
||||
_ib->update(0, iData, _indexOffset * IDATA_BYTE);
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
void MeshBuffer::switchBuffer(uint32_t vertexCount)
|
||||
{
|
||||
std::size_t offset = ++_vbPos;
|
||||
|
||||
_byteOffset = 0;
|
||||
_vertexOffset = 0;
|
||||
_indexOffset = 0;
|
||||
_indexStart = 0;
|
||||
|
||||
if (offset < _vbArr.size())
|
||||
{
|
||||
_vb = _vbArr.at(offset);
|
||||
_ib = _ibArr.at(offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceGraphics* device = _batcher->getFlow()->getDevice();
|
||||
_vb = VertexBuffer::create(device, _vertexFmt, Usage::DYNAMIC, nullptr, 0, 0);
|
||||
_vbArr.pushBack(_vb);
|
||||
|
||||
_ib = IndexBuffer::create(device, IndexFormat::UINT16, Usage::STATIC, nullptr, 0, 0);
|
||||
_ibArr.pushBack(_ib);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshBuffer::checkAndSwitchBuffer(uint32_t vertexCount)
|
||||
{
|
||||
if (_vertexOffset + vertexCount > MAX_VERTEX_COUNT)
|
||||
{
|
||||
uploadData();
|
||||
_batcher->flush();
|
||||
switchBuffer(vertexCount);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshBuffer::updateOffset (uint32_t vertexCount, uint32_t indiceCount, uint32_t byteOffset)
|
||||
{
|
||||
_offsetInfo.vertex = _vertexOffset;
|
||||
_vertexOffset += vertexCount;
|
||||
|
||||
_offsetInfo.index = _indexOffset;
|
||||
_indexOffset += indiceCount;
|
||||
|
||||
_offsetInfo.vByte = _byteOffset;
|
||||
_byteOffset = byteOffset;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void MeshBuffer::reset()
|
||||
{
|
||||
_vbPos = 0;
|
||||
_vb = _vbArr.at(0);
|
||||
_ib = _ibArr.at(0);
|
||||
_byteStart = 0;
|
||||
_byteOffset = 0;
|
||||
_vertexStart = 0;
|
||||
_vertexOffset = 0;
|
||||
_indexStart = 0;
|
||||
_indexOffset = 0;
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
189
cocos2d-x/cocos/renderer/scene/MeshBuffer.hpp
Normal file
189
cocos2d-x/cocos/renderer/scene/MeshBuffer.hpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "../gfx/VertexFormat.h"
|
||||
#include "../gfx/VertexBuffer.h"
|
||||
#include "../gfx/IndexBuffer.h"
|
||||
#include "base/CCVector.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class ModelBatcher;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief The buffer which stores mesh render datas, including the vertices data and the indices data.
|
||||
* It can be used as a global buffer shared by multiple render handles and eventually shared by Models
|
||||
*/
|
||||
class MeshBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief It describes a range of buffer in the global buffer, it contains result when you request the buffer.
|
||||
*/
|
||||
struct OffsetInfo
|
||||
{
|
||||
/** bytes count of the requested buffer */
|
||||
uint32_t vByte = 0;
|
||||
/** offset in index buffer */
|
||||
uint32_t index = 0;
|
||||
/** offset in vertex buffer */
|
||||
uint32_t vertex = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] batcher The ModelBatcher which creates the current buffer
|
||||
* @param[in] fmt The vertex format of vertex data
|
||||
*/
|
||||
MeshBuffer(ModelBatcher* batcher, VertexFormat* fmt);
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~MeshBuffer();
|
||||
|
||||
/**
|
||||
* @brief Requests a range of buffer for the given count of vertices and indices
|
||||
* @param[in] vertexCount Requested count of vertices
|
||||
* @param[in] indexCount Requested count of indices
|
||||
* @param[out] offset The result indicates the allocated buffer range
|
||||
*/
|
||||
const OffsetInfo& request(uint32_t vertexCount, uint32_t indexCount);
|
||||
const OffsetInfo& requestStatic(uint32_t vertexCount, uint32_t indexCount);
|
||||
|
||||
/**
|
||||
* @brief Upload data to GPU memory
|
||||
*/
|
||||
void uploadData();
|
||||
/**
|
||||
* @brief Reset all states.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @brief Gets the current byte offset which indicates the start of empty range
|
||||
* @return Byte offset.
|
||||
*/
|
||||
uint32_t getByteOffset() const { return _byteOffset; };
|
||||
/**
|
||||
* @brief Gets the current vertex start offset since last time updateOffset is invoked
|
||||
* @return Vertex start.
|
||||
*/
|
||||
uint32_t getVertexStart() const { return _vertexStart; };
|
||||
/**
|
||||
* @brief Gets the current vertex offset, which should equals to total allocated vertex count.
|
||||
* @return Vertex offset.
|
||||
*/
|
||||
uint32_t getVertexOffset() const { return _vertexOffset; };
|
||||
/**
|
||||
* @brief Gets the current index start offset since last time updateOffset is invoked
|
||||
* @return Index start.
|
||||
*/
|
||||
uint32_t getIndexStart() const { return _indexStart; };
|
||||
/**
|
||||
* @brief Gets the current index offset, which should equals to total allocated index count.
|
||||
* @return Index offset.
|
||||
*/
|
||||
uint32_t getIndexOffset() const { return _indexOffset; };
|
||||
|
||||
/**
|
||||
* @brief Update the current allocated offsets to the start offsets.
|
||||
*/
|
||||
void updateOffset()
|
||||
{
|
||||
_byteStart = _byteOffset;
|
||||
_vertexStart = _vertexOffset;
|
||||
_indexStart = _indexOffset;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Gets the vertex buffer.
|
||||
*/
|
||||
VertexBuffer* getVertexBuffer() const { return _vb; };
|
||||
/**
|
||||
* @brief Gets the index buffer.
|
||||
*/
|
||||
IndexBuffer* getIndexBuffer() const { return _ib; };
|
||||
|
||||
/**
|
||||
* @brief The vertex data storage in memory
|
||||
*/
|
||||
float* vData = nullptr;
|
||||
/**
|
||||
* @brief The index data storage in memory
|
||||
*/
|
||||
uint16_t* iData = nullptr;
|
||||
/**
|
||||
* @brief Vertex format of the vertex data.
|
||||
*/
|
||||
VertexFormat* _vertexFmt;
|
||||
|
||||
static const int INIT_VERTEX_COUNT = 4096;
|
||||
static const uint8_t VDATA_BYTE = sizeof(float);
|
||||
static const uint8_t IDATA_BYTE = sizeof(uint16_t);
|
||||
protected:
|
||||
void reallocVBuffer();
|
||||
void reallocIBuffer();
|
||||
void checkAndSwitchBuffer(uint32_t vertexCount);
|
||||
void switchBuffer(uint32_t vertexCount);
|
||||
void updateOffset(uint32_t vertexCount, uint32_t indiceCount, uint32_t byteOffset);
|
||||
private:
|
||||
uint32_t _byteStart = 0;
|
||||
uint32_t _byteOffset = 0;
|
||||
uint32_t _indexStart = 0;
|
||||
uint32_t _indexOffset = 0;
|
||||
uint32_t _vertexStart = 0;
|
||||
uint32_t _vertexOffset = 0;
|
||||
uint32_t _bytesPerVertex = 0;
|
||||
|
||||
uint32_t _vDataCount = 0;
|
||||
uint32_t _iDataCount = 0;
|
||||
|
||||
uint32_t _oldVDataCount = 0;
|
||||
uint32_t _oldIDataCount = 0;
|
||||
|
||||
bool _dirty = false;
|
||||
|
||||
ModelBatcher* _batcher = nullptr;
|
||||
std::size_t _vbPos = 0;
|
||||
cocos2d::Vector<VertexBuffer*> _vbArr;
|
||||
cocos2d::Vector<IndexBuffer*> _ibArr;
|
||||
VertexBuffer* _vb = nullptr;
|
||||
IndexBuffer* _ib = nullptr;
|
||||
OffsetInfo _offsetInfo;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
380
cocos2d-x/cocos/renderer/scene/ModelBatcher.cpp
Normal file
380
cocos2d-x/cocos/renderer/scene/ModelBatcher.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "RenderFlow.hpp"
|
||||
#include "StencilManager.hpp"
|
||||
#include "assembler/RenderDataList.hpp"
|
||||
#include "NodeProxy.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
#define INIT_MODEL_LENGTH 16
|
||||
|
||||
ModelBatcher::ModelBatcher(RenderFlow* flow)
|
||||
: _flow(flow)
|
||||
, _modelOffset(0)
|
||||
, _cullingMask(0)
|
||||
, _walking(false)
|
||||
, _currEffect(nullptr)
|
||||
, _buffer(nullptr)
|
||||
, _useModel(false)
|
||||
, _node(nullptr)
|
||||
{
|
||||
for (int i = 0; i < INIT_MODEL_LENGTH; i++)
|
||||
{
|
||||
_modelPool.push_back(new Model());
|
||||
}
|
||||
|
||||
_stencilMgr = StencilManager::getInstance();
|
||||
}
|
||||
|
||||
ModelBatcher::~ModelBatcher()
|
||||
{
|
||||
setCurrentEffect(nullptr);
|
||||
setNode(nullptr);
|
||||
|
||||
for (int i = 0; i < _modelPool.size(); i++)
|
||||
{
|
||||
auto model = _modelPool[i];
|
||||
delete model;
|
||||
}
|
||||
_modelPool.clear();
|
||||
|
||||
for (auto iter = _buffers.begin(); iter != _buffers.end(); ++iter)
|
||||
{
|
||||
MeshBuffer *buffer = iter->second;
|
||||
delete buffer;
|
||||
}
|
||||
_buffers.clear();
|
||||
}
|
||||
|
||||
void ModelBatcher::reset()
|
||||
{
|
||||
for (int i = 0; i < _modelOffset; ++i)
|
||||
{
|
||||
Model* model = _modelPool[i];
|
||||
model->reset();
|
||||
}
|
||||
_flow->getRenderScene()->removeModels();
|
||||
_modelOffset = 0;
|
||||
|
||||
for (auto iter : _buffers)
|
||||
{
|
||||
iter.second->reset();
|
||||
}
|
||||
_buffer = nullptr;
|
||||
|
||||
_commitState = CommitState::None;
|
||||
setCurrentEffect(nullptr);
|
||||
setNode(nullptr);
|
||||
_ia.clear();
|
||||
_cullingMask = 0;
|
||||
_walking = false;
|
||||
_useModel = false;
|
||||
|
||||
_modelMat.set(Mat4::IDENTITY);
|
||||
_stencilMgr->reset();
|
||||
}
|
||||
|
||||
void ModelBatcher::changeCommitState(CommitState state)
|
||||
{
|
||||
if (_commitState == state) return;
|
||||
switch(_commitState)
|
||||
{
|
||||
case CommitState::Custom:
|
||||
flushIA();
|
||||
break;
|
||||
case CommitState::Common:
|
||||
flush();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
setCurrentEffect(nullptr);
|
||||
_commitState = state;
|
||||
}
|
||||
|
||||
void ModelBatcher::commit(NodeProxy* node, Assembler* assembler, int cullingMask)
|
||||
{
|
||||
changeCommitState(CommitState::Common);
|
||||
|
||||
bool useModel = assembler->getUseModel();
|
||||
bool ignoreWorldMatrix = assembler->isIgnoreWorldMatrix();
|
||||
|
||||
auto customWorldMat = assembler->getCustomWorldMatrix();
|
||||
customWorldMat = customWorldMat ? customWorldMat : &node->getWorldMatrix();
|
||||
const Mat4& worldMat = useModel && !ignoreWorldMatrix ? *customWorldMat : Mat4::IDENTITY;
|
||||
|
||||
auto asmDirty = assembler->isDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
auto nodeDirty = node->isDirty(RenderFlow::NODE_OPACITY_CHANGED);
|
||||
auto needUpdateOpacity = (asmDirty || nodeDirty) && !assembler->isIgnoreOpacityFlag();
|
||||
|
||||
for (std::size_t i = 0, l = assembler->getIACount(); i < l; ++i)
|
||||
{
|
||||
assembler->beforeFillBuffers(i);
|
||||
|
||||
EffectVariant* effect = assembler->getEffect(i);
|
||||
if (!effect) continue;
|
||||
|
||||
if (_currEffect == nullptr ||
|
||||
_currEffect->getHash() != effect->getHash() ||
|
||||
_cullingMask != cullingMask || useModel)
|
||||
{
|
||||
// Break auto batch
|
||||
flush();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
}
|
||||
|
||||
if (needUpdateOpacity)
|
||||
{
|
||||
assembler->updateOpacity(i, node->getRealOpacity());
|
||||
}
|
||||
|
||||
assembler->fillBuffers(node, this, i);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelBatcher::commitIA(NodeProxy* node, CustomAssembler* assembler, int cullingMask)
|
||||
{
|
||||
changeCommitState(CommitState::Custom);
|
||||
|
||||
EffectVariant* effect = assembler->getEffect(0);
|
||||
if (!effect) return;
|
||||
|
||||
auto customIA = assembler->getIA(0);
|
||||
if (!customIA) return;
|
||||
|
||||
std::size_t iaCount = assembler->getIACount();
|
||||
bool useModel = assembler->getUseModel();
|
||||
auto customWorldMat = assembler->getCustomWorldMatrix();
|
||||
customWorldMat = customWorldMat ? customWorldMat : &node->getWorldMatrix();
|
||||
const Mat4& worldMat = useModel ? *customWorldMat : Mat4::IDENTITY;
|
||||
|
||||
if (_currEffect == nullptr ||
|
||||
_currEffect->getHash() != effect->getHash() ||
|
||||
_cullingMask != cullingMask || useModel ||
|
||||
!_ia.isMergeable(*customIA))
|
||||
{
|
||||
flushIA();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
|
||||
_ia.setVertexBuffer(customIA->getVertexBuffer());
|
||||
_ia.setIndexBuffer(customIA->getIndexBuffer());
|
||||
_ia.setStart(customIA->getStart());
|
||||
_ia.setCount(0);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < iaCount; i++ )
|
||||
{
|
||||
customIA = assembler->getIA(i);
|
||||
effect = assembler->getEffect(i);
|
||||
if (!effect) continue;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
flushIA();
|
||||
|
||||
setNode(_useModel ? node : nullptr);
|
||||
setCurrentEffect(effect);
|
||||
_modelMat.set(worldMat);
|
||||
_useModel = useModel;
|
||||
_cullingMask = cullingMask;
|
||||
|
||||
_ia.setVertexBuffer(customIA->getVertexBuffer());
|
||||
_ia.setIndexBuffer(customIA->getIndexBuffer());
|
||||
_ia.setStart(customIA->getStart());
|
||||
_ia.setCount(0);
|
||||
}
|
||||
|
||||
_ia.setCount(_ia.getCount() + customIA->getCount());
|
||||
}
|
||||
}
|
||||
|
||||
void ModelBatcher::flushIA()
|
||||
{
|
||||
if (_commitState != CommitState::Custom)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_walking || !_currEffect || _ia.getCount() <= 0)
|
||||
{
|
||||
_ia.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Stencil manager process
|
||||
_stencilMgr->handleEffect(_currEffect);
|
||||
|
||||
// Generate model
|
||||
Model* model = nullptr;
|
||||
if (_modelOffset >= _modelPool.size())
|
||||
{
|
||||
model = new Model();
|
||||
_modelPool.push_back(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
model = _modelPool[_modelOffset];
|
||||
}
|
||||
_modelOffset++;
|
||||
model->setWorldMatix(_modelMat);
|
||||
model->setCullingMask(_cullingMask);
|
||||
model->setEffect(_currEffect);
|
||||
model->setNode(_node);
|
||||
model->setInputAssembler(_ia);
|
||||
|
||||
_ia.clear();
|
||||
|
||||
_flow->getRenderScene()->addModel(model);
|
||||
}
|
||||
|
||||
void ModelBatcher::flush()
|
||||
{
|
||||
if (_commitState != CommitState::Common)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_walking || !_currEffect || !_buffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int indexStart = _buffer->getIndexStart();
|
||||
int indexOffset = _buffer->getIndexOffset();
|
||||
int indexCount = indexOffset - indexStart;
|
||||
if (indexCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ia.setVertexBuffer(_buffer->getVertexBuffer());
|
||||
_ia.setIndexBuffer(_buffer->getIndexBuffer());
|
||||
_ia.setStart(indexStart);
|
||||
_ia.setCount(indexCount);
|
||||
|
||||
// Stencil manager process
|
||||
_stencilMgr->handleEffect(_currEffect);
|
||||
|
||||
// Generate model
|
||||
Model* model = nullptr;
|
||||
if (_modelOffset >= _modelPool.size())
|
||||
{
|
||||
model = new Model();
|
||||
_modelPool.push_back(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
model = _modelPool[_modelOffset];
|
||||
}
|
||||
_modelOffset++;
|
||||
model->setWorldMatix(_modelMat);
|
||||
model->setCullingMask(_cullingMask);
|
||||
model->setEffect(_currEffect);
|
||||
model->setNode(_node);
|
||||
model->setInputAssembler(_ia);
|
||||
|
||||
_ia.clear();
|
||||
|
||||
_flow->getRenderScene()->addModel(model);
|
||||
|
||||
_buffer->updateOffset();
|
||||
}
|
||||
|
||||
void ModelBatcher::startBatch()
|
||||
{
|
||||
reset();
|
||||
_walking = true;
|
||||
}
|
||||
|
||||
void ModelBatcher::terminateBatch()
|
||||
{
|
||||
flush();
|
||||
flushIA();
|
||||
|
||||
for (auto iter : _buffers)
|
||||
{
|
||||
iter.second->uploadData();
|
||||
}
|
||||
|
||||
_walking = false;
|
||||
}
|
||||
|
||||
void ModelBatcher::setNode(NodeProxy* node)
|
||||
{
|
||||
if (_node == node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CC_SAFE_RELEASE(_node);
|
||||
_node = node;
|
||||
CC_SAFE_RETAIN(_node);
|
||||
}
|
||||
|
||||
void ModelBatcher::setCurrentEffect(EffectVariant* effect)
|
||||
{
|
||||
if (_currEffect == effect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CC_SAFE_RELEASE(_currEffect);
|
||||
_currEffect = effect;
|
||||
CC_SAFE_RETAIN(_currEffect);
|
||||
};
|
||||
|
||||
MeshBuffer* ModelBatcher::getBuffer(VertexFormat* fmt)
|
||||
{
|
||||
if (_buffer != nullptr && fmt == _buffer->_vertexFmt)
|
||||
{
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = nullptr;
|
||||
auto iter = _buffers.find(fmt);
|
||||
if (iter == _buffers.end())
|
||||
{
|
||||
buffer = new MeshBuffer(this, fmt);
|
||||
_buffers.emplace(fmt, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = iter->second;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
157
cocos2d-x/cocos/renderer/scene/ModelBatcher.hpp
Normal file
157
cocos2d-x/cocos/renderer/scene/ModelBatcher.hpp
Normal file
@@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "assembler/Assembler.hpp"
|
||||
#include "assembler/CustomAssembler.hpp"
|
||||
#include "MeshBuffer.hpp"
|
||||
#include "../renderer/Renderer.h"
|
||||
#include "math/CCMath.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class RenderFlow;
|
||||
class StencilManager;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ModelBatcher is responsible for transforming node's render handles into final render datas.
|
||||
* It collects render data, batches different render handle together into Models and submits to render Scene.
|
||||
*/
|
||||
class ModelBatcher
|
||||
{
|
||||
public:
|
||||
|
||||
enum CommitState {
|
||||
None,
|
||||
Common,
|
||||
Custom,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The constructor.
|
||||
*/
|
||||
ModelBatcher(RenderFlow* flow);
|
||||
/**
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~ModelBatcher();
|
||||
/**
|
||||
* @brief Reset all render buffer.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* @brief Commit a render handle to the model batcher
|
||||
* @param[in] node The node which owns the render handle
|
||||
* @param[in] handle The render handle contains render datas
|
||||
*/
|
||||
void commit(NodeProxy* node, Assembler* handle, int cullingMask);
|
||||
/**
|
||||
* @brief Commit a custom render handle to the model batcher
|
||||
* @param[in] node The node which owns the render handle
|
||||
* @param[in] handle The custom render handle contains render datas
|
||||
*/
|
||||
void commitIA(NodeProxy* node, CustomAssembler* handle, int cullingMask);
|
||||
|
||||
/**
|
||||
* @brief This method should be invoked before commit any render handles each frame.
|
||||
* It notifies the model batcher to get ready for constructing Models
|
||||
*/
|
||||
void startBatch();
|
||||
/**
|
||||
* @brief Flush all cached render data into a new Model and add the Model to render Scene.
|
||||
*/
|
||||
void flush();
|
||||
/**
|
||||
* @brief Finished Custom input assmebler batch and add the Model to render Scene.
|
||||
*/
|
||||
void flushIA();
|
||||
/**
|
||||
* @brief Add new input assembler into current input assembler.
|
||||
*/
|
||||
void flushIA(InputAssembler* customIA);
|
||||
/**
|
||||
* @brief This method should be invoked after committed all render handles each frame.
|
||||
*/
|
||||
void terminateBatch();
|
||||
|
||||
/**
|
||||
* @brief Gets a suitable MeshBuffer for the given VertexFormat.
|
||||
* Render datas arranged in different VertexFormat can't share the same buffer.
|
||||
* @param[in] fmt The VertexFormat
|
||||
*/
|
||||
MeshBuffer* getBuffer(VertexFormat* fmt);
|
||||
/**
|
||||
* @brief Gets the current MeshBuffer.
|
||||
*/
|
||||
const MeshBuffer* getCurrentBuffer() const { return _buffer; };
|
||||
/**
|
||||
* @brief Sets the current MeshBuffer.
|
||||
* @param[in] buffer
|
||||
*/
|
||||
void setCurrentBuffer(MeshBuffer* buffer) { _buffer = buffer; };
|
||||
/**
|
||||
* @brief Gets the global RenderFlow pointer.
|
||||
*/
|
||||
RenderFlow* getFlow() const { return _flow; };
|
||||
|
||||
void setNode(NodeProxy* node);
|
||||
void setCullingMask(int cullingMask) { _cullingMask = cullingMask; }
|
||||
void setCurrentEffect(EffectVariant* effect);
|
||||
void setUseModel(bool useModel) { _useModel = useModel; }
|
||||
void changeCommitState(CommitState state);
|
||||
private:
|
||||
int _modelOffset = 0;
|
||||
int _cullingMask = 0;
|
||||
bool _useModel = false;
|
||||
bool _walking = false;
|
||||
cocos2d::Mat4 _modelMat;
|
||||
CommitState _commitState = CommitState::None;
|
||||
|
||||
NodeProxy* _node = nullptr;
|
||||
|
||||
MeshBuffer* _buffer = nullptr;
|
||||
EffectVariant* _currEffect = nullptr;
|
||||
RenderFlow* _flow = nullptr;
|
||||
|
||||
StencilManager* _stencilMgr = nullptr;
|
||||
|
||||
InputAssembler _ia;
|
||||
std::vector<Model*> _modelPool;
|
||||
std::unordered_map<VertexFormat*, MeshBuffer*> _buffers;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
186
cocos2d-x/cocos/renderer/scene/NodeMemPool.cpp
Normal file
186
cocos2d-x/cocos/renderer/scene/NodeMemPool.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "NodeMemPool.hpp"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
UnitNode::UnitNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UnitNode::~UnitNode()
|
||||
{
|
||||
unset(&dirty, (uint8_t**)&dirtyData, &dirtyLen);
|
||||
unset(&trs, (uint8_t**)&trsData, &trsLen);
|
||||
unset(&localMat, (uint8_t**)&localMatData, &localMatLen);
|
||||
unset(&worldMat, (uint8_t**)&worldMatData, &worldMatLen);
|
||||
unset(&parent, (uint8_t**)&parentData, &parentLen);
|
||||
unset(&zOrder, (uint8_t**)&zOrderData, &zOrderLen);
|
||||
unset(&cullingMask, (uint8_t**)&cullingMaskData, &cullingMaskLen);
|
||||
unset(&opacity, (uint8_t**)&opacityData, &opacityLen);
|
||||
unset(&is3D, (uint8_t**)&is3DData, &is3DLen);
|
||||
unset(&node, (uint8_t**)&nodeData, &nodeLen);
|
||||
unset(&skew, (uint8_t**)&skewData, &skewLen);
|
||||
}
|
||||
|
||||
void UnitNode::setDirty(se::Object* jsData)
|
||||
{
|
||||
set(&dirty, (uint8_t**)&dirtyData, &dirtyLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setTRS(se::Object* jsData)
|
||||
{
|
||||
set(&trs, (uint8_t**)&trsData, &trsLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setLocalMat(se::Object* jsData)
|
||||
{
|
||||
set(&localMat, (uint8_t**)&localMatData, &localMatLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setWorldMat(se::Object* jsData)
|
||||
{
|
||||
set(&worldMat, (uint8_t**)&worldMatData, &worldMatLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setParent(se::Object* jsData)
|
||||
{
|
||||
set(&parent, (uint8_t**)&parentData, &parentLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setZOrder(se::Object* jsData)
|
||||
{
|
||||
set(&zOrder, (uint8_t**)&zOrderData, &zOrderLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setCullingMask(se::Object* jsData)
|
||||
{
|
||||
set(&cullingMask, (uint8_t**)&cullingMaskData, &cullingMaskLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setOpacity(se::Object* jsData)
|
||||
{
|
||||
set(&opacity, (uint8_t**)&opacityData, &opacityLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setIs3D(se::Object* jsData)
|
||||
{
|
||||
set(&is3D, (uint8_t**)&is3DData, &is3DLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setNode(se::Object *jsData)
|
||||
{
|
||||
set(&node, (uint8_t**)&nodeData, &nodeLen, jsData);
|
||||
}
|
||||
|
||||
void UnitNode::setSkew(se::Object* jsData)
|
||||
{
|
||||
set(&skew, (uint8_t**)&skewData, &skewLen, jsData);
|
||||
}
|
||||
|
||||
NodeMemPool* NodeMemPool::_instance = nullptr;
|
||||
|
||||
NodeMemPool::NodeMemPool()
|
||||
{
|
||||
_instance = this;
|
||||
}
|
||||
|
||||
NodeMemPool::~NodeMemPool()
|
||||
{
|
||||
for(auto it = _nodePool.begin(); it != _nodePool.end(); it++)
|
||||
{
|
||||
if (*it)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
_nodePool.clear();
|
||||
_instance = nullptr;
|
||||
}
|
||||
|
||||
const std::vector<UnitNode*>& NodeMemPool::getNodePool() const
|
||||
{
|
||||
return _nodePool;
|
||||
}
|
||||
|
||||
void NodeMemPool::removeNodeData(std::size_t unitID)
|
||||
{
|
||||
CCASSERT(unitID < _nodePool.size(), "NodeMemPool removeNodeData unitID can not be rather than pool size");
|
||||
auto unit = _nodePool[unitID];
|
||||
if (unit)
|
||||
{
|
||||
delete unit;
|
||||
_nodePool[unitID] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
UnitNode* NodeMemPool::getUnit(std::size_t unitID) const
|
||||
{
|
||||
CCASSERT(unitID < _nodePool.size(), "NodeMemPool getUnit unitID can not be rather than pool size");
|
||||
return _nodePool[unitID];
|
||||
}
|
||||
|
||||
void NodeMemPool::updateNodeData(std::size_t unitID, se_object_ptr dirty, se_object_ptr trs, se_object_ptr localMat, se_object_ptr worldMat, se_object_ptr parent, se_object_ptr zOrder, se_object_ptr cullingMask, se_object_ptr opacity, se_object_ptr is3D, se_object_ptr node, se_object_ptr skew)
|
||||
{
|
||||
// UnitID may equal to node pool size, then node pool must increase size.
|
||||
CCASSERT(unitID <= _nodePool.size(), "NodeMemPool updateNodeData unitID can not be rather than pool size");
|
||||
|
||||
UnitNode* unit = nullptr;
|
||||
if (unitID == _nodePool.size())
|
||||
{
|
||||
unit = new UnitNode;
|
||||
_nodePool.push_back(unit);
|
||||
}
|
||||
else if (unitID < _nodePool.size())
|
||||
{
|
||||
unit = _nodePool[unitID];
|
||||
if(!unit)
|
||||
{
|
||||
unit = new UnitNode;
|
||||
_nodePool[unitID] = unit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit->unitID = unitID;
|
||||
unit->setDirty(dirty);
|
||||
unit->setTRS(trs);
|
||||
unit->setLocalMat(localMat);
|
||||
unit->setWorldMat(worldMat);
|
||||
unit->setParent(parent);
|
||||
unit->setZOrder(zOrder);
|
||||
unit->setCullingMask(cullingMask);
|
||||
unit->setOpacity(opacity);
|
||||
unit->setIs3D(is3D);
|
||||
unit->setNode(node);
|
||||
unit->setSkew(skew);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
196
cocos2d-x/cocos/renderer/scene/NodeMemPool.hpp
Normal file
196
cocos2d-x/cocos/renderer/scene/NodeMemPool.hpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MemPool.hpp"
|
||||
#include "math/Mat4.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
|
||||
struct TRS {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float qx = 0.0f;
|
||||
float qy = 0.0f;
|
||||
float qz = 0.0f;
|
||||
float qw = 0.0f;
|
||||
float sx = 0.0f;
|
||||
float sy = 0.0f;
|
||||
float sz = 0.0f;
|
||||
};
|
||||
|
||||
#define PARENT_INVALID 0xffffffff
|
||||
struct ParentInfo {
|
||||
uint32_t unitID = 0;
|
||||
uint32_t index = 0;
|
||||
};
|
||||
|
||||
struct Skew {
|
||||
float_t x = 0.0f;
|
||||
float_t y = 0.0f;
|
||||
};
|
||||
|
||||
class UnitNode: public UnitBase {
|
||||
public:
|
||||
UnitNode();
|
||||
virtual ~UnitNode();
|
||||
void setDirty(se::Object* jsData);
|
||||
void setTRS(se::Object* jsData);
|
||||
void setLocalMat(se::Object* jsData);
|
||||
void setWorldMat(se::Object* jsData);
|
||||
void setParent(se::Object* jsData);
|
||||
void setZOrder(se::Object* jsData);
|
||||
void setCullingMask(se::Object* jsData);
|
||||
void setOpacity(se::Object* jsData);
|
||||
void setIs3D(se::Object* jsData);
|
||||
void setNode(se::Object* jsData);
|
||||
void setLevel(se::Object* jsData);
|
||||
void setSkew(se::Object* jsData);
|
||||
|
||||
uint32_t* getDirty(std::size_t index) const
|
||||
{
|
||||
return dirtyData + index;
|
||||
}
|
||||
|
||||
TRS* getTRS(std::size_t index) const
|
||||
{
|
||||
return (TRS*)trsData + index;
|
||||
}
|
||||
|
||||
cocos2d::Mat4* getLocalMat(std::size_t index) const
|
||||
{
|
||||
return (cocos2d::Mat4*)localMatData + index;
|
||||
}
|
||||
|
||||
cocos2d::Mat4* getWorldMat(std::size_t index) const
|
||||
{
|
||||
return (cocos2d::Mat4*)worldMatData + index;
|
||||
}
|
||||
|
||||
ParentInfo* getParent(std::size_t index) const
|
||||
{
|
||||
return (ParentInfo*)parentData + index;
|
||||
}
|
||||
|
||||
int32_t* getZOrder(std::size_t index) const
|
||||
{
|
||||
return zOrderData + index;
|
||||
}
|
||||
|
||||
int32_t* getCullingMask(std::size_t index) const
|
||||
{
|
||||
return cullingMaskData + index;
|
||||
}
|
||||
|
||||
uint8_t* getOpacity(std::size_t index) const
|
||||
{
|
||||
return opacityData + index;
|
||||
}
|
||||
|
||||
uint8_t* getIs3D(std::size_t index) const
|
||||
{
|
||||
return is3DData + index;
|
||||
}
|
||||
|
||||
uint64_t* getNode(std::size_t index) const
|
||||
{
|
||||
return nodeData + index;
|
||||
}
|
||||
|
||||
Skew* getSkew(std::size_t index) const
|
||||
{
|
||||
return (Skew*)skewData + index;
|
||||
}
|
||||
protected:
|
||||
se::Object* dirty = nullptr;
|
||||
uint32_t* dirtyData = nullptr;
|
||||
std::size_t dirtyLen = 0;
|
||||
|
||||
se::Object* trs = nullptr;
|
||||
float_t* trsData = nullptr;
|
||||
std::size_t trsLen = 0;
|
||||
|
||||
se::Object* localMat = nullptr;
|
||||
float_t* localMatData = nullptr;
|
||||
std::size_t localMatLen = 0;
|
||||
|
||||
se::Object* worldMat = nullptr;
|
||||
float_t* worldMatData = nullptr;
|
||||
std::size_t worldMatLen = 0;
|
||||
|
||||
se::Object* parent = nullptr;
|
||||
uint32_t* parentData = nullptr;
|
||||
std::size_t parentLen = 0;
|
||||
|
||||
se::Object* zOrder = nullptr;
|
||||
int32_t* zOrderData = nullptr;
|
||||
std::size_t zOrderLen = 0;
|
||||
|
||||
se::Object* cullingMask = nullptr;
|
||||
int32_t* cullingMaskData = nullptr;
|
||||
std::size_t cullingMaskLen = 0;
|
||||
|
||||
se::Object* opacity = nullptr;
|
||||
uint8_t* opacityData = nullptr;
|
||||
std::size_t opacityLen = 0;
|
||||
|
||||
se::Object* is3D = nullptr;
|
||||
uint8_t* is3DData = nullptr;
|
||||
std::size_t is3DLen = 0;
|
||||
|
||||
se::Object* node = nullptr;
|
||||
uint64_t* nodeData = nullptr;
|
||||
std::size_t nodeLen = 0;
|
||||
|
||||
se::Object* skew = nullptr;
|
||||
float_t* skewData = nullptr;
|
||||
std::size_t skewLen = 0;
|
||||
};
|
||||
|
||||
class NodeMemPool: public MemPool {
|
||||
public:
|
||||
NodeMemPool();
|
||||
virtual ~NodeMemPool();
|
||||
|
||||
static NodeMemPool* getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void removeNodeData(std::size_t unitID);
|
||||
|
||||
void updateNodeData(std::size_t unitID, se_object_ptr dirty, se_object_ptr trs, se_object_ptr localMat, se_object_ptr worldMat, se_object_ptr parent, se_object_ptr zOrder, se_object_ptr cullingMask, se_object_ptr opacity, se_object_ptr is3D, se_object_ptr node, se_object_ptr skew);
|
||||
|
||||
UnitNode* getUnit(std::size_t unitID) const;
|
||||
const std::vector<UnitNode*>& getNodePool() const;
|
||||
private:
|
||||
static NodeMemPool* _instance;
|
||||
std::vector<UnitNode*> _nodePool;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
587
cocos2d-x/cocos/renderer/scene/NodeProxy.cpp
Normal file
587
cocos2d-x/cocos/renderer/scene/NodeProxy.cpp
Normal file
@@ -0,0 +1,587 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "NodeProxy.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "../renderer/Scene.h"
|
||||
#include "base/ccMacros.h"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
|
||||
#include "cocos/scripting/js-bindings/auto/jsb_renderer_auto.hpp"
|
||||
#include "NodeMemPool.hpp"
|
||||
#include <math.h>
|
||||
#include "RenderFlow.hpp"
|
||||
#include "assembler/AssemblerSprite.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
uint32_t NodeProxy::_globalRenderOrder = 0;
|
||||
|
||||
NodeProxy::NodeProxy(std::size_t unitID, std::size_t index, const std::string& id, const std::string& name)
|
||||
{
|
||||
traverseHandle = render;
|
||||
|
||||
_id = id;
|
||||
_unitID = unitID;
|
||||
_index = index;
|
||||
_name = name;
|
||||
|
||||
NodeMemPool* pool = NodeMemPool::getInstance();
|
||||
CCASSERT(pool, "NodeProxy constructor NodeMemPool is null");
|
||||
UnitNode* unit = pool->getUnit(unitID);
|
||||
CCASSERT(unit, "NodeProxy constructor unit is null");
|
||||
|
||||
UnitCommon* common = pool->getCommonUnit(unitID);
|
||||
_signData = common->getSignData(_index);
|
||||
|
||||
_dirty = unit->getDirty(index);
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
|
||||
_trs = unit->getTRS(index);
|
||||
_localMat = unit->getLocalMat(index);
|
||||
_worldMat = unit->getWorldMat(index);
|
||||
_parentInfo = unit->getParent(index);
|
||||
_parentInfo->unitID = PARENT_INVALID;
|
||||
_parentInfo->index = PARENT_INVALID;
|
||||
_localZOrder = unit->getZOrder(index);
|
||||
_cullingMask = unit->getCullingMask(index);
|
||||
_opacity = unit->getOpacity(index);
|
||||
_is3DNode = unit->getIs3D(index);
|
||||
_skew = unit->getSkew(index);
|
||||
|
||||
uint64_t* self = unit->getNode(index);
|
||||
*self = (uint64_t)this;
|
||||
}
|
||||
|
||||
NodeProxy::~NodeProxy()
|
||||
{
|
||||
for (auto& child : _children)
|
||||
{
|
||||
child->_parent = nullptr;
|
||||
}
|
||||
|
||||
CC_SAFE_RELEASE(_assembler);
|
||||
}
|
||||
|
||||
void NodeProxy::destroyImmediately()
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
RenderFlow::getInstance()->removeNodeLevel(_level, _worldMat);
|
||||
CC_SAFE_RELEASE_NULL(_assembler);
|
||||
_level = NODE_LEVEL_INVALID;
|
||||
_dirty = nullptr;
|
||||
_trs = nullptr;
|
||||
_localMat = nullptr;
|
||||
_worldMat = nullptr;
|
||||
_parentInfo = nullptr;
|
||||
_localZOrder = nullptr;
|
||||
_cullingMask = nullptr;
|
||||
_opacity = nullptr;
|
||||
_is3DNode = nullptr;
|
||||
_skew = nullptr;
|
||||
}
|
||||
|
||||
// lazy allocs
|
||||
void NodeProxy::childrenAlloc()
|
||||
{
|
||||
_children.reserve(4);
|
||||
}
|
||||
|
||||
void NodeProxy::addChild(NodeProxy* child)
|
||||
{
|
||||
if (child == nullptr)
|
||||
{
|
||||
CCLOGWARN("Argument must be non-nil");
|
||||
return;
|
||||
}
|
||||
if (child->_parent != nullptr)
|
||||
{
|
||||
CCLOGWARN("child already added. It can't be added again");
|
||||
return;
|
||||
}
|
||||
auto assertNotSelfChild
|
||||
( [ this, child ]() -> bool
|
||||
{
|
||||
for ( NodeProxy* parent( this ); parent != nullptr;
|
||||
parent = parent->getParent() )
|
||||
if ( parent == child )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} );
|
||||
(void)assertNotSelfChild;
|
||||
|
||||
if (!assertNotSelfChild())
|
||||
{
|
||||
CCLOGWARN("A node cannot be the child of his own children" );
|
||||
return;
|
||||
}
|
||||
|
||||
if (_children.empty())
|
||||
{
|
||||
this->childrenAlloc();
|
||||
}
|
||||
_children.pushBack(child);
|
||||
child->setParent(this);
|
||||
}
|
||||
|
||||
void NodeProxy::detachChild(NodeProxy *child, ssize_t childIndex)
|
||||
{
|
||||
// set parent nil at the end
|
||||
child->setParent(nullptr);
|
||||
_children.erase(childIndex);
|
||||
}
|
||||
|
||||
void NodeProxy::removeChild(NodeProxy* child)
|
||||
{
|
||||
// explicit nil handling
|
||||
if (_children.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ssize_t index = _children.getIndex(child);
|
||||
if( index != CC_INVALID_INDEX )
|
||||
this->detachChild( child, index );
|
||||
}
|
||||
|
||||
void NodeProxy::removeAllChildren()
|
||||
{
|
||||
// not using detachChild improves speed here
|
||||
for (const auto& child : _children)
|
||||
{
|
||||
// set parent nil at the end
|
||||
child->setParent(nullptr);
|
||||
}
|
||||
|
||||
_children.clear();
|
||||
}
|
||||
|
||||
NodeProxy* NodeProxy::getChildByName(std::string childName)
|
||||
{
|
||||
for (auto child : _children)
|
||||
{
|
||||
if (child->_name == childName)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NodeProxy* NodeProxy::getChildByID(std::string id)
|
||||
{
|
||||
for (auto child : _children)
|
||||
{
|
||||
if (child->_id == id)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NodeProxy::notifyUpdateParent()
|
||||
{
|
||||
if (_parentInfo->index == PARENT_INVALID)
|
||||
{
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
updateLevel();
|
||||
return;
|
||||
}
|
||||
|
||||
NodeMemPool* pool = NodeMemPool::getInstance();
|
||||
CCASSERT(pool, "NodeProxy updateParent NodeMemPool is null");
|
||||
UnitNode* unit = pool->getUnit(_parentInfo->unitID);
|
||||
CCASSERT(unit, "NodeProxy updateParent unit is null");
|
||||
uint64_t* parentAddrs = unit->getNode(_parentInfo->index);
|
||||
NodeProxy* parent = (NodeProxy*)*parentAddrs;
|
||||
CCASSERT(parent, "NodeProxy updateParent parent is null");
|
||||
|
||||
if (parent != _parent) {
|
||||
if (_parent)
|
||||
{
|
||||
_parent->removeChild(this);
|
||||
}
|
||||
parent->addChild(this);
|
||||
updateLevel();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateLevel()
|
||||
{
|
||||
static RenderFlow::LevelInfo levelInfo;
|
||||
auto renderFlow = RenderFlow::getInstance();
|
||||
|
||||
renderFlow->removeNodeLevel(_level, _worldMat);
|
||||
|
||||
levelInfo.dirty = _dirty;
|
||||
levelInfo.localMat = _localMat;
|
||||
levelInfo.worldMat = _worldMat;
|
||||
levelInfo.opacity = _opacity;
|
||||
levelInfo.realOpacity = &_realOpacity;
|
||||
|
||||
if (_parent)
|
||||
{
|
||||
_level = _parent->_level + 1;
|
||||
levelInfo.parentWorldMat = _parent->_worldMat;
|
||||
levelInfo.parentDirty = _parent->_dirty;
|
||||
levelInfo.parentRealOpacity = &_parent->_realOpacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
_level = 0;
|
||||
levelInfo.parentWorldMat = nullptr;
|
||||
levelInfo.parentDirty = nullptr;
|
||||
levelInfo.parentRealOpacity = nullptr;
|
||||
}
|
||||
renderFlow->insertNodeLevel(_level, levelInfo);
|
||||
|
||||
for (auto it = _children.begin(); it != _children.end(); it++)
|
||||
{
|
||||
(*it)->updateLevel();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::setLocalZOrder(int zOrder)
|
||||
{
|
||||
if (*_localZOrder != zOrder)
|
||||
{
|
||||
*_localZOrder = zOrder;
|
||||
if (_parent != nullptr)
|
||||
{
|
||||
*_parent->_dirty |= RenderFlow::REORDER_CHILDREN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::reorderChildren()
|
||||
{
|
||||
if (*_dirty & RenderFlow::REORDER_CHILDREN)
|
||||
{
|
||||
#if CC_64BITS
|
||||
std::sort(std::begin(_children), std::end(_children), [](NodeProxy* n1, NodeProxy* n2) {
|
||||
return (*n1->_localZOrder < *n2->_localZOrder);
|
||||
});
|
||||
#else
|
||||
std::stable_sort(std::begin(_children), std::end(_children), [](NodeProxy* n1, NodeProxy* n2) {
|
||||
return *n1->_localZOrder < *n2->_localZOrder;
|
||||
});
|
||||
#endif
|
||||
*_dirty &= ~RenderFlow::REORDER_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::setAssembler(AssemblerBase* assembler)
|
||||
{
|
||||
if (assembler == _assembler) return;
|
||||
CC_SAFE_RELEASE(_assembler);
|
||||
_assembler = assembler;
|
||||
CC_SAFE_RETAIN(_assembler);
|
||||
|
||||
auto assemblerSprite = dynamic_cast<AssemblerSprite*>(_assembler);
|
||||
if (assemblerSprite)
|
||||
{
|
||||
*_dirty |= RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
else
|
||||
{
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::clearAssembler()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_assembler);
|
||||
*_dirty &= ~RenderFlow::PRE_CALCULATE_VERTICES;
|
||||
}
|
||||
|
||||
AssemblerBase* NodeProxy::getAssembler() const
|
||||
{
|
||||
return _assembler;
|
||||
}
|
||||
|
||||
void NodeProxy::getPosition(cocos2d::Vec3* out) const
|
||||
{
|
||||
out->x = _trs->x;
|
||||
out->y = _trs->y;
|
||||
out->z = _trs->z;
|
||||
}
|
||||
|
||||
void NodeProxy::getRotation(cocos2d::Quaternion* out) const
|
||||
{
|
||||
out->x = _trs->qx;
|
||||
out->y = _trs->qy;
|
||||
out->z = _trs->qz;
|
||||
out->w = _trs->qw;
|
||||
}
|
||||
|
||||
void NodeProxy::getScale(cocos2d::Vec3* out) const
|
||||
{
|
||||
out->x = _trs->sx;
|
||||
out->y = _trs->sy;
|
||||
out->z = _trs->sz;
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldRotation(cocos2d::Quaternion* out) const
|
||||
{
|
||||
getRotation(out);
|
||||
|
||||
cocos2d::Quaternion rot;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getRotation(&rot);
|
||||
Quaternion::multiply(rot, *out, out);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldPosition(cocos2d::Vec3* out) const
|
||||
{
|
||||
getPosition(out);
|
||||
|
||||
cocos2d::Vec3 pos;
|
||||
cocos2d::Quaternion rot;
|
||||
cocos2d::Vec3 scale;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getPosition(&pos);
|
||||
curr->getRotation(&rot);
|
||||
curr->getScale(&scale);
|
||||
|
||||
out->multiply(scale);
|
||||
out->transformQuat(rot);
|
||||
out->add(pos);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::getWorldRT(cocos2d::Mat4* out) const
|
||||
{
|
||||
cocos2d::Vec3 opos(_trs->x, _trs->y, _trs->z);
|
||||
cocos2d::Quaternion orot(_trs->qx, _trs->qy, _trs->qz, _trs->qw);
|
||||
|
||||
cocos2d::Vec3 pos;
|
||||
cocos2d::Quaternion rot;
|
||||
cocos2d::Vec3 scale;
|
||||
NodeProxy* curr = _parent;
|
||||
while (curr != nullptr)
|
||||
{
|
||||
curr->getPosition(&pos);
|
||||
curr->getRotation(&rot);
|
||||
curr->getScale(&scale);
|
||||
|
||||
opos.multiply(scale);
|
||||
opos.transformQuat(rot);
|
||||
opos.add(pos);
|
||||
Quaternion::multiply(rot, orot, &orot);
|
||||
curr = curr->getParent();
|
||||
}
|
||||
out->setIdentity();
|
||||
out->translate(opos);
|
||||
cocos2d::Mat4 quatMat;
|
||||
cocos2d::Mat4::createRotation(orot, &quatMat);
|
||||
out->multiply(quatMat);
|
||||
}
|
||||
|
||||
void NodeProxy::setOpacity(uint8_t opacity)
|
||||
{
|
||||
if (*_opacity != opacity)
|
||||
{
|
||||
*_opacity = opacity;
|
||||
*_dirty |= RenderFlow::OPACITY;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateRealOpacity()
|
||||
{
|
||||
bool selfOpacityDirty = *_dirty & RenderFlow::OPACITY;
|
||||
if (_parent)
|
||||
{
|
||||
if (selfOpacityDirty || *_parent->_dirty & RenderFlow::NODE_OPACITY_CHANGED)
|
||||
{
|
||||
_realOpacity = *_opacity * _parent->getRealOpacity() / 255.0f;
|
||||
*_dirty &= ~RenderFlow::OPACITY;
|
||||
*_dirty |= RenderFlow::NODE_OPACITY_CHANGED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
_realOpacity = *_opacity;
|
||||
*_dirty &= ~RenderFlow::OPACITY;
|
||||
*_dirty |= RenderFlow::NODE_OPACITY_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateWorldMatrix()
|
||||
{
|
||||
if (!_updateWorldMatrix) return;
|
||||
|
||||
bool selfWorldDirty = *_dirty & RenderFlow::WORLD_TRANSFORM;
|
||||
if (_parent)
|
||||
{
|
||||
if (selfWorldDirty || *_parent->_dirty & RenderFlow::WORLD_TRANSFORM_CHANGED)
|
||||
{
|
||||
cocos2d::Mat4::multiply(_parent->getWorldMatrix(), *_localMat, _worldMat);
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
}
|
||||
else if (selfWorldDirty)
|
||||
{
|
||||
*_worldMat = *_localMat;
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::updateWorldMatrix(const cocos2d::Mat4& worldMatrix)
|
||||
{
|
||||
*_worldMat = worldMatrix;
|
||||
*_dirty &= ~RenderFlow::WORLD_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM_CHANGED;
|
||||
}
|
||||
|
||||
void NodeProxy::updateLocalMatrix()
|
||||
{
|
||||
bool skew = std::abs(_skew->x - 0.0f) > MATH_EPSILON || std::abs(_skew->y - 0.0f) > MATH_EPSILON;
|
||||
if (*_dirty & RenderFlow::LOCAL_TRANSFORM || skew)
|
||||
{
|
||||
_localMat->setIdentity();
|
||||
|
||||
// Transform = Translate * Rotation * Scale;
|
||||
cocos2d::Quaternion q(_trs->qx, _trs->qy, _trs->qz, _trs->qw);
|
||||
if (*_is3DNode)
|
||||
{
|
||||
_localMat->translate(_trs->x, _trs->y, _trs->z);
|
||||
_localMat->rotate(q);
|
||||
_localMat->scale(_trs->sx, _trs->sy, _trs->sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
_localMat->translate(_trs->x, _trs->y, 0);
|
||||
_localMat->rotate(q);
|
||||
_localMat->scale(_trs->sx, _trs->sy, 1);
|
||||
}
|
||||
|
||||
if (skew)
|
||||
{
|
||||
auto& m = _localMat->m;
|
||||
auto a = m[0];
|
||||
auto b = m[1];
|
||||
auto c = m[4];
|
||||
auto d = m[5];
|
||||
auto skx = (float)tanf(CC_DEGREES_TO_RADIANS(_skew->x));
|
||||
auto sky = (float)tanf(CC_DEGREES_TO_RADIANS(_skew->y));
|
||||
m[0] = a + c * sky;
|
||||
m[1] = b + d * sky;
|
||||
m[4] = c + a * skx;
|
||||
m[5] = d + b * skx;
|
||||
}
|
||||
|
||||
*_dirty &= ~RenderFlow::LOCAL_TRANSFORM;
|
||||
*_dirty |= RenderFlow::WORLD_TRANSFORM;
|
||||
}
|
||||
}
|
||||
|
||||
void NodeProxy::render(NodeProxy* node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
node->_renderOrder = _globalRenderOrder++;
|
||||
|
||||
if (!node->_needVisit || node->_realOpacity == 0) return;
|
||||
|
||||
bool needRender = *node->_dirty & RenderFlow::RENDER;
|
||||
if (node->_needRender != needRender)
|
||||
{
|
||||
if (node->_assembler) node->_assembler->enableDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
node->_needRender = needRender;
|
||||
}
|
||||
|
||||
// pre render
|
||||
if (node->_assembler && needRender) node->_assembler->handle(node, batcher, scene);
|
||||
|
||||
node->reorderChildren();
|
||||
for (const auto& child : node->_children)
|
||||
{
|
||||
auto traverseHandle = child->traverseHandle;
|
||||
traverseHandle(child, batcher, scene);
|
||||
}
|
||||
|
||||
// post render
|
||||
bool needPostRender = *(node->_dirty) & RenderFlow::POST_RENDER;
|
||||
if (node->_assembler && needPostRender) node->_assembler->postHandle(node, batcher, scene);
|
||||
}
|
||||
|
||||
void NodeProxy::visit(NodeProxy* node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
node->_renderOrder = _globalRenderOrder++;
|
||||
|
||||
if (!node->_needVisit) return;
|
||||
|
||||
node->updateRealOpacity();
|
||||
|
||||
if (node->_realOpacity == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node->updateLocalMatrix();
|
||||
node->updateWorldMatrix();
|
||||
|
||||
bool needRender = *(node->_dirty) & RenderFlow::RENDER;
|
||||
if (node->_needRender != needRender)
|
||||
{
|
||||
if (node->_assembler) node->_assembler->enableDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
node->_needRender = needRender;
|
||||
}
|
||||
|
||||
// pre render
|
||||
if (node->_assembler && needRender) node->_assembler->handle(node, batcher, scene);
|
||||
|
||||
node->reorderChildren();
|
||||
for (const auto& child : node->_children)
|
||||
{
|
||||
visit(child, batcher, scene);
|
||||
}
|
||||
|
||||
// post render
|
||||
bool needPostRender = *(node->_dirty) & RenderFlow::POST_RENDER;
|
||||
if (node->_assembler && needPostRender) node->_assembler->postHandle(node, batcher, scene);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
369
cocos2d-x/cocos/renderer/scene/NodeProxy.hpp
Normal file
369
cocos2d-x/cocos/renderer/scene/NodeProxy.hpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "base/CCRef.h"
|
||||
#include "base/ccTypes.h"
|
||||
#include "base/CCVector.h"
|
||||
#include "base/CCMap.h"
|
||||
#include "math/CCMath.h"
|
||||
#include "assembler/AssemblerBase.hpp"
|
||||
#include "MemPool.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class ModelBatcher;
|
||||
class Scene;
|
||||
struct TRS;
|
||||
struct ParentInfo;
|
||||
struct Skew;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief NodeProxy is a cpp delegator of js Node.\n
|
||||
* It synchronize the hierarchy from js node tree, update the transform each frame, and manages assembler which represent the render component.\n
|
||||
* JS API: renderer.NodeProxy
|
||||
@code
|
||||
let node = new cc.Node();
|
||||
// NodeProxy is automatically created by cc.Node
|
||||
let proxy = node._proxy;
|
||||
@endcode
|
||||
*/
|
||||
class NodeProxy : public Ref
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(NodeProxy*, ModelBatcher*, Scene*)> TraverseFunc;
|
||||
|
||||
/*
|
||||
* @brief Visit the node but do not transform position.
|
||||
*/
|
||||
static void render(NodeProxy* node, ModelBatcher* batcher, Scene* scene);
|
||||
/*
|
||||
* @brief Visit the node as a ordinary node but not a root node.
|
||||
*/
|
||||
static void visit(NodeProxy* node, ModelBatcher* batcher, Scene* scene);
|
||||
/*
|
||||
* @brief Reset global render order.
|
||||
*/
|
||||
static void resetGlobalRenderOrder() { _globalRenderOrder = 0; }
|
||||
|
||||
/*
|
||||
* @brief The default constructor.
|
||||
*/
|
||||
NodeProxy(std::size_t unitID, std::size_t index, const std::string& id, const std::string& name);
|
||||
/*
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~NodeProxy();
|
||||
/*
|
||||
* @brief destroy node data immediately .
|
||||
*/
|
||||
void destroyImmediately();
|
||||
|
||||
/*
|
||||
* @brief If js node has been destroy.
|
||||
*/
|
||||
bool isValid() { return _trs != nullptr; }
|
||||
|
||||
/// @{
|
||||
/// @name Hierarchy
|
||||
|
||||
/**
|
||||
* @brief Adds child node proxy to the node proxy.
|
||||
* @param[in] child A child node proxy pointer.
|
||||
*/
|
||||
void addChild(NodeProxy * child);
|
||||
/**
|
||||
* @brief Removes child node proxy from the node proxy.
|
||||
* @param[in] child A child node proxy pointer.
|
||||
*/
|
||||
void removeChild(NodeProxy* child);
|
||||
/**
|
||||
* @brief Removes all child node proxies from the current one.
|
||||
*/
|
||||
void removeAllChildren();
|
||||
/**
|
||||
* @brief Update parent by parent unitId and index.
|
||||
*/
|
||||
void notifyUpdateParent();
|
||||
|
||||
/**
|
||||
* @brief Sets the node proxy parent.
|
||||
* @param[in] parent.
|
||||
*/
|
||||
inline void setParent(NodeProxy* parent) { _parent = parent; };
|
||||
/**
|
||||
* @brief Gets the node proxy parent.
|
||||
* @return Parent.
|
||||
*/
|
||||
inline NodeProxy* getParent() const { return _parent; };
|
||||
/**
|
||||
* @brief Gets the node proxy all children.
|
||||
* @return Children container.
|
||||
*/
|
||||
inline const Vector<NodeProxy*>& getChildren() const { return _children; };
|
||||
/**
|
||||
* @brief Gets the node proxy child count.
|
||||
* @return Child count.
|
||||
*/
|
||||
inline size_t getChildrenCount() const { return _children.size(); };
|
||||
/**
|
||||
* @brief Gets a child node by name.
|
||||
* @return Child node.
|
||||
*/
|
||||
NodeProxy* getChildByName(std::string childName);
|
||||
/**
|
||||
* @brief Gets a child node by runtime id.
|
||||
* @return Child node.
|
||||
*/
|
||||
NodeProxy* getChildByID(std::string id);
|
||||
/**
|
||||
* @brief Sets the node proxy's local zorder.
|
||||
* @param[in] zOrder The value of zorder.
|
||||
*/
|
||||
void setLocalZOrder(int zOrder);
|
||||
|
||||
/// @} end of Hierarchy
|
||||
|
||||
/*
|
||||
* @brief Gets the world matrix.
|
||||
* @return World matrix.
|
||||
*/
|
||||
inline const cocos2d::Mat4& getWorldMatrix() const { return *_worldMat; };
|
||||
|
||||
/*
|
||||
* @brief Gets the local matrix.
|
||||
* @return Local matrix.
|
||||
*/
|
||||
inline const cocos2d::Mat4& getLocalMatrix() const { return *_localMat; };
|
||||
|
||||
/*
|
||||
* @brief Gets the position.
|
||||
* @param[out] out The position vector
|
||||
*/
|
||||
void getPosition(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets the rotation.
|
||||
* @param[out] out The rotation quaternion.
|
||||
*/
|
||||
void getRotation(cocos2d::Quaternion* out) const;
|
||||
/*
|
||||
* @brief Gets the scale.
|
||||
* @param[out] out The scale vector.
|
||||
*/
|
||||
void getScale(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets world rotation.
|
||||
* @param[out] out The rotation quaternion.
|
||||
*/
|
||||
void getWorldRotation(cocos2d::Quaternion* out) const;
|
||||
/*
|
||||
* @brief Gets the position in world coordinates.
|
||||
* @param[out] out The world position vector.
|
||||
*/
|
||||
void getWorldPosition(cocos2d::Vec3* out) const;
|
||||
/*
|
||||
* @brief Gets the matrix contains the world rotation and translation.
|
||||
* @param[out] out The matrix to store datas.
|
||||
*/
|
||||
void getWorldRT(cocos2d::Mat4* out) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the node's opacity.
|
||||
*/
|
||||
inline uint8_t getOpacity() const { return *_opacity; };
|
||||
/**
|
||||
* @brief Sets the node's opacity.
|
||||
*/
|
||||
void setOpacity(uint8_t opacity);
|
||||
/**
|
||||
* @brief Updates opacity from parent.
|
||||
*/
|
||||
void updateRealOpacity();
|
||||
/**
|
||||
* @brief Gets the node's realOpacity.
|
||||
*/
|
||||
inline const uint8_t getRealOpacity() const {return _realOpacity;};
|
||||
/**
|
||||
* @brief Gets the node's group id, this controls which camera can see the node.
|
||||
*/
|
||||
inline int getCullingMask() const { return *_cullingMask; };
|
||||
/**
|
||||
* @brief Sets the node's group id.
|
||||
* @param[in] groupID The group id
|
||||
*/
|
||||
inline void setCullingMask(int cullingMask) { *_cullingMask = cullingMask; };
|
||||
|
||||
/**
|
||||
* @brief Gets the node's name.
|
||||
* This equals to the one in JS node, helps to debug in cpp.
|
||||
* @return name
|
||||
*/
|
||||
inline const std::string& getName() const { return _name; };
|
||||
/**
|
||||
* @brief Sets the node's name.
|
||||
* The name should be updated once JS node's name changes.
|
||||
* @param[in] name
|
||||
*/
|
||||
inline void setName(const std::string& name) { _name = name; };
|
||||
|
||||
/**
|
||||
* @brief Sets the node's 3D state.
|
||||
* @param[in] is3DNode
|
||||
*/
|
||||
inline void set3DNode(bool is3DNode) { *_is3DNode = is3DNode ? 0x1 : 0x0; };
|
||||
|
||||
/**
|
||||
* @brief Sets a system handle to the node proxy, system handle will be invoked during node's visit process.
|
||||
* @param[in] handle The system handle pointer.
|
||||
*/
|
||||
void setAssembler(AssemblerBase* assembler);
|
||||
/**
|
||||
* @brief Removes a system handle from node proxy by system id.
|
||||
* @param[in] sysid The system id.
|
||||
*/
|
||||
void clearAssembler();
|
||||
/**
|
||||
* @brief Gets the system handle by system id.
|
||||
* @param[in] sysid The system id.
|
||||
* @return The system handle object or nullptr if not exist
|
||||
*/
|
||||
AssemblerBase* getAssembler() const;
|
||||
/*
|
||||
* @brief Enables visit.
|
||||
*/
|
||||
void enableVisit(bool value) { _needVisit = value; }
|
||||
|
||||
/*
|
||||
* @brief Disables visit.
|
||||
*/
|
||||
void disableVisit() { _needVisit = false; }
|
||||
|
||||
/*
|
||||
* @brief Updates local matrix.
|
||||
*/
|
||||
void updateLocalMatrix();
|
||||
/*
|
||||
* @brief Updates world matrix.
|
||||
*/
|
||||
void updateWorldMatrix();
|
||||
/*
|
||||
* @brief Updates world matrix with provide matrix.
|
||||
*/
|
||||
void updateWorldMatrix(const cocos2d::Mat4& worldMatrix);
|
||||
/*
|
||||
* @brief Enables calc world matrix.
|
||||
*/
|
||||
void enableUpdateWorldMatrix(bool value) { _updateWorldMatrix = value; }
|
||||
|
||||
/*
|
||||
* @brief Gets node runtime id
|
||||
*/
|
||||
const std::string& getID() const { return _id; }
|
||||
|
||||
/*
|
||||
* @brief Gets node dirty
|
||||
*/
|
||||
uint32_t* getDirty() const { return _dirty; }
|
||||
|
||||
/*
|
||||
* @brief Is node flag dirty
|
||||
*/
|
||||
bool isDirty(uint32_t flag) const { return *_dirty & flag; }
|
||||
|
||||
/*
|
||||
* @brief Gets render order
|
||||
*/
|
||||
uint32_t getRenderOrder () { return _renderOrder; }
|
||||
|
||||
/*
|
||||
* @brief switch traverse interface to visit
|
||||
*/
|
||||
void switchTraverseToVisit() { traverseHandle = visit; }
|
||||
/*
|
||||
* @brief switch traverse interface to render
|
||||
*/
|
||||
void switchTraverseToRender() { traverseHandle = render; }
|
||||
|
||||
/*
|
||||
* @brief traverse handle
|
||||
*/
|
||||
TraverseFunc traverseHandle = nullptr;
|
||||
protected:
|
||||
void updateLevel();
|
||||
void childrenAlloc();
|
||||
void detachChild(NodeProxy* child, ssize_t childIndex);
|
||||
void reorderChildren();
|
||||
private:
|
||||
bool _needVisit = true;
|
||||
bool _updateWorldMatrix = true;
|
||||
bool _needRender = false;
|
||||
|
||||
uint8_t _realOpacity = 255;
|
||||
std::string _id = "";
|
||||
std::string _name = "";
|
||||
std::size_t _level = 0;
|
||||
|
||||
uint32_t* _dirty = nullptr;
|
||||
TRS* _trs = nullptr;
|
||||
cocos2d::Mat4* _localMat = nullptr;
|
||||
cocos2d::Mat4* _worldMat = nullptr;
|
||||
ParentInfo* _parentInfo = nullptr;
|
||||
int32_t* _localZOrder = nullptr;
|
||||
int32_t* _cullingMask = nullptr;
|
||||
uint8_t* _opacity = nullptr;
|
||||
uint8_t* _is3DNode = nullptr;
|
||||
Skew* _skew = nullptr;
|
||||
|
||||
std::size_t _unitID = 0;
|
||||
std::size_t _index = 0;
|
||||
|
||||
Sign* _signData = nullptr;
|
||||
NodeProxy* _parent = nullptr; ///< weak reference to parent node
|
||||
cocos2d::Vector<NodeProxy*> _children; ///< array of children nodes
|
||||
|
||||
AssemblerBase* _assembler = nullptr;
|
||||
|
||||
uint32_t _renderOrder = 0;
|
||||
static uint32_t _globalRenderOrder;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
176
cocos2d-x/cocos/renderer/scene/ParallelTask.cpp
Normal file
176
cocos2d-x/cocos/renderer/scene/ParallelTask.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "ParallelTask.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
ParallelTask::ParallelTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ParallelTask::~ParallelTask()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void ParallelTask::init(int threadNum)
|
||||
{
|
||||
_finished = false;
|
||||
_threadNum = threadNum;
|
||||
|
||||
_tasks.resize(_threadNum);
|
||||
_threads.resize(_threadNum);
|
||||
_runFlags = new uint8_t[_threadNum];
|
||||
memset(_runFlags, RunFlag::Stop, sizeof(uint8_t) * _threadNum);
|
||||
|
||||
for(auto i = 0; i < _threadNum; i++)
|
||||
{
|
||||
setThread(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelTask::pushTask(int tid, const Task& task)
|
||||
{
|
||||
if (tid >= 0 && tid < _tasks.size())
|
||||
{
|
||||
_tasks[tid].push_back(task);
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelTask::clearTasks()
|
||||
{
|
||||
for(std::size_t i = 0, n = _tasks.size(); i < n; i++)
|
||||
{
|
||||
_tasks[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* ParallelTask::getRunFlag()
|
||||
{
|
||||
return _runFlags;
|
||||
}
|
||||
|
||||
void ParallelTask::destroy()
|
||||
{
|
||||
_finished = true;
|
||||
beginAllThreads();
|
||||
for (int i = 0, n = (int)_threads.size(); i < n; ++i)
|
||||
{
|
||||
joinThread(i);
|
||||
}
|
||||
_tasks.clear();
|
||||
_threads.clear();
|
||||
delete _runFlags;
|
||||
_runFlags = nullptr;
|
||||
_threadNum = 0;
|
||||
}
|
||||
|
||||
void ParallelTask::stopAllThreads()
|
||||
{
|
||||
if (!_runFlags) return;
|
||||
memset(_runFlags, RunFlag::Stop, sizeof(uint8_t) * _threadNum);
|
||||
}
|
||||
|
||||
void ParallelTask::beginAllThreads()
|
||||
{
|
||||
if (!_runFlags) return;
|
||||
memset(_runFlags, RunFlag::Begin, sizeof(uint8_t) * _threadNum);
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cv.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelTask::waitAllThreads()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cv.wait(lock, [this]() {
|
||||
if (!_runFlags) return true;
|
||||
for (auto i = 0; i < _threadNum; i++)
|
||||
{
|
||||
if (_runFlags[i] == RunFlag::Begin) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void ParallelTask::joinThread(int tid)
|
||||
{
|
||||
if (tid < 0 || tid >= (int)_threads.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_threads[tid]->joinable())
|
||||
{
|
||||
_threads[tid]->join();
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelTask::setThread(int tid)
|
||||
{
|
||||
auto f = [this, tid]() {
|
||||
uint8_t& runFlag = _runFlags[tid];
|
||||
if (!runFlag) return;
|
||||
|
||||
auto& taskQueue = _tasks[tid];
|
||||
std::size_t idx = 0;
|
||||
std::size_t taskCount = 0;
|
||||
|
||||
while (!_finished)
|
||||
{
|
||||
switch (runFlag)
|
||||
{
|
||||
case RunFlag::Begin:
|
||||
for (idx = 0, taskCount = taskQueue.size(); idx < taskCount; idx++)
|
||||
{
|
||||
const Task& task = taskQueue[idx];
|
||||
task(tid);
|
||||
}
|
||||
runFlag = RunFlag::Stop;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cv.notify_all();
|
||||
}
|
||||
break;
|
||||
case RunFlag::Stop:
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cv.wait(lock, [this, &runFlag]()
|
||||
{
|
||||
return runFlag == RunFlag::Begin || _finished;
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
_threads[tid].reset(new(std::nothrow) std::thread(f));
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
78
cocos2d-x/cocos/renderer/scene/ParallelTask.hpp
Normal file
78
cocos2d-x/cocos/renderer/scene/ParallelTask.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class ParallelTask
|
||||
{
|
||||
public:
|
||||
|
||||
enum RunFlag{
|
||||
Begin = 0x00,
|
||||
Stop = 0x01,
|
||||
};
|
||||
|
||||
typedef std::function<void(int)> Task;
|
||||
|
||||
ParallelTask();
|
||||
virtual ~ParallelTask();
|
||||
|
||||
void pushTask(int tid, const Task& task);
|
||||
void clearTasks();
|
||||
|
||||
uint8_t* getRunFlag();
|
||||
|
||||
void init(int threadNum);
|
||||
void destroy();
|
||||
|
||||
void waitAllThreads();
|
||||
void stopAllThreads();
|
||||
void beginAllThreads();
|
||||
private:
|
||||
void joinThread(int tid);
|
||||
void setThread(int tid);
|
||||
private:
|
||||
std::vector<std::vector<Task>> _tasks;
|
||||
std::vector<std::unique_ptr<std::thread>> _threads;
|
||||
|
||||
uint8_t* _runFlags = nullptr;
|
||||
bool _finished = false;
|
||||
int _threadNum = 0;
|
||||
|
||||
std::mutex _mutex;
|
||||
std::condition_variable _cv;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
379
cocos2d-x/cocos/renderer/scene/RenderFlow.cpp
Normal file
379
cocos2d-x/cocos/renderer/scene/RenderFlow.cpp
Normal file
@@ -0,0 +1,379 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderFlow.hpp"
|
||||
#include "NodeMemPool.hpp"
|
||||
#include "assembler/AssemblerSprite.hpp"
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
#include "MiddlewareManager.h"
|
||||
#endif
|
||||
|
||||
#define SUB_RENDER_THREAD_COUNT 1
|
||||
#define RENDER_THREAD_COUNT (SUB_RENDER_THREAD_COUNT + 1)
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
const uint32_t InitLevelCount = 3;
|
||||
const uint32_t InitLevelNodeCount = 100;
|
||||
|
||||
const uint32_t LocalMat_Use_Thread_Unit_Count = 5;
|
||||
const uint32_t WorldMat_Use_Thread_Node_count = 500;
|
||||
|
||||
RenderFlow* RenderFlow::_instance = nullptr;
|
||||
|
||||
RenderFlow::RenderFlow(DeviceGraphics* device, Scene* scene, ForwardRenderer* forward)
|
||||
: _device(device)
|
||||
, _scene(scene)
|
||||
, _forward(forward)
|
||||
{
|
||||
_instance = this;
|
||||
|
||||
_batcher = new ModelBatcher(this);
|
||||
|
||||
#if SUB_RENDER_THREAD_COUNT > 0
|
||||
_paralleTask = new ParallelTask();
|
||||
_paralleTask->init(SUB_RENDER_THREAD_COUNT);
|
||||
|
||||
for (uint32_t i = 0; i < SUB_RENDER_THREAD_COUNT; i++)
|
||||
{
|
||||
_paralleTask->pushTask(i, [this](int tid){
|
||||
switch(_parallelStage)
|
||||
{
|
||||
case ParallelStage::LOCAL_MAT:
|
||||
calculateLocalMatrix(tid);
|
||||
break;
|
||||
case ParallelStage::WORLD_MAT:
|
||||
calculateLevelWorldMatrix(tid, _parallelStage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
_levelInfoArr.resize(InitLevelCount);
|
||||
for (auto i = 0; i < InitLevelCount; i++)
|
||||
{
|
||||
_levelInfoArr[i].reserve(InitLevelNodeCount);
|
||||
}
|
||||
}
|
||||
|
||||
RenderFlow::~RenderFlow()
|
||||
{
|
||||
CC_SAFE_DELETE(_paralleTask);
|
||||
CC_SAFE_DELETE(_batcher);
|
||||
}
|
||||
|
||||
void RenderFlow::removeNodeLevel(std::size_t level, cocos2d::Mat4* worldMat)
|
||||
{
|
||||
if (level >= _levelInfoArr.size()) return;
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
for(auto it = levelInfos.begin(); it != levelInfos.end(); it++)
|
||||
{
|
||||
if (it->worldMat == worldMat)
|
||||
{
|
||||
levelInfos.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::insertNodeLevel(std::size_t level, const LevelInfo& levelInfo)
|
||||
{
|
||||
if (level >= _levelInfoArr.size())
|
||||
{
|
||||
_levelInfoArr.resize(level + 1);
|
||||
}
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
levelInfos.push_back(levelInfo);
|
||||
}
|
||||
|
||||
void RenderFlow::calculateLocalMatrix(int tid)
|
||||
{
|
||||
const uint16_t SPACE_FREE_FLAG = 0x0;
|
||||
cocos2d::Mat4 matTemp;
|
||||
|
||||
NodeMemPool* instance = NodeMemPool::getInstance();
|
||||
CCASSERT(instance, "RenderFlow calculateLocalMatrix NodeMemPool is null");
|
||||
auto& commonList = instance->getCommonList();
|
||||
auto& nodePool = instance->getNodePool();
|
||||
|
||||
UnitCommon* commonUnit = nullptr;
|
||||
uint16_t usingNum = 0;
|
||||
std::size_t contentNum = 0;
|
||||
Sign* signData = nullptr;
|
||||
UnitNode* nodeUnit = nullptr;
|
||||
uint32_t* dirty = nullptr;
|
||||
cocos2d::Mat4* localMat = nullptr;
|
||||
TRS* trs = nullptr;
|
||||
uint8_t* is3D = nullptr;
|
||||
cocos2d::Quaternion* quat = nullptr;
|
||||
float trsZ = 0.0f, trsSZ = 0.0f;
|
||||
|
||||
std::size_t begin = 0, end = commonList.size();
|
||||
std::size_t fieldSize = end / RENDER_THREAD_COUNT;
|
||||
if (tid >= 0)
|
||||
{
|
||||
begin = tid * fieldSize;
|
||||
if (tid < RENDER_THREAD_COUNT - 1)
|
||||
{
|
||||
end = (tid + 1) * fieldSize;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto i = begin; i < end; i++)
|
||||
{
|
||||
commonUnit = commonList[i];
|
||||
if (!commonUnit) continue;
|
||||
usingNum = commonUnit->getUsingNum();
|
||||
if (usingNum == 0) continue;
|
||||
|
||||
contentNum = commonUnit->getContentNum();
|
||||
signData = commonUnit->getSignData(0);
|
||||
|
||||
nodeUnit = nodePool[commonUnit->unitID];
|
||||
|
||||
dirty = nodeUnit->getDirty(0);
|
||||
localMat = nodeUnit->getLocalMat(0);
|
||||
trs = nodeUnit->getTRS(0);
|
||||
is3D = nodeUnit->getIs3D(0);
|
||||
|
||||
NodeProxy** nodeProxy = (NodeProxy**)nodeUnit->getNode(0);
|
||||
|
||||
for (auto j = 0; j < contentNum; j++, localMat ++, trs ++, is3D ++, signData++, dirty++, nodeProxy++)
|
||||
{
|
||||
if (signData->freeFlag == SPACE_FREE_FLAG) continue;
|
||||
|
||||
// reset world transform changed flag
|
||||
*dirty &= ~(WORLD_TRANSFORM_CHANGED | NODE_OPACITY_CHANGED);
|
||||
if (!(*dirty & LOCAL_TRANSFORM)) continue;
|
||||
|
||||
localMat->setIdentity();
|
||||
trsZ = *is3D ? trs->z : 0;
|
||||
localMat->translate(trs->x, trs->y, trsZ);
|
||||
|
||||
quat = (cocos2d::Quaternion*)&(trs->qx);
|
||||
cocos2d::Mat4::createRotation(*quat, &matTemp);
|
||||
cocos2d::Mat4::multiply(*localMat, matTemp, localMat);
|
||||
|
||||
trsSZ = *is3D ? trs->sz : 1;
|
||||
cocos2d::Mat4::createScale(trs->sx, trs->sy, trsSZ, &matTemp);
|
||||
cocos2d::Mat4::multiply(*localMat, matTemp, localMat);
|
||||
|
||||
*dirty &= ~LOCAL_TRANSFORM;
|
||||
*dirty |= WORLD_TRANSFORM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::calculateLevelWorldMatrix(int tid, int stage)
|
||||
{
|
||||
if (_curLevel >= _levelInfoArr.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& levelInfos = _levelInfoArr[_curLevel];
|
||||
|
||||
std::size_t begin = 0, end = levelInfos.size();
|
||||
std::size_t fieldSize = end / RENDER_THREAD_COUNT;
|
||||
if (tid >= 0)
|
||||
{
|
||||
begin = tid * fieldSize;
|
||||
if (tid < RENDER_THREAD_COUNT - 1)
|
||||
{
|
||||
end = (tid + 1) * fieldSize;
|
||||
}
|
||||
}
|
||||
|
||||
for(std::size_t index = begin; index < end; index++)
|
||||
{
|
||||
auto& info = levelInfos[index];
|
||||
auto dirty = info.dirty;
|
||||
auto parentDirty = info.parentDirty;
|
||||
auto selfWorldDirty = *dirty & WORLD_TRANSFORM;
|
||||
auto selfOpacityDirty = *dirty & OPACITY;
|
||||
|
||||
if (parentDirty)
|
||||
{
|
||||
if ((*parentDirty & WORLD_TRANSFORM_CHANGED) || selfWorldDirty)
|
||||
{
|
||||
cocos2d::Mat4::multiply(*info.parentWorldMat, *info.localMat, info.worldMat);
|
||||
*dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if ((*parentDirty & NODE_OPACITY_CHANGED) || selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity * *info.parentRealOpacity / 255.0f;
|
||||
*dirty |= NODE_OPACITY_CHANGED;
|
||||
*dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfWorldDirty)
|
||||
{
|
||||
*info.worldMat = *info.localMat;
|
||||
*dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity;
|
||||
*dirty |= NODE_OPACITY_CHANGED;
|
||||
*dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::calculateWorldMatrix()
|
||||
{
|
||||
for(std::size_t level = 0, n = _levelInfoArr.size(); level < n; level++)
|
||||
{
|
||||
auto& levelInfos = _levelInfoArr[level];
|
||||
for(std::size_t index = 0, count = levelInfos.size(); index < count; index++)
|
||||
{
|
||||
auto& info = levelInfos[index];
|
||||
auto selfWorldDirty = *info.dirty & WORLD_TRANSFORM;
|
||||
auto selfOpacityDirty = *info.dirty & OPACITY;
|
||||
|
||||
if (info.parentDirty)
|
||||
{
|
||||
if ((*info.parentDirty & WORLD_TRANSFORM_CHANGED) || selfWorldDirty)
|
||||
{
|
||||
cocos2d::Mat4::multiply(*info.parentWorldMat, *info.localMat, info.worldMat);
|
||||
*info.dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*info.dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if ((*info.parentDirty & NODE_OPACITY_CHANGED) || selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity * *info.parentRealOpacity / 255.0f;
|
||||
*info.dirty |= NODE_OPACITY_CHANGED;
|
||||
*info.dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selfWorldDirty)
|
||||
{
|
||||
*info.worldMat = *info.localMat;
|
||||
*info.dirty |= WORLD_TRANSFORM_CHANGED;
|
||||
*info.dirty &= ~WORLD_TRANSFORM;
|
||||
}
|
||||
|
||||
if (selfOpacityDirty)
|
||||
{
|
||||
*info.realOpacity = *info.opacity;
|
||||
*info.dirty |= NODE_OPACITY_CHANGED;
|
||||
*info.dirty &= ~OPACITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::render(NodeProxy* scene, float deltaTime, Camera *camera)
|
||||
{
|
||||
if (scene != nullptr)
|
||||
{
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
// udpate middleware before render
|
||||
middleware::MiddlewareManager::getInstance()->update(deltaTime);
|
||||
#endif
|
||||
|
||||
#if SUB_RENDER_THREAD_COUNT > 0
|
||||
|
||||
int mainThreadTid = RENDER_THREAD_COUNT - 1;
|
||||
|
||||
NodeMemPool* instance = NodeMemPool::getInstance();
|
||||
auto& commonList = instance->getCommonList();
|
||||
if (commonList.size() < LocalMat_Use_Thread_Unit_Count)
|
||||
{
|
||||
_parallelStage = ParallelStage::NONE;
|
||||
calculateLocalMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
_parallelStage = ParallelStage::LOCAL_MAT;
|
||||
_paralleTask->beginAllThreads();
|
||||
calculateLocalMatrix(mainThreadTid);
|
||||
_paralleTask->waitAllThreads();
|
||||
}
|
||||
|
||||
_curLevel = 0;
|
||||
for(auto count = _levelInfoArr.size(); _curLevel < count; _curLevel++)
|
||||
{
|
||||
auto& levelInfos = _levelInfoArr[_curLevel];
|
||||
if (levelInfos.size() < WorldMat_Use_Thread_Node_count)
|
||||
{
|
||||
_parallelStage = ParallelStage::NONE;
|
||||
calculateLevelWorldMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
_parallelStage = ParallelStage::WORLD_MAT;
|
||||
_paralleTask->beginAllThreads();
|
||||
calculateLevelWorldMatrix(mainThreadTid);
|
||||
_paralleTask->waitAllThreads();
|
||||
}
|
||||
}
|
||||
#else
|
||||
calculateLocalMatrix();
|
||||
calculateWorldMatrix();
|
||||
#endif
|
||||
|
||||
_batcher->startBatch();
|
||||
|
||||
#if USE_MIDDLEWARE
|
||||
// render middleware
|
||||
middleware::MiddlewareManager::getInstance()->render(deltaTime);
|
||||
#endif
|
||||
scene->resetGlobalRenderOrder();
|
||||
|
||||
auto traverseHandle = scene->traverseHandle;
|
||||
traverseHandle(scene, _batcher, _scene);
|
||||
_batcher->terminateBatch();
|
||||
|
||||
if (camera) {
|
||||
_forward->renderCamera(camera, _scene);
|
||||
}
|
||||
else {
|
||||
_forward->render(_scene, deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFlow::visit(NodeProxy* rootNode)
|
||||
{
|
||||
NodeProxy::visit(rootNode, _batcher, _scene);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
180
cocos2d-x/cocos/renderer/scene/RenderFlow.hpp
Normal file
180
cocos2d-x/cocos/renderer/scene/RenderFlow.hpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Macro.h"
|
||||
#include "NodeProxy.hpp"
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "../renderer/Scene.h"
|
||||
#include "../renderer/ForwardRenderer.h"
|
||||
#include "../gfx/DeviceGraphics.h"
|
||||
#include "ParallelTask.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This class is responsible for the rendering process.\n
|
||||
* It visits the node tree, let nodes commit their render handles, starts the device level rendering process with ForwardRenderer.\n
|
||||
* JS API: renderer.RenderFlow
|
||||
@code
|
||||
// You actually shouldn't create RenderFlow by yourself, you can
|
||||
let renderFlow = cc.RenderFlow._nativeFlow;
|
||||
@endcode
|
||||
*/
|
||||
|
||||
#define NODE_LEVEL_INVALID 0xffffffff
|
||||
|
||||
class RenderFlow
|
||||
{
|
||||
public:
|
||||
|
||||
enum RenderFlowFlag {
|
||||
// sync js render flag
|
||||
|
||||
DONOTHING = 1 << 0,
|
||||
BREAK_FLOW = 1 << 1,
|
||||
LOCAL_TRANSFORM = 1 << 2,
|
||||
WORLD_TRANSFORM = 1 << 3,
|
||||
TRANSFORM = LOCAL_TRANSFORM | WORLD_TRANSFORM,
|
||||
UPDATE_RENDER_DATA = 1 << 4,
|
||||
OPACITY = 1 << 5,
|
||||
COLOR = 1 << 6,
|
||||
RENDER = 1 << 7,
|
||||
CHILDREN = 1 << 8,
|
||||
POST_RENDER = 1 << 9,
|
||||
FINAL = 1 << 10,
|
||||
|
||||
PRE_CALCULATE_VERTICES = 1 << 28,
|
||||
// native render flag
|
||||
REORDER_CHILDREN = 1 << 29,
|
||||
// world matrix changed
|
||||
WORLD_TRANSFORM_CHANGED = 1 << 30,
|
||||
// cascade opacity changed
|
||||
NODE_OPACITY_CHANGED = 1 << 31,
|
||||
};
|
||||
|
||||
enum ParallelStage {
|
||||
NONE = 1 << 0,
|
||||
LOCAL_MAT = 1 << 1,
|
||||
WORLD_MAT = 1 << 2,
|
||||
CALC_VERTICES = 1 << 3,
|
||||
};
|
||||
|
||||
struct LevelInfo{
|
||||
uint32_t* dirty = nullptr;
|
||||
uint32_t* parentDirty = nullptr;
|
||||
cocos2d::Mat4* parentWorldMat = nullptr;
|
||||
uint8_t* parentRealOpacity = nullptr;
|
||||
cocos2d::Mat4* localMat = nullptr;
|
||||
cocos2d::Mat4* worldMat = nullptr;
|
||||
uint8_t* opacity = nullptr;
|
||||
uint8_t* realOpacity = nullptr;
|
||||
};
|
||||
|
||||
static RenderFlow *getInstance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief The constructor.
|
||||
* @param[in] device
|
||||
* @param[in] scene
|
||||
* @param[in] forward
|
||||
*/
|
||||
RenderFlow(DeviceGraphics* device, Scene* scene, ForwardRenderer* forward);
|
||||
/*
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~RenderFlow();
|
||||
|
||||
/*
|
||||
* @brief Gets the ModelBatcher which is responsible for collecting render Models.
|
||||
*/
|
||||
ModelBatcher* getModelBatcher() const { return _batcher; };
|
||||
/*
|
||||
* @brief Gets the DeviceGraphics using by the current RenderFlow.
|
||||
*/
|
||||
DeviceGraphics* getDevice() const { return _device; };
|
||||
/*
|
||||
* @brief Gets the render Scene which manages all render Models.
|
||||
*/
|
||||
Scene* getRenderScene() const { return _scene; };
|
||||
/**
|
||||
* @brief Render the scene specified by its root node.
|
||||
* @param[in] scene The root node.
|
||||
*/
|
||||
void render(NodeProxy* scene, float deltaTime, Camera *camera = nullptr);
|
||||
/**
|
||||
* @brief Visit a node tree.
|
||||
*/
|
||||
void visit(NodeProxy* rootNode);
|
||||
/**
|
||||
* @brief Calculate local matrix.
|
||||
* @param[in] tid It must rather than -1 if enable multiple thread.
|
||||
*/
|
||||
void calculateLocalMatrix(int tid = -1);
|
||||
/**
|
||||
* @brief Calculate world matrix.
|
||||
*/
|
||||
void calculateWorldMatrix();
|
||||
/**
|
||||
* @brief Calculate world matrix by level.
|
||||
* @param[in] tid Thread id.
|
||||
* @param[level] level Node level.
|
||||
*/
|
||||
void calculateLevelWorldMatrix(int tid = -1, int stage = -1);
|
||||
/**
|
||||
* @brief remove node level
|
||||
*/
|
||||
void removeNodeLevel(std::size_t level, cocos2d::Mat4* worldMat);
|
||||
/**
|
||||
* @brief insert node level
|
||||
*/
|
||||
void insertNodeLevel(std::size_t level, const LevelInfo& levelInfo);
|
||||
private:
|
||||
|
||||
static RenderFlow *_instance;
|
||||
|
||||
ModelBatcher* _batcher = nullptr;
|
||||
Scene* _scene = nullptr;
|
||||
DeviceGraphics* _device = nullptr;
|
||||
ForwardRenderer* _forward = nullptr;
|
||||
std::size_t _curLevel = 0;
|
||||
std::vector<std::vector<LevelInfo>> _levelInfoArr;
|
||||
|
||||
ParallelStage _parallelStage = ParallelStage::NONE;
|
||||
ParallelTask* _paralleTask = nullptr;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
184
cocos2d-x/cocos/renderer/scene/StencilManager.cpp
Normal file
184
cocos2d-x/cocos/renderer/scene/StencilManager.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "StencilManager.hpp"
|
||||
#include "../Types.h"
|
||||
#include "../renderer/Technique.h"
|
||||
#include "../renderer/Pass.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
static const std::string techStage = "opaque";
|
||||
StencilManager* StencilManager::_instance = nullptr;
|
||||
|
||||
StencilManager::StencilManager ()
|
||||
: _stage(Stage::DISABLED)
|
||||
{
|
||||
}
|
||||
|
||||
StencilManager::~StencilManager ()
|
||||
{
|
||||
}
|
||||
|
||||
void StencilManager::reset ()
|
||||
{
|
||||
// reset stack and stage
|
||||
_maskStack.clear();
|
||||
_stage = Stage::DISABLED;
|
||||
}
|
||||
|
||||
EffectVariant* StencilManager::handleEffect (EffectVariant* effect)
|
||||
{
|
||||
Vector<Pass*>& passes = (Vector<Pass*>&)effect->getPasses();
|
||||
if (_stage == Stage::DISABLED)
|
||||
{
|
||||
for (const auto& pass : passes)
|
||||
{
|
||||
if (pass->isStencilTest()) {
|
||||
pass->disableStencilTest();
|
||||
}
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
|
||||
auto size = _maskStack.size();
|
||||
if (size == 0 || size == size_t(-1))
|
||||
{
|
||||
return effect;
|
||||
}
|
||||
|
||||
uint32_t ref;
|
||||
uint8_t stencilMask, writeMask;
|
||||
bool mask;
|
||||
StencilFunc func;
|
||||
StencilOp failOp = StencilOp::KEEP;
|
||||
const StencilOp& zFailOp = StencilOp::KEEP;
|
||||
const StencilOp& zPassOp = StencilOp::KEEP;
|
||||
|
||||
if (_stage == Stage::ENABLED)
|
||||
{
|
||||
mask = _maskStack.back();
|
||||
func = StencilFunc::EQUAL;
|
||||
failOp = StencilOp::KEEP;
|
||||
ref = getStencilRef();
|
||||
stencilMask = ref;
|
||||
writeMask = getWriteMask();
|
||||
}
|
||||
else {
|
||||
if (_stage == Stage::CLEAR) {
|
||||
mask = _maskStack.back();
|
||||
func = StencilFunc::NEVER;
|
||||
failOp = mask ? StencilOp::REPLACE : StencilOp::ZERO;
|
||||
ref = getWriteMask();
|
||||
stencilMask = ref;
|
||||
writeMask = ref;
|
||||
}
|
||||
else if (_stage == Stage::ENTER_LEVEL) {
|
||||
mask = _maskStack.back();
|
||||
// Fill stencil mask
|
||||
func = StencilFunc::NEVER;
|
||||
failOp = mask ? StencilOp::ZERO : StencilOp::REPLACE;
|
||||
ref = getWriteMask();
|
||||
stencilMask = ref;
|
||||
writeMask = ref;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pass : passes) {
|
||||
pass->setStencilFront(func, ref, stencilMask, failOp, zFailOp, zPassOp, writeMask);
|
||||
pass->setStencilBack(func, ref, stencilMask, failOp, zFailOp, zPassOp, writeMask);
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
|
||||
void StencilManager::pushMask (bool mask)
|
||||
{
|
||||
if (_maskStack.size() + 1 > _maxLevel)
|
||||
{
|
||||
cocos2d::log("StencilManager:pushMask _maxLevel:%d is out of range", _maxLevel);
|
||||
}
|
||||
_maskStack.push_back(mask);
|
||||
}
|
||||
|
||||
void StencilManager::clear ()
|
||||
{
|
||||
_stage = Stage::CLEAR;
|
||||
}
|
||||
|
||||
void StencilManager::enterLevel ()
|
||||
{
|
||||
_stage = Stage::ENTER_LEVEL;
|
||||
}
|
||||
|
||||
void StencilManager::enableMask ()
|
||||
{
|
||||
_stage = Stage::ENABLED;
|
||||
}
|
||||
|
||||
void StencilManager::exitMask ()
|
||||
{
|
||||
if (_maskStack.size() == 0) {
|
||||
cocos2d::log("StencilManager:exitMask _maskStack:%zu size is 0", _maskStack.size());
|
||||
}
|
||||
_maskStack.pop_back();
|
||||
if (_maskStack.size() == 0) {
|
||||
_stage = Stage::DISABLED;
|
||||
}
|
||||
else {
|
||||
_stage = Stage::ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t StencilManager::getWriteMask ()
|
||||
{
|
||||
return 0x01 << (_maskStack.size() - 1);
|
||||
}
|
||||
|
||||
uint8_t StencilManager::getExitWriteMask ()
|
||||
{
|
||||
return 0x01 << _maskStack.size();
|
||||
}
|
||||
|
||||
uint32_t StencilManager::getStencilRef ()
|
||||
{
|
||||
int32_t result = 0;
|
||||
size_t size = _maskStack.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result += (0x01 << i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t StencilManager::getInvertedRef ()
|
||||
{
|
||||
int32_t result = 0;
|
||||
size_t size = _maskStack.size();
|
||||
for (int i = 0; i < size - 1; ++i)
|
||||
{
|
||||
result += (0x01 << i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
113
cocos2d-x/cocos/renderer/scene/StencilManager.hpp
Normal file
113
cocos2d-x/cocos/renderer/scene/StencilManager.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/****************************************************************************
|
||||
LICENSING AGREEMENT
|
||||
|
||||
Xiamen Yaji Software Co., Ltd., (the “Licensor”) grants the user (the “Licensee”) non-exclusive and non-transferable rights to use the software according to the following conditions:
|
||||
a. The Licensee shall pay royalties to the Licensor, and the amount of those royalties and the payment method are subject to separate negotiations between the parties.
|
||||
b. The software is licensed for use rather than sold, and the Licensor reserves all rights over the software that are not expressly granted (whether by implication, reservation or prohibition).
|
||||
c. The open source codes contained in the software are subject to the MIT Open Source Licensing Agreement (see the attached for the details);
|
||||
d. The Licensee acknowledges and consents to the possibility that errors may occur during the operation of the software for one or more technical reasons, and the Licensee shall take precautions and prepare remedies for such events. In such circumstance, the Licensor shall provide software patches or updates according to the agreement between the two parties. The Licensor will not assume any liability beyond the explicit wording of this Licensing Agreement.
|
||||
e. Where the Licensor must assume liability for the software according to relevant laws, the Licensor’s entire liability is limited to the annual royalty payable by the Licensee.
|
||||
f. The Licensor owns the portions listed in the root directory and subdirectory (if any) in the software and enjoys the intellectual property rights over those portions. As for the portions owned by the Licensor, the Licensee shall not:
|
||||
- i. Bypass or avoid any relevant technical protection measures in the products or services;
|
||||
- ii. Release the source codes to any other parties;
|
||||
- iii. Disassemble, decompile, decipher, attack, emulate, exploit or reverse-engineer these portion of code;
|
||||
- iv. Apply it to any third-party products or services without Licensor’s permission;
|
||||
- v. Publish, copy, rent, lease, sell, export, import, distribute or lend any products containing these portions of code;
|
||||
- vi. Allow others to use any services relevant to the technology of these codes;
|
||||
- vii. Conduct any other act beyond the scope of this Licensing Agreement.
|
||||
g. This Licensing Agreement terminates immediately if the Licensee breaches this Agreement. The Licensor may claim compensation from the Licensee where the Licensee’s breach causes any damage to the Licensor.
|
||||
h. The laws of the People's Republic of China apply to this Licensing Agreement.
|
||||
i. This Agreement is made in both Chinese and English, and the Chinese version shall prevail the event of conflict.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include "../../base/CCVector.h"
|
||||
#include "renderer/EffectVariant.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
// Stage types
|
||||
enum class Stage{
|
||||
// Stencil disabled
|
||||
DISABLED = 0,
|
||||
// Clear stencil buffer
|
||||
CLEAR = 1,
|
||||
// Entering a new level, should handle new stencil
|
||||
ENTER_LEVEL = 2,
|
||||
// In content
|
||||
ENABLED = 3,
|
||||
// Exiting a level, should restore old stencil or disable
|
||||
EXIT_LEVEL = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* The stencil manager post process the Effect in Model to make them apply correct stencil states
|
||||
* After activated a stencil mask and before desactivated it, all Models committed in between should apply the stencil's states in the Pass of Effect.
|
||||
* This is a singleton class mainly used by ModelBatcher.
|
||||
*/
|
||||
class StencilManager
|
||||
{
|
||||
public:
|
||||
StencilManager();
|
||||
~StencilManager();
|
||||
/**
|
||||
* Reset all states
|
||||
*/
|
||||
void reset();
|
||||
/**
|
||||
* Apply correct stencil states to the Effect
|
||||
*/
|
||||
EffectVariant* handleEffect(EffectVariant* effect);
|
||||
/**
|
||||
* Add a mask to the stack
|
||||
*/
|
||||
void pushMask(bool mask);
|
||||
/**
|
||||
* Stage for clearing the stencil buffer for the last mask
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* Enters a new mask level, this stage is for drawing the stencil ref to the stencil buffer.
|
||||
*/
|
||||
void enterLevel();
|
||||
/**
|
||||
* Enables the current mask, this stage is for applying stencil states defined by the current mask.
|
||||
*/
|
||||
void enableMask();
|
||||
/**
|
||||
* Exits a mask level
|
||||
*/
|
||||
void exitMask();
|
||||
uint8_t getWriteMask();
|
||||
uint8_t getExitWriteMask();
|
||||
uint32_t getStencilRef();
|
||||
uint32_t getInvertedRef();
|
||||
|
||||
static StencilManager* getInstance()
|
||||
{
|
||||
if (_instance == nullptr)
|
||||
{
|
||||
_instance = new StencilManager;
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
private:
|
||||
const int _maxLevel = 8;
|
||||
std::vector<bool> _maskStack;
|
||||
Stage _stage;
|
||||
static StencilManager* _instance;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
285
cocos2d-x/cocos/renderer/scene/assembler/Assembler.cpp
Normal file
285
cocos2d-x/cocos/renderer/scene/assembler/Assembler.cpp
Normal file
@@ -0,0 +1,285 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Assembler.hpp"
|
||||
|
||||
#include "../NodeProxy.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
#include "../MeshBuffer.hpp"
|
||||
#include "../../renderer/Scene.h"
|
||||
#include "math/CCMath.h"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
#include "cocos/scripting/js-bindings/manual/jsb_conversions.hpp"
|
||||
#include "cocos/scripting/js-bindings/auto/jsb_renderer_auto.hpp"
|
||||
#include "../RenderFlow.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Assembler::IARenderData::IARenderData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Assembler::IARenderData::IARenderData(const IARenderData& o)
|
||||
{
|
||||
meshIndex = o.meshIndex;
|
||||
verticesStart = o.verticesStart;
|
||||
verticesCount = o.verticesCount;
|
||||
indicesStart = o.indicesStart;
|
||||
indicesCount = o.indicesCount;
|
||||
setEffect(o.getEffect());
|
||||
}
|
||||
|
||||
Assembler::IARenderData::~IARenderData()
|
||||
{
|
||||
CC_SAFE_RELEASE(_effect);
|
||||
}
|
||||
|
||||
void Assembler::IARenderData::setEffect(EffectVariant* effect)
|
||||
{
|
||||
if (effect == _effect) return;
|
||||
CC_SAFE_RELEASE(_effect);
|
||||
_effect = effect;
|
||||
CC_SAFE_RETAIN(_effect);
|
||||
}
|
||||
|
||||
EffectVariant* Assembler::IARenderData::getEffect() const
|
||||
{
|
||||
return _effect;
|
||||
}
|
||||
|
||||
Assembler::Assembler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Assembler::~Assembler()
|
||||
{
|
||||
CC_SAFE_RELEASE_NULL(_datas);
|
||||
CC_SAFE_RELEASE(_vfmt);
|
||||
}
|
||||
|
||||
void Assembler::updateMeshIndex(std::size_t iaIndex, int meshIndex)
|
||||
{
|
||||
if (iaIndex >= _iaDatas.size())
|
||||
{
|
||||
_iaDatas.resize(iaIndex + 1);
|
||||
}
|
||||
IARenderData& ia = _iaDatas[iaIndex];
|
||||
ia.meshIndex = meshIndex;
|
||||
}
|
||||
|
||||
void Assembler::updateIndicesRange(std::size_t iaIndex, int start, int count)
|
||||
{
|
||||
if (iaIndex >= _iaDatas.size())
|
||||
{
|
||||
_iaDatas.resize(iaIndex + 1);
|
||||
}
|
||||
IARenderData& ia = _iaDatas[iaIndex];
|
||||
ia.indicesStart = start;
|
||||
ia.indicesCount = count;
|
||||
}
|
||||
|
||||
void Assembler::updateVerticesRange(std::size_t iaIndex, int start, int count)
|
||||
{
|
||||
if (iaIndex >= _iaDatas.size())
|
||||
{
|
||||
_iaDatas.resize(iaIndex + 1);
|
||||
}
|
||||
IARenderData& ia = _iaDatas[iaIndex];
|
||||
ia.verticesStart = start;
|
||||
ia.verticesCount = count;
|
||||
|
||||
enableDirty(AssemblerBase::VERTICES_OPACITY_CHANGED);
|
||||
}
|
||||
|
||||
void Assembler::updateEffect(std::size_t iaIndex, EffectVariant* effect)
|
||||
{
|
||||
if (iaIndex >= _iaDatas.size())
|
||||
{
|
||||
_iaDatas.resize(iaIndex + 1);
|
||||
}
|
||||
IARenderData& ia = _iaDatas[iaIndex];
|
||||
ia.setEffect(effect);
|
||||
}
|
||||
|
||||
void Assembler::reset()
|
||||
{
|
||||
_iaDatas.clear();
|
||||
}
|
||||
|
||||
void Assembler::handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
batcher->commit(node, this, node->getCullingMask());
|
||||
}
|
||||
|
||||
void Assembler::fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index)
|
||||
{
|
||||
if(!_datas || !_vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = batcher->getBuffer(_vfmt);
|
||||
|
||||
const IARenderData& ia = _iaDatas[index];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : index;
|
||||
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CCASSERT(data->getVBytes() % _bytesPerVertex == 0, "Assembler::fillBuffers vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
uint32_t indexCount = ia.indicesCount >= 0 ? (uint32_t)ia.indicesCount : (uint32_t)data->getIBytes() / sizeof(unsigned short);
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(vertexCount, indexCount);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
uint32_t vertexOffset = vertexId - vertexStart;
|
||||
uint32_t num = _vfPos->num;
|
||||
|
||||
float* worldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(worldVerts, data->getVertices() + vertexStart * _bytesPerVertex, vertexCount * _bytesPerVertex);
|
||||
|
||||
// Calculate vertices world positions
|
||||
if (!_useModel && !_ignoreWorldMatrix)
|
||||
{
|
||||
size_t dataPerVertex = _bytesPerVertex / sizeof(float);
|
||||
float* ptrPos = worldVerts + _posOffset;
|
||||
auto& worldMat = node->getWorldMatrix();
|
||||
|
||||
switch (num) {
|
||||
// Vertex is X Y Z Format
|
||||
case 3:
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
((cocos2d::Vec3*)ptrPos)->transformMat4(*((cocos2d::Vec3*)ptrPos), worldMat);
|
||||
ptrPos += dataPerVertex;
|
||||
}
|
||||
break;
|
||||
// Vertex is X Y Format
|
||||
case 2:
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
float z = ptrPos[2];
|
||||
ptrPos[2] = 0;
|
||||
worldMat.transformPoint((cocos2d::Vec3*)ptrPos);
|
||||
ptrPos[2] = z;
|
||||
ptrPos += dataPerVertex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* indices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dst = buffer->iData;
|
||||
for (auto i = 0, j = ia.indicesStart; i < indexCount; ++i, ++j)
|
||||
{
|
||||
dst[indexId++] = vertexOffset + indices[j];
|
||||
}
|
||||
}
|
||||
|
||||
void Assembler::setVertexFormat(VertexFormat* vfmt)
|
||||
{
|
||||
if (_vfmt == vfmt) return;
|
||||
CC_SAFE_RETAIN(vfmt);
|
||||
CC_SAFE_RELEASE(_vfmt);
|
||||
_vfmt = vfmt;
|
||||
if (_vfmt)
|
||||
{
|
||||
_bytesPerVertex = _vfmt->getBytes();
|
||||
_vfPos = _vfmt->getElement(ATTRIB_NAME_POSITION_HASH);
|
||||
_posOffset = _vfPos->offset / 4;
|
||||
_vfColor = _vfmt->getElement(ATTRIB_NAME_COLOR_HASH);
|
||||
if (_vfColor != nullptr)
|
||||
{
|
||||
_alphaOffset = _vfColor->offset + 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Assembler::setRenderDataList(RenderDataList* datas)
|
||||
{
|
||||
if (_datas == datas) return;
|
||||
CC_SAFE_RELEASE(_datas);
|
||||
_datas = datas;
|
||||
CC_SAFE_RETAIN(_datas);
|
||||
}
|
||||
|
||||
void Assembler::updateOpacity(std::size_t index, uint8_t opacity)
|
||||
{
|
||||
// has no color info in vertex buffer
|
||||
if(!_vfColor || !_datas || !_vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const IARenderData& ia = _iaDatas[index];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : index;
|
||||
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CCASSERT(data->getVBytes() % _bytesPerVertex == 0, "Assembler::updateOpacity vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
|
||||
size_t dataPerVertex = _bytesPerVertex / sizeof(uint8_t);
|
||||
uint8_t* ptrAlpha = (uint8_t*)data->getVertices() + _alphaOffset;
|
||||
const Vector<Pass*>& passes = ia.getEffect()->getPasses();
|
||||
if (passes.at(0)->getBlendSrc() == BlendFactor::ONE)
|
||||
{
|
||||
float alpha = opacity / 255.0;
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
*(ptrAlpha-1) *= alpha;
|
||||
*(ptrAlpha-2) *= alpha;
|
||||
*(ptrAlpha-3) *= alpha;
|
||||
|
||||
*ptrAlpha = opacity;
|
||||
ptrAlpha += dataPerVertex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
*ptrAlpha = opacity;
|
||||
ptrAlpha += dataPerVertex;
|
||||
}
|
||||
}
|
||||
|
||||
*_dirty &= ~VERTICES_OPACITY_CHANGED;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
202
cocos2d-x/cocos/renderer/scene/assembler/Assembler.hpp
Normal file
202
cocos2d-x/cocos/renderer/scene/assembler/Assembler.hpp
Normal file
@@ -0,0 +1,202 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include "AssemblerBase.hpp"
|
||||
#include "../MeshBuffer.hpp"
|
||||
#include "math/CCMath.h"
|
||||
#include "../../renderer/Effect.h"
|
||||
#include "RenderDataList.hpp"
|
||||
#include "../../renderer/EffectVariant.hpp"
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
class HandleObject;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
class ModelBatcher;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
class Assembler : public AssemblerBase
|
||||
{
|
||||
public:
|
||||
|
||||
class IARenderData {
|
||||
public:
|
||||
IARenderData();
|
||||
IARenderData(const IARenderData& o);
|
||||
~IARenderData();
|
||||
void setEffect(EffectVariant* effect);
|
||||
EffectVariant* getEffect() const;
|
||||
private:
|
||||
EffectVariant* _effect = nullptr;
|
||||
public:
|
||||
int meshIndex = -1;
|
||||
int verticesStart = 0;
|
||||
int verticesCount = -1;
|
||||
int indicesStart = 0;
|
||||
int indicesCount = -1;
|
||||
};
|
||||
|
||||
Assembler();
|
||||
virtual ~Assembler();
|
||||
/*
|
||||
* @brief Commit the current render handle to ModelBatcher
|
||||
*/
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
/*
|
||||
* @brief Do nothing
|
||||
*/
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override {}
|
||||
/*
|
||||
* @brief before fill buffers handle
|
||||
*/
|
||||
virtual void beforeFillBuffers(std::size_t index) {}
|
||||
/*
|
||||
* @brief Fills render data in given index to the MeshBuffer
|
||||
* @param[in] buffer The shared mesh buffer
|
||||
* @param[in] index The index of render data to be updated
|
||||
* @param[in] node
|
||||
*/
|
||||
virtual void fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index);
|
||||
|
||||
/**
|
||||
* @brief Sets IArenderDataList
|
||||
*/
|
||||
virtual void setRenderDataList(RenderDataList* datas);
|
||||
|
||||
/**
|
||||
* @brief Gets the vertex format.
|
||||
*/
|
||||
VertexFormat* getVertexFormat() const { return _vfmt; };
|
||||
/**
|
||||
* @brief Sets the vertex format.
|
||||
*/
|
||||
virtual void setVertexFormat(VertexFormat* vfmt);
|
||||
|
||||
/*
|
||||
* @brief Update local render buffer opacity
|
||||
* @param[in] index The index of render data to be updated
|
||||
* @param[in] opacity Inherit opacity
|
||||
*/
|
||||
virtual void updateOpacity(std::size_t index, uint8_t opacity);
|
||||
|
||||
/**
|
||||
* @brief ignore opacity flag, it will always not update vertices opacity
|
||||
*/
|
||||
void ignoreOpacityFlag() { _ignoreOpacityFlag = true; }
|
||||
|
||||
/**
|
||||
* @brief Is ignore opacity.
|
||||
* @return _ignoreOpacityFlag
|
||||
*/
|
||||
bool isIgnoreOpacityFlag() { return _ignoreOpacityFlag; }
|
||||
|
||||
/**
|
||||
* @brief Enable ignore world matrix.
|
||||
*/
|
||||
void ignoreWorldMatrix() { _ignoreWorldMatrix = true; }
|
||||
|
||||
/**
|
||||
* @brief Is ignore world matrix.
|
||||
* @return _opacityAlwaysDirty
|
||||
*/
|
||||
bool isIgnoreWorldMatrix() { return _ignoreWorldMatrix; }
|
||||
|
||||
/**
|
||||
* @brief Updates mesh index
|
||||
*/
|
||||
void updateMeshIndex(std::size_t iaIndex, int meshIndex);
|
||||
/**
|
||||
* @brief Updates indices range
|
||||
*/
|
||||
void updateIndicesRange(std::size_t iaIndex, int start, int count);
|
||||
|
||||
/**
|
||||
* @brief Updates vertices range
|
||||
*/
|
||||
void updateVerticesRange(std::size_t iaIndex, int start, int count);
|
||||
|
||||
/**
|
||||
* @brief Update the material for the given index.
|
||||
* @param[in] iaIndex Render data index.
|
||||
* @param[in] effect Effect pointer.
|
||||
*/
|
||||
virtual void updateEffect(std::size_t iaIndex, EffectVariant* effect);
|
||||
|
||||
/**
|
||||
* @brief Resets ia data.
|
||||
*/
|
||||
virtual void reset() override;
|
||||
|
||||
/**
|
||||
* @brief Gets the material for the given index.
|
||||
* @param[in] index Render data index.
|
||||
* @return Effect pointer.
|
||||
*/
|
||||
inline EffectVariant* getEffect(std::size_t index) const
|
||||
{
|
||||
if (index >= _iaDatas.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return _iaDatas[index].getEffect();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets Effect count.
|
||||
* @return Count.
|
||||
*/
|
||||
inline std::size_t getIACount() const
|
||||
{
|
||||
return _iaDatas.size();
|
||||
}
|
||||
protected:
|
||||
RenderDataList* _datas = nullptr;
|
||||
std::vector<IARenderData> _iaDatas;
|
||||
|
||||
uint32_t _bytesPerVertex = 0;
|
||||
size_t _posOffset = 0;
|
||||
size_t _alphaOffset = 0;
|
||||
VertexFormat* _vfmt = nullptr;
|
||||
const VertexFormat::Element* _vfPos = nullptr;
|
||||
const VertexFormat::Element* _vfColor = nullptr;
|
||||
|
||||
bool _ignoreWorldMatrix = false;
|
||||
bool _ignoreOpacityFlag = false;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
69
cocos2d-x/cocos/renderer/scene/assembler/AssemblerBase.cpp
Normal file
69
cocos2d-x/cocos/renderer/scene/assembler/AssemblerBase.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "AssemblerBase.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
AssemblerBase::AssemblerBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AssemblerBase::~AssemblerBase()
|
||||
{
|
||||
if (_jsDirty)
|
||||
{
|
||||
_jsDirty->unroot();
|
||||
_jsDirty->decRef();
|
||||
_jsDirty = nullptr;
|
||||
}
|
||||
_dirty = nullptr;
|
||||
_dirtyLen = 0;
|
||||
|
||||
clearCustomWorldMatirx();
|
||||
}
|
||||
|
||||
void AssemblerBase::setDirty(se_object_ptr jsDirty)
|
||||
{
|
||||
if (_jsDirty == jsDirty) return;
|
||||
|
||||
if (_jsDirty)
|
||||
{
|
||||
_jsDirty->unroot();
|
||||
_jsDirty->decRef();
|
||||
_jsDirty = nullptr;
|
||||
}
|
||||
|
||||
if (jsDirty == nullptr) return;
|
||||
|
||||
_jsDirty = jsDirty;
|
||||
_jsDirty->root();
|
||||
_jsDirty->incRef();
|
||||
_dirty = nullptr;
|
||||
_dirtyLen = 0;
|
||||
_jsDirty->getTypedArrayData((uint8_t**)&_dirty, &_dirtyLen);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
180
cocos2d-x/cocos/renderer/scene/assembler/AssemblerBase.hpp
Normal file
180
cocos2d-x/cocos/renderer/scene/assembler/AssemblerBase.hpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include <stdint.h>
|
||||
#include "base/CCVector.h"
|
||||
#include "../../renderer/Effect.h"
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
#include "math/Mat4.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
class ModelBatcher;
|
||||
class Scene;
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Base class for all assembler
|
||||
* A assembler could take actions during node visit process, before and after all children visit.
|
||||
*/
|
||||
class AssemblerBase: public cocos2d::Ref
|
||||
{
|
||||
public:
|
||||
|
||||
enum AssemblerFlag {
|
||||
VERTICES_OPACITY_CHANGED = 1 << 0,
|
||||
VERTICES_DIRTY = 1 << 1,
|
||||
};
|
||||
|
||||
AssemblerBase();
|
||||
|
||||
virtual ~AssemblerBase();
|
||||
|
||||
/**
|
||||
* @brief Callback which will be invoked before visiting child nodes.
|
||||
* @param[in] node The node being processed.
|
||||
* @param[in] batcher
|
||||
* @param[in] scene
|
||||
*/
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) {}
|
||||
/**
|
||||
* @brief Callback which will be invoked after visiting child nodes.
|
||||
* @param[in] node The node being processed.
|
||||
* @param[in] batcher
|
||||
* @param[in] scene
|
||||
*/
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) {}
|
||||
|
||||
/**
|
||||
* @brief Gets whether the current handle should use model matrix uniform during rendering
|
||||
*/
|
||||
bool getUseModel() const
|
||||
{
|
||||
return _useModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets whether the current handle should use model matrix uniform during rendering
|
||||
*/
|
||||
void setUseModel(bool useModel)
|
||||
{
|
||||
_useModel = useModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets custom world matrix
|
||||
*/
|
||||
const cocos2d::Mat4* getCustomWorldMatrix() const
|
||||
{
|
||||
return _worldMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets custom world matrix
|
||||
*/
|
||||
void setCustomWorldMatrix(const cocos2d::Mat4& matrix)
|
||||
{
|
||||
if (!_worldMatrix)
|
||||
{
|
||||
_worldMatrix = new cocos2d::Mat4();
|
||||
}
|
||||
*_worldMatrix = matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear custom world matrix
|
||||
*/
|
||||
void clearCustomWorldMatirx()
|
||||
{
|
||||
if (_worldMatrix)
|
||||
{
|
||||
delete _worldMatrix;
|
||||
_worldMatrix = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sync script dirty flag.
|
||||
*/
|
||||
void setDirty(se_object_ptr jsDirty);
|
||||
|
||||
/**
|
||||
* @brief Changes dirty flag.
|
||||
*/
|
||||
void enableDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
*_dirty |= flag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes dirty flag.
|
||||
*/
|
||||
void disableDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
*_dirty &= ~flag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Is flag dirty.
|
||||
*/
|
||||
bool isDirty(uint32_t flag)
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
return *_dirty & flag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets data.
|
||||
*/
|
||||
virtual void reset() {}
|
||||
protected:
|
||||
se::Object* _jsDirty = nullptr;
|
||||
uint32_t* _dirty = nullptr;
|
||||
std::size_t _dirtyLen = 0;
|
||||
|
||||
bool _useModel = false;
|
||||
cocos2d::Mat4* _worldMatrix = nullptr;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
160
cocos2d-x/cocos/renderer/scene/assembler/AssemblerSprite.cpp
Normal file
160
cocos2d-x/cocos/renderer/scene/assembler/AssemblerSprite.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "AssemblerSprite.hpp"
|
||||
#include "../RenderFlow.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
AssemblerSprite::AssemblerSprite()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AssemblerSprite::~AssemblerSprite()
|
||||
{
|
||||
if(_localObj != nullptr)
|
||||
{
|
||||
_localObj->unroot();
|
||||
_localObj->decRef();
|
||||
_localObj = nullptr;
|
||||
_localData = nullptr;
|
||||
_localLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblerSprite::setLocalData(se_object_ptr localData)
|
||||
{
|
||||
if (!localData || localData == _localObj) return;
|
||||
if (_localObj)
|
||||
{
|
||||
_localObj->unroot();
|
||||
_localObj->decRef();
|
||||
}
|
||||
_localObj = localData;
|
||||
_localObj->root();
|
||||
_localObj->incRef();
|
||||
_localData = nullptr;
|
||||
_localLen = 0;
|
||||
_localObj->getTypedArrayData((uint8_t**)&_localData, (std::size_t*)&_localLen);
|
||||
}
|
||||
|
||||
void AssemblerSprite::fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index)
|
||||
{
|
||||
if(!_datas || !_vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= _iaDatas.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = batcher->getBuffer(_vfmt);
|
||||
|
||||
const IARenderData& ia = _iaDatas[index];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : index;
|
||||
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CCASSERT(data->getVBytes() % _bytesPerVertex == 0, "AssemblerSprite::fillBuffers vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
uint32_t indexCount = ia.indicesCount >= 0 ? (uint32_t)ia.indicesCount : (uint32_t)data->getIBytes() / sizeof(unsigned short);
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(vertexCount, indexCount);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
uint32_t vertexOffset = vertexId - vertexStart;
|
||||
|
||||
if (*_dirty & VERTICES_DIRTY || node->isDirty(RenderFlow::WORLD_TRANSFORM_CHANGED | RenderFlow::NODE_OPACITY_CHANGED))
|
||||
{
|
||||
generateWorldVertices();
|
||||
calculateWorldVertices(node->getWorldMatrix());
|
||||
}
|
||||
|
||||
float* dstWorldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(dstWorldVerts, data->getVertices() + vertexStart * _bytesPerVertex, vertexCount * _bytesPerVertex);
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* srcIndices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dstIndices = buffer->iData;
|
||||
for (auto i = 0, j = ia.indicesStart; i < indexCount; ++i, ++j)
|
||||
{
|
||||
dstIndices[indexId++] = vertexOffset + srcIndices[j];
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblerSprite::calculateWorldVertices(const Mat4& worldMat)
|
||||
{
|
||||
if(!_datas || !_vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t num = _vfPos->num;
|
||||
size_t dataPerVertex = _bytesPerVertex / sizeof(float);
|
||||
|
||||
for (std::size_t iaIdx = 0, iaCount = _iaDatas.size(); iaIdx < iaCount; iaIdx++)
|
||||
{
|
||||
const IARenderData& ia = _iaDatas[iaIdx];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : iaIdx;
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data) continue;
|
||||
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
float* srcWorldVerts = (float*)(data->getVertices() + vertexStart * _bytesPerVertex) + _posOffset;
|
||||
|
||||
switch (num) {
|
||||
case 3:
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
((cocos2d::Vec3*)srcWorldVerts)->transformMat4(*((cocos2d::Vec3*)srcWorldVerts), worldMat);
|
||||
srcWorldVerts += dataPerVertex;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (uint32_t i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
float z = srcWorldVerts[2];
|
||||
srcWorldVerts[2] = 0;
|
||||
worldMat.transformPoint((cocos2d::Vec3*)srcWorldVerts);
|
||||
srcWorldVerts[2] = z;
|
||||
srcWorldVerts += dataPerVertex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*_dirty &= ~VERTICES_DIRTY;
|
||||
}
|
||||
RENDERER_END
|
||||
48
cocos2d-x/cocos/renderer/scene/assembler/AssemblerSprite.hpp
Normal file
48
cocos2d-x/cocos/renderer/scene/assembler/AssemblerSprite.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
#include "Assembler.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class AssemblerSprite: public Assembler
|
||||
{
|
||||
public:
|
||||
AssemblerSprite();
|
||||
virtual ~AssemblerSprite();
|
||||
virtual void setLocalData(se_object_ptr localData);
|
||||
virtual void fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index) override;
|
||||
virtual void calculateWorldVertices(const Mat4& worldMat);
|
||||
virtual void generateWorldVertices() {};
|
||||
protected:
|
||||
se::Object* _localObj = nullptr;
|
||||
float* _localData = nullptr;
|
||||
std::size_t _localLen = 0;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
133
cocos2d-x/cocos/renderer/scene/assembler/CustomAssembler.cpp
Normal file
133
cocos2d-x/cocos/renderer/scene/assembler/CustomAssembler.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "CustomAssembler.hpp"
|
||||
#include "../NodeProxy.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
#include "../../renderer/Scene.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
CustomAssembler::CustomAssembler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CustomAssembler::~CustomAssembler()
|
||||
{
|
||||
for (std::size_t i = 0, n = _iaPool.size(); i < n; i++)
|
||||
{
|
||||
auto ia = _iaPool[i];
|
||||
delete ia;
|
||||
}
|
||||
_iaPool.clear();
|
||||
}
|
||||
|
||||
void CustomAssembler::handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
batcher->commitIA(node, this, node->getCullingMask());
|
||||
}
|
||||
|
||||
void CustomAssembler::reset()
|
||||
{
|
||||
_iaCount = 0;
|
||||
for (auto it = _iaPool.begin(); it != _iaPool.end(); it++)
|
||||
{
|
||||
(*it)->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CustomAssembler::updateIARange(std::size_t index, int start, int count)
|
||||
{
|
||||
auto ia = adjustIA(index);
|
||||
if (!ia) return;
|
||||
|
||||
ia->setCount(count);
|
||||
ia->setStart(start);
|
||||
}
|
||||
|
||||
void CustomAssembler::updateIABuffer(std::size_t index, VertexBuffer* vb, IndexBuffer* ib)
|
||||
{
|
||||
auto ia = adjustIA(index);
|
||||
if (!ia) return;
|
||||
|
||||
ia->setVertexBuffer(vb);
|
||||
ia->setIndexBuffer(ib);
|
||||
}
|
||||
|
||||
InputAssembler* CustomAssembler::adjustIA(std::size_t index)
|
||||
{
|
||||
auto size = _iaPool.size();
|
||||
InputAssembler* ia = nullptr;
|
||||
if (index == size)
|
||||
{
|
||||
ia = new InputAssembler();
|
||||
_iaPool.push_back(ia);
|
||||
}
|
||||
else if (index < size)
|
||||
{
|
||||
ia = _iaPool[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
cocos2d::log("CustomAssembler:updateIA index:%zu is out of range", index);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto newIACount = index + 1;
|
||||
if (_iaCount < newIACount)
|
||||
{
|
||||
_iaCount = newIACount;
|
||||
}
|
||||
|
||||
return ia;
|
||||
}
|
||||
|
||||
InputAssembler* CustomAssembler::getIA(std::size_t index) const
|
||||
{
|
||||
if (index >= _iaCount)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return _iaPool[index];
|
||||
}
|
||||
|
||||
void CustomAssembler::updateEffect(std::size_t index, EffectVariant* effect)
|
||||
{
|
||||
auto size = _effects.size();
|
||||
if (index == size)
|
||||
{
|
||||
_effects.pushBack(effect);
|
||||
return;
|
||||
}
|
||||
else if (index < size)
|
||||
{
|
||||
_effects.replace(index, effect);
|
||||
return;
|
||||
}
|
||||
cocos2d::log("CustomAssembler:updateEffect index:%zu out of range", index);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
134
cocos2d-x/cocos/renderer/scene/assembler/CustomAssembler.hpp
Normal file
134
cocos2d-x/cocos/renderer/scene/assembler/CustomAssembler.hpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AssemblerBase.hpp"
|
||||
#include <vector>
|
||||
#include "../../renderer/InputAssembler.h"
|
||||
#include "../../renderer/EffectVariant.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
/**
|
||||
* @addtogroup scene
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Custom render handle base class
|
||||
* Render components that manages render buffer directly like spine, dragonBones should extend from this handle type.
|
||||
*/
|
||||
class CustomAssembler : public AssemblerBase
|
||||
{
|
||||
public:
|
||||
CustomAssembler();
|
||||
virtual ~CustomAssembler();
|
||||
|
||||
/**
|
||||
* @brief Updates InputAssembler indices range
|
||||
* @param[in] index InputAssembler index.
|
||||
* @param[in] start Indices buffer start pos
|
||||
* @param[in] count Indices count
|
||||
*/
|
||||
virtual void updateIARange(std::size_t index, int start, int count);
|
||||
/**
|
||||
* @brief Updates InputAssembler indices and vertices buffer
|
||||
* @param[in] index InputAssembler index.
|
||||
* @param[in] vb Vertices buffer pointer
|
||||
* @param[in] ib Indices buffer pointer
|
||||
*/
|
||||
virtual void updateIABuffer(std::size_t index, cocos2d::renderer::VertexBuffer* vb, cocos2d::renderer::IndexBuffer* ib);
|
||||
|
||||
/**
|
||||
* @brief Gets input assembler by index
|
||||
* @param[in] index.
|
||||
*/
|
||||
InputAssembler* getIA(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* @brief Gets input assembler count.
|
||||
* @return Count.
|
||||
*/
|
||||
virtual inline std::size_t getIACount() const
|
||||
{
|
||||
return _iaCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Commit the current render handle to ModelBatcher
|
||||
*/
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
/**
|
||||
* @brief Do nothing
|
||||
*/
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override {}
|
||||
/**
|
||||
* @brief Resets ia data.
|
||||
*/
|
||||
virtual void reset() override;
|
||||
/**
|
||||
* @brief Adjusts ia data.
|
||||
*/
|
||||
virtual InputAssembler* adjustIA(std::size_t index);
|
||||
|
||||
/**
|
||||
* @brief Update the material for the given index.
|
||||
* @param[in] index Render data index.
|
||||
* @param[in] effect Effect pointer.
|
||||
*/
|
||||
virtual void updateEffect(std::size_t index, EffectVariant* effect);
|
||||
|
||||
/**
|
||||
* @brief Gets the material for the given index.
|
||||
* @param[in] index Render data index.
|
||||
* @return Effect pointer.
|
||||
*/
|
||||
inline EffectVariant* getEffect(std::size_t index) const
|
||||
{
|
||||
if (index >= _effects.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return _effects.at(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears all effect.
|
||||
* @return Count.
|
||||
*/
|
||||
virtual void clearEffect()
|
||||
{
|
||||
_effects.clear();
|
||||
}
|
||||
protected:
|
||||
std::vector<cocos2d::renderer::InputAssembler*> _iaPool;
|
||||
cocos2d::Vector<EffectVariant*> _effects;
|
||||
std::size_t _iaCount = 0;
|
||||
};
|
||||
|
||||
// end of scene group
|
||||
/// @}
|
||||
|
||||
RENDERER_END
|
||||
91
cocos2d-x/cocos/renderer/scene/assembler/MaskAssembler.cpp
Normal file
91
cocos2d-x/cocos/renderer/scene/assembler/MaskAssembler.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MaskAssembler.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
#include "../StencilManager.hpp"
|
||||
#include "../../Macro.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
MaskAssembler::MaskAssembler()
|
||||
{
|
||||
}
|
||||
|
||||
MaskAssembler::~MaskAssembler()
|
||||
{
|
||||
CC_SAFE_RELEASE(_renderSubHandle);
|
||||
CC_SAFE_RELEASE(_clearSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::setRenderSubHandle(Assembler* renderSubHandle)
|
||||
{
|
||||
if (_renderSubHandle == renderSubHandle) return;
|
||||
CC_SAFE_RELEASE(_renderSubHandle);
|
||||
_renderSubHandle = renderSubHandle;
|
||||
CC_SAFE_RETAIN(_renderSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::setClearSubHandle(Assembler* clearSubHandle)
|
||||
{
|
||||
if (_clearSubHandle == clearSubHandle) return;
|
||||
CC_SAFE_RELEASE(_clearSubHandle);
|
||||
_clearSubHandle = clearSubHandle;
|
||||
CC_SAFE_RETAIN(_clearSubHandle);
|
||||
}
|
||||
|
||||
void MaskAssembler::handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
batcher->flush();
|
||||
batcher->flushIA();
|
||||
|
||||
StencilManager* instance = StencilManager::getInstance();
|
||||
instance->pushMask(_inverted);
|
||||
instance->clear();
|
||||
batcher->commit(node, _clearSubHandle, node->getCullingMask());
|
||||
batcher->flush();
|
||||
instance->enterLevel();
|
||||
|
||||
if (_imageStencil)
|
||||
{
|
||||
batcher->commit(node, this, node->getCullingMask());
|
||||
}
|
||||
else if (_renderSubHandle)
|
||||
{
|
||||
_renderSubHandle->handle(node, batcher, scene);
|
||||
}
|
||||
|
||||
batcher->flush();
|
||||
instance->enableMask();
|
||||
}
|
||||
|
||||
void MaskAssembler::postHandle(NodeProxy *node, ModelBatcher *batcher, Scene *scene)
|
||||
{
|
||||
batcher->flush();
|
||||
batcher->flushIA();
|
||||
batcher->setCurrentEffect(getEffect(0));
|
||||
StencilManager::getInstance()->exitMask();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
62
cocos2d-x/cocos/renderer/scene/assembler/MaskAssembler.hpp
Normal file
62
cocos2d-x/cocos/renderer/scene/assembler/MaskAssembler.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Assembler.hpp"
|
||||
#include "../MeshBuffer.hpp"
|
||||
#include "math/CCMath.h"
|
||||
#include "SimpleSprite2D.hpp"
|
||||
|
||||
class ModelBatcher;
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class MaskAssembler: public SimpleSprite2D
|
||||
{
|
||||
public:
|
||||
MaskAssembler();
|
||||
virtual ~MaskAssembler();
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
virtual void postHandle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
|
||||
void setMaskInverted(bool inverted) { _inverted = inverted; };
|
||||
bool getMaskInverted() { return _inverted; };
|
||||
|
||||
void setRenderSubHandle(Assembler* renderSubHandle);
|
||||
void setClearSubHandle(Assembler* clearSubHandle);
|
||||
|
||||
void setImageStencil(bool isImageStencil) { _imageStencil = isImageStencil; };
|
||||
|
||||
protected:
|
||||
bool _inverted = false;
|
||||
bool _imageStencil = false;
|
||||
|
||||
private:
|
||||
Assembler* _renderSubHandle = nullptr;
|
||||
Assembler* _clearSubHandle = nullptr;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
111
cocos2d-x/cocos/renderer/scene/assembler/MeshAssembler.cpp
Normal file
111
cocos2d-x/cocos/renderer/scene/assembler/MeshAssembler.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MeshAssembler.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
MeshAssembler::MeshAssembler()
|
||||
{
|
||||
_useModel = true;
|
||||
}
|
||||
|
||||
MeshAssembler::~MeshAssembler()
|
||||
{
|
||||
RENDERER_SAFE_RELEASE(_renderNode);
|
||||
}
|
||||
|
||||
void MeshAssembler::handle(NodeProxy *node, ModelBatcher *batcher, Scene *scene)
|
||||
{
|
||||
if (_renderNode != nullptr)
|
||||
{
|
||||
batcher->commitIA(_renderNode, this, node->getCullingMask());
|
||||
}
|
||||
else
|
||||
{
|
||||
batcher->commitIA(node, this, node->getCullingMask());
|
||||
}
|
||||
|
||||
batcher->flushIA();
|
||||
}
|
||||
|
||||
void MeshAssembler::setNode(NodeProxy* node)
|
||||
{
|
||||
if (_renderNode == node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_renderNode != nullptr)
|
||||
{
|
||||
_renderNode->release();
|
||||
}
|
||||
_renderNode = node;
|
||||
if (_renderNode != nullptr)
|
||||
{
|
||||
_renderNode->retain();
|
||||
}
|
||||
}
|
||||
|
||||
void MeshAssembler::updateIAData(std::size_t index, VertexFormat* vfmt, se_object_ptr vertices, se_object_ptr indices)
|
||||
{
|
||||
_datas.updateMesh(index, vertices, indices);
|
||||
auto data = _datas.getRenderData(index);
|
||||
|
||||
auto ia = adjustIA(index);
|
||||
|
||||
auto ib = ia->getIndexBuffer();
|
||||
if (!ib) {
|
||||
ib = new IndexBuffer();
|
||||
ib->autorelease();
|
||||
ib->init(DeviceGraphics::getInstance(), IndexFormat::UINT16, Usage::STATIC, data->getIndices(), data->getIBytes(), (uint32_t)data->getIBytes() / sizeof(unsigned short));
|
||||
ia->setIndexBuffer(ib);
|
||||
}
|
||||
else {
|
||||
ib->update(0, data->getIndices(), data->getIBytes());
|
||||
}
|
||||
|
||||
auto vb = ia->getVertexBuffer();
|
||||
if (!vb) {
|
||||
vb = new VertexBuffer();
|
||||
vb->autorelease();
|
||||
vb->init(DeviceGraphics::getInstance(), vfmt, Usage::STATIC, data->getVertices(), data->getVBytes(), (uint32_t)data->getVBytes() / vfmt->getBytes());
|
||||
ia->setVertexBuffer(vb);
|
||||
}
|
||||
else {
|
||||
vb->update(0, data->getVertices(), data->getVBytes());
|
||||
}
|
||||
|
||||
ia->setCount(ib->getCount());
|
||||
}
|
||||
|
||||
void MeshAssembler::reset()
|
||||
{
|
||||
CustomAssembler::reset();
|
||||
|
||||
_datas.clear();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
54
cocos2d-x/cocos/renderer/scene/assembler/MeshAssembler.hpp
Normal file
54
cocos2d-x/cocos/renderer/scene/assembler/MeshAssembler.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include "CustomAssembler.hpp"
|
||||
#include "../NodeProxy.hpp"
|
||||
#include "../../gfx/VertexFormat.h"
|
||||
#include "RenderDataList.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class MeshAssembler: public CustomAssembler
|
||||
{
|
||||
public:
|
||||
MeshAssembler();
|
||||
virtual ~MeshAssembler();
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
/**
|
||||
* @brief Sets the related node proxy which provids model matrix for render.
|
||||
*/
|
||||
void setNode(NodeProxy* node);
|
||||
void updateIAData(std::size_t index, VertexFormat* vfmt, se_object_ptr vertices, se_object_ptr indices);
|
||||
|
||||
virtual void reset() override;
|
||||
protected:
|
||||
NodeProxy* _renderNode = nullptr;
|
||||
RenderDataList _datas;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
|
||||
136
cocos2d-x/cocos/renderer/scene/assembler/Particle3DAssembler.cpp
Normal file
136
cocos2d-x/cocos/renderer/scene/assembler/Particle3DAssembler.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "Particle3DAssembler.hpp"
|
||||
#include "../NodeProxy.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
Particle3DAssembler::Particle3DAssembler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Particle3DAssembler::~Particle3DAssembler()
|
||||
{
|
||||
CC_SAFE_RELEASE(_trailVfmt);
|
||||
}
|
||||
|
||||
void Particle3DAssembler::setTrailVertexFormat(VertexFormat *vfmt)
|
||||
{
|
||||
if (_trailVfmt == vfmt) return;
|
||||
CC_SAFE_RETAIN(vfmt);
|
||||
CC_SAFE_RELEASE(_trailVfmt);
|
||||
_trailVfmt = vfmt;
|
||||
if (_trailVfmt)
|
||||
{
|
||||
_trailVertexBytes = _trailVfmt->getBytes();
|
||||
const VertexFormat::Element* vfPos = _vfmt->getElement(ATTRIB_NAME_POSITION_HASH);
|
||||
_trailPosOffset = vfPos->offset / 4;
|
||||
}
|
||||
}
|
||||
|
||||
void Particle3DAssembler::fillBuffer(NodeProxy *node, MeshBuffer *buffer, const IARenderData& ia, RenderData* data)
|
||||
{
|
||||
CCASSERT(data->getVBytes() % _bytesPerVertex == 0, "Assembler::fillBuffers vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _bytesPerVertex;
|
||||
uint32_t indexCount = ia.indicesCount >= 0 ? (uint32_t)ia.indicesCount : (uint32_t)data->getIBytes() / sizeof(unsigned short);
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(vertexCount, indexCount);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
uint32_t vertexOffset = vertexId - vertexStart;
|
||||
|
||||
float* worldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(worldVerts, data->getVertices() + vertexStart * _bytesPerVertex, vertexCount * _bytesPerVertex);
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* indices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dst = buffer->iData;
|
||||
for (auto i = 0, j = ia.indicesStart; i < indexCount; ++i, ++j)
|
||||
{
|
||||
dst[indexId++] = vertexOffset + indices[j];
|
||||
}
|
||||
}
|
||||
|
||||
void Particle3DAssembler::fillTrailBuffer(NodeProxy *node, MeshBuffer *buffer, const IARenderData& ia, RenderData* data)
|
||||
{
|
||||
CCASSERT(data->getVBytes() % _trailVertexBytes == 0, "Assembler::fillBuffers vertices data doesn't follow vertex format");
|
||||
uint32_t vertexCount = ia.verticesCount >= 0 ? (uint32_t)ia.verticesCount : (uint32_t)data->getVBytes() / _trailVertexBytes;
|
||||
uint32_t indexCount = ia.indicesCount >= 0 ? (uint32_t)ia.indicesCount : (uint32_t)data->getIBytes() / sizeof(unsigned short);
|
||||
uint32_t vertexStart = (uint32_t)ia.verticesStart;
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(vertexCount, indexCount);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
uint32_t vertexOffset = vertexId - vertexStart;
|
||||
|
||||
float* worldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(worldVerts, data->getVertices() + vertexStart * _trailVertexBytes, vertexCount * _trailVertexBytes);
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* indices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dst = buffer->iData;
|
||||
for (auto i = 0, j = ia.indicesStart; i < indexCount; ++i, ++j)
|
||||
{
|
||||
dst[indexId++] = vertexOffset + indices[j];
|
||||
}
|
||||
}
|
||||
|
||||
void Particle3DAssembler::fillBuffers(NodeProxy *node, ModelBatcher *batcher, std::size_t index)
|
||||
{
|
||||
VertexFormat* vfmt = index == 0 ? _vfmt : _trailVfmt;
|
||||
|
||||
if (!_datas || !vfmt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = batcher->getBuffer(vfmt);
|
||||
|
||||
const IARenderData& ia = _iaDatas[index];
|
||||
std::size_t meshIndex = ia.meshIndex >= 0 ? ia.meshIndex : index;
|
||||
|
||||
RenderData* data = _datas->getRenderData(meshIndex);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (index != 0)
|
||||
{
|
||||
fillTrailBuffer(node, buffer, ia, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
fillBuffer(node, buffer, ia, data);
|
||||
}
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Assembler.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class NodeProxy;
|
||||
class ModelBatcher;
|
||||
|
||||
enum class Space: uint8_t
|
||||
{
|
||||
WORLD = 0,
|
||||
LOCAL = 1,
|
||||
CUSTOM = 2
|
||||
};
|
||||
|
||||
class Particle3DAssembler: public Assembler
|
||||
{
|
||||
public:
|
||||
Particle3DAssembler();
|
||||
~Particle3DAssembler();
|
||||
|
||||
virtual void fillBuffers(NodeProxy *node, ModelBatcher *batcher, std::size_t index) override;
|
||||
void setTrailVertexFormat(VertexFormat* vfmt);
|
||||
void setTrailModuleEnable(bool enable) {_trailModuleEnable = enable;};
|
||||
|
||||
void setParticleSpace(Space space) {_particleSpace = space;};
|
||||
void setTrailSpace(Space space) {_trailSpace = space;};
|
||||
private:
|
||||
void fillBuffer(NodeProxy *node, MeshBuffer *buffer, const IARenderData& ia, RenderData* data);
|
||||
void fillTrailBuffer(NodeProxy *node, MeshBuffer *buffer, const IARenderData& ia, RenderData* data);
|
||||
|
||||
private:
|
||||
Space _particleSpace = Space::LOCAL;
|
||||
Space _trailSpace = Space::LOCAL;
|
||||
|
||||
uint32_t _trailVertexBytes = 0;
|
||||
size_t _trailPosOffset = 0;
|
||||
bool _trailModuleEnable = false;
|
||||
|
||||
VertexFormat* _trailVfmt = nullptr;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
126
cocos2d-x/cocos/renderer/scene/assembler/RenderData.cpp
Normal file
126
cocos2d-x/cocos/renderer/scene/assembler/RenderData.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderData.hpp"
|
||||
#include "../../renderer/Effect.h"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
RenderData::RenderData ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RenderData::RenderData (const RenderData& o)
|
||||
{
|
||||
setVertices(o._jsVertices);
|
||||
setIndices(o._jsIndices);
|
||||
}
|
||||
|
||||
RenderData::~RenderData ()
|
||||
{
|
||||
if(_jsVertices != nullptr)
|
||||
{
|
||||
_jsVertices->unroot();
|
||||
_jsVertices->decRef();
|
||||
_jsVertices = nullptr;
|
||||
_vertices = nullptr;
|
||||
_vBytes = 0;
|
||||
}
|
||||
|
||||
if(_jsIndices != nullptr)
|
||||
{
|
||||
_jsIndices->unroot();
|
||||
_jsIndices->decRef();
|
||||
_jsIndices = nullptr;
|
||||
_indices = nullptr;
|
||||
_iBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderData::setVertices (se::Object* jsVertices)
|
||||
{
|
||||
if (!jsVertices || jsVertices == _jsVertices) return;
|
||||
if (_jsVertices)
|
||||
{
|
||||
_jsVertices->unroot();
|
||||
_jsVertices->decRef();
|
||||
}
|
||||
_jsVertices = jsVertices;
|
||||
_jsVertices->root();
|
||||
_jsVertices->incRef();
|
||||
_vertices = nullptr;
|
||||
_vBytes = 0;
|
||||
_jsVertices->getTypedArrayData(&_vertices, (std::size_t*)&_vBytes);
|
||||
}
|
||||
|
||||
void RenderData::setIndices (se::Object* jsIndices)
|
||||
{
|
||||
if (!jsIndices || jsIndices == _jsIndices) return;
|
||||
if (_jsIndices)
|
||||
{
|
||||
_jsIndices->unroot();
|
||||
_jsIndices->decRef();
|
||||
}
|
||||
_jsIndices = jsIndices;
|
||||
_jsIndices->root();
|
||||
_jsIndices->incRef();
|
||||
_indices = nullptr;
|
||||
_iBytes = 0;
|
||||
_jsIndices->getTypedArrayData(&_indices, (std::size_t*)&_iBytes);
|
||||
}
|
||||
|
||||
uint8_t* RenderData::getVertices () const
|
||||
{
|
||||
return _vertices;
|
||||
}
|
||||
|
||||
uint8_t* RenderData::getIndices () const
|
||||
{
|
||||
return _indices;
|
||||
}
|
||||
|
||||
void RenderData::clear()
|
||||
{
|
||||
if(_jsVertices != nullptr)
|
||||
{
|
||||
_jsVertices->unroot();
|
||||
_jsVertices->decRef();
|
||||
_jsVertices = nullptr;
|
||||
}
|
||||
|
||||
if(_jsIndices != nullptr)
|
||||
{
|
||||
_jsIndices->unroot();
|
||||
_jsIndices->decRef();
|
||||
_jsIndices = nullptr;
|
||||
}
|
||||
|
||||
_vBytes = 0;
|
||||
_iBytes = 0;
|
||||
_vertices = nullptr;
|
||||
_indices = nullptr;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
66
cocos2d-x/cocos/renderer/scene/assembler/RenderData.hpp
Normal file
66
cocos2d-x/cocos/renderer/scene/assembler/RenderData.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Macro.h"
|
||||
#include "base/CCRef.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
class HandleObject;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class Effect;
|
||||
|
||||
class RenderData {
|
||||
public:
|
||||
RenderData ();
|
||||
RenderData (const RenderData& o);
|
||||
virtual ~RenderData ();
|
||||
|
||||
void setVertices (se::Object* jsVertices);
|
||||
void setIndices (se::Object* jsIndices);
|
||||
|
||||
uint8_t* getVertices () const;
|
||||
uint8_t* getIndices () const;
|
||||
|
||||
unsigned long getVBytes () { return _vBytes; }
|
||||
unsigned long getIBytes () { return _iBytes; }
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
unsigned long _vBytes = 0;
|
||||
unsigned long _iBytes = 0;
|
||||
uint8_t* _vertices = nullptr;
|
||||
uint8_t* _indices = nullptr;
|
||||
se::Object* _jsVertices = nullptr;
|
||||
se::Object* _jsIndices = nullptr;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
63
cocos2d-x/cocos/renderer/scene/assembler/RenderDataList.cpp
Normal file
63
cocos2d-x/cocos/renderer/scene/assembler/RenderDataList.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "RenderDataList.hpp"
|
||||
#include "cocos/scripting/js-bindings/jswrapper/SeApi.h"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
void RenderDataList::updateMesh(std::size_t index, se_object_ptr vertices, se_object_ptr indices)
|
||||
{
|
||||
if (index >= _datas.size())
|
||||
{
|
||||
_datas.resize(index + 1);
|
||||
}
|
||||
|
||||
se::ScriptEngine::getInstance()->clearException();
|
||||
se::AutoHandleScope hs;
|
||||
|
||||
RenderData& data = _datas[index];
|
||||
data.setVertices(vertices);
|
||||
data.setIndices(indices);
|
||||
}
|
||||
|
||||
RenderData* RenderDataList::getRenderData(std::size_t index)
|
||||
{
|
||||
if (index >= _datas.size())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return &_datas[index];
|
||||
}
|
||||
|
||||
void RenderDataList::clear()
|
||||
{
|
||||
for (auto it = _datas.begin(); it != _datas.end(); it++)
|
||||
{
|
||||
it->clear();
|
||||
}
|
||||
_datas.clear();
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
68
cocos2d-x/cocos/renderer/scene/assembler/RenderDataList.hpp
Normal file
68
cocos2d-x/cocos/renderer/scene/assembler/RenderDataList.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/CCRef.h"
|
||||
#include <vector>
|
||||
#include "RenderData.hpp"
|
||||
#include "scripting/js-bindings/jswrapper/Object.hpp"
|
||||
|
||||
namespace se {
|
||||
class Object;
|
||||
class HandleObject;
|
||||
}
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class RenderDataList: public cocos2d::Ref {
|
||||
public:
|
||||
RenderDataList () {}
|
||||
virtual ~RenderDataList() {}
|
||||
/**
|
||||
* @brief Update the mesh data for the given index.
|
||||
* @param[in] index Render data index.
|
||||
* @param[in] vertices Vertex data.
|
||||
* @param[in] indices Index data.
|
||||
*/
|
||||
void updateMesh(std::size_t index, se_object_ptr vertices, se_object_ptr indices);
|
||||
/**
|
||||
* @brief Gets the count of render datas
|
||||
* @return Count.
|
||||
*/
|
||||
std::size_t getMeshCount() const { return _datas.size(); };
|
||||
/**
|
||||
* @brief Gets IARenderData.
|
||||
* @return IARenderData.
|
||||
*/
|
||||
RenderData* getRenderData(std::size_t index);
|
||||
/**
|
||||
* @brief Resets all IARenderData.
|
||||
*/
|
||||
void clear();
|
||||
private:
|
||||
std::vector<RenderData> _datas;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
105
cocos2d-x/cocos/renderer/scene/assembler/SimpleSprite2D.cpp
Normal file
105
cocos2d-x/cocos/renderer/scene/assembler/SimpleSprite2D.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "SimpleSprite2D.hpp"
|
||||
#include "../RenderFlow.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
SimpleSprite2D::SimpleSprite2D()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SimpleSprite2D::~SimpleSprite2D()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SimpleSprite2D::fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index)
|
||||
{
|
||||
RenderData* data = _datas->getRenderData(0);
|
||||
if (!data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MeshBuffer* buffer = batcher->getBuffer(_vfmt);
|
||||
|
||||
// must retrieve offset before request
|
||||
auto& bufferOffset = buffer->request(4, 6);
|
||||
uint32_t vBufferOffset = bufferOffset.vByte / sizeof(float);
|
||||
uint32_t indexId = bufferOffset.index;
|
||||
uint32_t vertexId = bufferOffset.vertex;
|
||||
|
||||
if (*_dirty & VERTICES_DIRTY || node->isDirty(RenderFlow::WORLD_TRANSFORM_CHANGED | RenderFlow::NODE_OPACITY_CHANGED))
|
||||
{
|
||||
float vl = _localData[0],
|
||||
vr = _localData[2],
|
||||
vb = _localData[1],
|
||||
vt = _localData[3];
|
||||
|
||||
const Mat4& worldMat = node->getWorldMatrix();
|
||||
size_t dataPerVertex = _bytesPerVertex / sizeof(float);
|
||||
float* srcWorldVerts = (float*)data->getVertices();
|
||||
|
||||
// left bottom
|
||||
float u = srcWorldVerts[2];
|
||||
worldMat.transformVector(vl, vb, 0.0f, 1.0f, (cocos2d::Vec3*)srcWorldVerts);
|
||||
srcWorldVerts[2] = u;
|
||||
|
||||
// right bottom
|
||||
srcWorldVerts += dataPerVertex;
|
||||
u = srcWorldVerts[2];
|
||||
worldMat.transformVector(vr, vb, 0.0f, 1.0f, (cocos2d::Vec3*)srcWorldVerts);
|
||||
srcWorldVerts[2] = u;
|
||||
|
||||
// left top
|
||||
srcWorldVerts += dataPerVertex;
|
||||
u = srcWorldVerts[2];
|
||||
worldMat.transformVector(vl, vt, 0.0f, 1.0f, (cocos2d::Vec3*)srcWorldVerts);
|
||||
srcWorldVerts[2] = u;
|
||||
|
||||
// right top
|
||||
srcWorldVerts += dataPerVertex;
|
||||
u = srcWorldVerts[2];
|
||||
worldMat.transformVector(vr, vt, 0.0f, 1.0f, (cocos2d::Vec3*)srcWorldVerts);
|
||||
srcWorldVerts[2] = u;
|
||||
|
||||
*_dirty &= ~VERTICES_DIRTY;
|
||||
}
|
||||
|
||||
float* dstWorldVerts = buffer->vData + vBufferOffset;
|
||||
memcpy(dstWorldVerts, data->getVertices(), 4 * _bytesPerVertex);
|
||||
|
||||
// Copy index buffer with vertex offset
|
||||
uint16_t* srcIndices = (uint16_t*)data->getIndices();
|
||||
uint16_t* dstIndices = buffer->iData;
|
||||
for (auto i = 0, j = 0; i < 6; ++i, ++j)
|
||||
{
|
||||
dstIndices[indexId++] = vertexId + srcIndices[j];
|
||||
}
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
39
cocos2d-x/cocos/renderer/scene/assembler/SimpleSprite2D.hpp
Normal file
39
cocos2d-x/cocos/renderer/scene/assembler/SimpleSprite2D.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AssemblerSprite.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class SimpleSprite2D: public AssemblerSprite
|
||||
{
|
||||
public:
|
||||
SimpleSprite2D();
|
||||
virtual ~SimpleSprite2D();
|
||||
virtual void fillBuffers(NodeProxy* node, ModelBatcher* batcher, std::size_t index) override;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
80
cocos2d-x/cocos/renderer/scene/assembler/SimpleSprite3D.cpp
Normal file
80
cocos2d-x/cocos/renderer/scene/assembler/SimpleSprite3D.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "SimpleSprite3D.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
SimpleSprite3D::SimpleSprite3D()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SimpleSprite3D::~SimpleSprite3D()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SimpleSprite3D::generateWorldVertices()
|
||||
{
|
||||
RenderData* data = _datas->getRenderData(0);
|
||||
float* verts = (float*)data->getVertices();
|
||||
|
||||
auto floatsPerVert = _bytesPerVertex / sizeof(float);
|
||||
|
||||
std::size_t dstOffset = 0;
|
||||
|
||||
float vl = _localData[0],
|
||||
vr = _localData[2],
|
||||
vb = _localData[1],
|
||||
vt = _localData[3];
|
||||
|
||||
// left bottom
|
||||
verts[dstOffset] = vl;
|
||||
verts[dstOffset+1] = vb;
|
||||
verts[dstOffset+2] = 0;
|
||||
|
||||
dstOffset += floatsPerVert;
|
||||
|
||||
// right bottom
|
||||
verts[dstOffset] = vr;
|
||||
verts[dstOffset+1] = vb;
|
||||
verts[dstOffset+2] = 0;
|
||||
|
||||
dstOffset += floatsPerVert;
|
||||
|
||||
// left top
|
||||
verts[dstOffset] = vl;
|
||||
verts[dstOffset+1] = vt;
|
||||
verts[dstOffset+2] = 0;
|
||||
|
||||
dstOffset += floatsPerVert;
|
||||
|
||||
// right top
|
||||
verts[dstOffset] = vr;
|
||||
verts[dstOffset+1] = vt;
|
||||
verts[dstOffset+2] = 0;
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
39
cocos2d-x/cocos/renderer/scene/assembler/SimpleSprite3D.hpp
Normal file
39
cocos2d-x/cocos/renderer/scene/assembler/SimpleSprite3D.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AssemblerSprite.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class SimpleSprite3D : public AssemblerSprite
|
||||
{
|
||||
public:
|
||||
SimpleSprite3D();
|
||||
virtual ~SimpleSprite3D() override;
|
||||
virtual void generateWorldVertices() override;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
57
cocos2d-x/cocos/renderer/scene/assembler/SlicedSprite2D.cpp
Normal file
57
cocos2d-x/cocos/renderer/scene/assembler/SlicedSprite2D.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "SlicedSprite2D.hpp"
|
||||
#include "../RenderFlow.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
SlicedSprite2D::SlicedSprite2D()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SlicedSprite2D::~SlicedSprite2D()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SlicedSprite2D::generateWorldVertices()
|
||||
{
|
||||
RenderData* data = _datas->getRenderData(0);
|
||||
float* verts = (float*)data->getVertices();
|
||||
|
||||
auto floatsPerVert = _bytesPerVertex / sizeof(float);
|
||||
for (auto row = 0; row < 4; ++row) {
|
||||
float localRowY = _localData[row * 2 + 1];
|
||||
for (auto col = 0; col < 4; ++col) {
|
||||
float localColX = _localData[col * 2];
|
||||
std::size_t worldIndex = (row * 4 + col) * floatsPerVert;
|
||||
verts[worldIndex] = localColX ;
|
||||
verts[worldIndex + 1] = localRowY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
39
cocos2d-x/cocos/renderer/scene/assembler/SlicedSprite2D.hpp
Normal file
39
cocos2d-x/cocos/renderer/scene/assembler/SlicedSprite2D.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AssemblerSprite.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class SlicedSprite2D: public AssemblerSprite
|
||||
{
|
||||
public:
|
||||
SlicedSprite2D();
|
||||
virtual ~SlicedSprite2D();
|
||||
virtual void generateWorldVertices() override;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
57
cocos2d-x/cocos/renderer/scene/assembler/SlicedSprite3D.cpp
Normal file
57
cocos2d-x/cocos/renderer/scene/assembler/SlicedSprite3D.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "SlicedSprite3D.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
SlicedSprite3D::SlicedSprite3D()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
SlicedSprite3D::~SlicedSprite3D()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
void SlicedSprite3D::generateWorldVertices()
|
||||
{
|
||||
RenderData* data = _datas->getRenderData(0);
|
||||
float* verts = (float*)data->getVertices();
|
||||
|
||||
auto floatsPerVert = _bytesPerVertex / sizeof(float);
|
||||
for (auto row = 0; row < 4; ++row) {
|
||||
float localRowY = _localData[row * 2 + 1];
|
||||
for (auto col = 0; col < 4; ++col) {
|
||||
float localColX = _localData[col * 2];
|
||||
std::size_t worldIndex = (row * 4 + col) * floatsPerVert;
|
||||
verts[worldIndex] = localColX ;
|
||||
verts[worldIndex + 1] = localRowY;
|
||||
verts[worldIndex + 2] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
39
cocos2d-x/cocos/renderer/scene/assembler/SlicedSprite3D.hpp
Normal file
39
cocos2d-x/cocos/renderer/scene/assembler/SlicedSprite3D.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AssemblerSprite.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class SlicedSprite3D : public AssemblerSprite
|
||||
{
|
||||
public:
|
||||
SlicedSprite3D();
|
||||
virtual ~SlicedSprite3D() override;
|
||||
virtual void generateWorldVertices() override;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "TiledMapAssembler.hpp"
|
||||
#include "../NodeProxy.hpp"
|
||||
#include "../ModelBatcher.hpp"
|
||||
#include "../RenderFlow.hpp"
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
TiledMapAssembler::TiledMapAssembler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TiledMapAssembler::~TiledMapAssembler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TiledMapAssembler::updateNodes(std::size_t iaIndex, const std::vector<std::string>& nodes)
|
||||
{
|
||||
_nodesMap[iaIndex] = nodes;
|
||||
}
|
||||
|
||||
void TiledMapAssembler::clearNodes(std::size_t iaIndex)
|
||||
{
|
||||
_nodesMap.erase(iaIndex);
|
||||
}
|
||||
|
||||
void TiledMapAssembler::handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene)
|
||||
{
|
||||
_node = node;
|
||||
_batcher = batcher;
|
||||
// Last tiles data may be empty, but has user node, so render it by manual.
|
||||
auto lastNodesIndex = getIACount();
|
||||
auto it = _nodesMap.find(lastNodesIndex);
|
||||
if (it != _nodesMap.end())
|
||||
{
|
||||
renderNodes(lastNodesIndex);
|
||||
}
|
||||
Assembler::handle(node, batcher, scene);
|
||||
}
|
||||
|
||||
void TiledMapAssembler::renderNodes(std::size_t index)
|
||||
{
|
||||
static cocos2d::Mat4 tempWorldMat;
|
||||
const auto& worldMat = _node->getWorldMatrix();
|
||||
auto it = _nodesMap.find(index);
|
||||
if (it != _nodesMap.end())
|
||||
{
|
||||
auto flow = _batcher->getFlow();
|
||||
for (auto& id : it->second) {
|
||||
auto child = _node->getChildByID(id);
|
||||
if (child)
|
||||
{
|
||||
child->enableVisit(true);
|
||||
child->enableUpdateWorldMatrix(false);
|
||||
child->updateLocalMatrix();
|
||||
auto& localMat = child->getLocalMatrix();
|
||||
cocos2d::Mat4::multiply(worldMat, localMat, &tempWorldMat);
|
||||
child->updateWorldMatrix(tempWorldMat);
|
||||
flow->visit(child);
|
||||
child->enableUpdateWorldMatrix(true);
|
||||
child->enableVisit(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
_batcher->changeCommitState(ModelBatcher::Common);
|
||||
}
|
||||
|
||||
void TiledMapAssembler::beforeFillBuffers(std::size_t index)
|
||||
{
|
||||
renderNodes(index);
|
||||
}
|
||||
|
||||
RENDERER_END
|
||||
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Assembler.hpp"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
RENDERER_BEGIN
|
||||
|
||||
class TiledMapAssembler : public Assembler {
|
||||
public:
|
||||
TiledMapAssembler();
|
||||
virtual ~TiledMapAssembler();
|
||||
virtual void handle(NodeProxy *node, ModelBatcher* batcher, Scene* scene) override;
|
||||
virtual void beforeFillBuffers(std::size_t index) override;
|
||||
void updateNodes(std::size_t iaIndex, const std::vector<std::string>& nodes);
|
||||
void clearNodes(std::size_t iaIndex);
|
||||
private:
|
||||
void renderNodes(std::size_t index);
|
||||
private:
|
||||
std::map<std::size_t, std::vector<std::string>> _nodesMap;
|
||||
NodeProxy* _node = nullptr;
|
||||
ModelBatcher* _batcher = nullptr;
|
||||
};
|
||||
|
||||
RENDERER_END
|
||||
43
cocos2d-x/cocos/renderer/scene/scene-bindings.h
Normal file
43
cocos2d-x/cocos/renderer/scene/scene-bindings.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MemPool.hpp"
|
||||
#include "NodeMemPool.hpp"
|
||||
#include "NodeProxy.hpp"
|
||||
#include "ModelBatcher.hpp"
|
||||
#include "RenderFlow.hpp"
|
||||
#include "MeshBuffer.hpp"
|
||||
|
||||
#include "assembler/Assembler.hpp"
|
||||
#include "assembler/MaskAssembler.hpp"
|
||||
#include "assembler/TiledMapAssembler.hpp"
|
||||
#include "assembler/AssemblerSprite.hpp"
|
||||
#include "assembler/SimpleSprite2D.hpp"
|
||||
#include "assembler/SlicedSprite2D.hpp"
|
||||
#include "assembler/MeshAssembler.hpp"
|
||||
#include "assembler/SimpleSprite3D.hpp"
|
||||
#include "assembler/SlicedSprite3D.hpp"
|
||||
#include "assembler/Particle3DAssembler.hpp"
|
||||
Reference in New Issue
Block a user