mirror of
https://gitee.com/nomat/lcc-ui-sorting-group-demo.git
synced 2024-12-26 03:38:27 +00:00
日常
This commit is contained in:
parent
934207d732
commit
457937ac7f
@ -945,7 +945,7 @@
|
|||||||
"__expectedType__": "cc.SpriteFrame"
|
"__expectedType__": "cc.SpriteFrame"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"listItemMax": 2,
|
"listItemMax": 200,
|
||||||
"_id": "9fuu+PfOFHPqnvdYJwsexB"
|
"_id": "9fuu+PfOFHPqnvdYJwsexB"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 4.6 KiB |
BIN
docs/images/Screenshot_20230207_103431.jpg
Normal file
BIN
docs/images/Screenshot_20230207_103431.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 395 KiB |
BIN
docs/images/Screenshot_20230207_103552.jpg
Normal file
BIN
docs/images/Screenshot_20230207_103552.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 392 KiB |
@ -43,12 +43,12 @@ if(NOT COCOS_X_PATH)
|
|||||||
message(FATAL_ERROR "COCOS_X_PATH is not set!")
|
message(FATAL_ERROR "COCOS_X_PATH is not set!")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# 引入lcc-ui-sorting-group native部分
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/../lcc-ui-sorting-group-native/CMakeLists.txt)
|
||||||
|
|
||||||
include(${COCOS_X_PATH}/CMakeLists.txt)
|
include(${COCOS_X_PATH}/CMakeLists.txt)
|
||||||
|
|
||||||
list(APPEND CC_COMMON_SOURCES
|
list(APPEND CC_COMMON_SOURCES
|
||||||
${CMAKE_CURRENT_LIST_DIR}/Classes/Game.h
|
${CMAKE_CURRENT_LIST_DIR}/Classes/Game.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/Classes/Game.cpp
|
${CMAKE_CURRENT_LIST_DIR}/Classes/Game.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# 引入lcc-ui-sorting-group native部分
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/../lcc-ui-sorting-group-native/CMakeLists.txt)
|
|
||||||
|
@ -1,29 +1,48 @@
|
|||||||
|
|
||||||
string(REPLACE "/" "\\" CMD_COCOS_X_PATH "${COCOS_X_PATH}")
|
#string(REPLACE "/" "\\" CMD_COCOS_X_PATH "${COCOS_X_PATH}")
|
||||||
string(REPLACE "/" "\\" CMD_CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
#string(REPLACE "/" "\\" CMD_CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
|
||||||
# 引擎编译添加源文件替换依赖目标
|
# 引擎编译添加源文件替换依赖目标
|
||||||
add_custom_command(
|
#add_custom_command(
|
||||||
OUTPUT ${CMAKE_CURRENT_LIST_DIR}/ENGINE_REPLACE.txt
|
# OUTPUT ${CMAKE_CURRENT_LIST_DIR}/ENGINE_REPLACE.txt
|
||||||
COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\replace\\Batcher2d.h\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\Batcher2d.h\""
|
# COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\replace\\Batcher2d.h\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\Batcher2d.h\""
|
||||||
COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\replace\\Batcher2d.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\Batcher2d.cpp\""
|
# COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\replace\\Batcher2d.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\Batcher2d.cpp\""
|
||||||
COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\replace\\RenderEntity.h\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.h\""
|
# COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\replace\\RenderEntity.h\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.h\""
|
||||||
COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\replace\\RenderEntity.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.cpp\""
|
# COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\replace\\RenderEntity.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.cpp\""
|
||||||
COMMAND echo "ENGINE_REPLACE" >> "${CMD_CMAKE_CURRENT_LIST_DIR}\\ENGINE_REPLACE.txt"
|
# COMMAND echo "ENGINE_REPLACE" >> "${CMD_CMAKE_CURRENT_LIST_DIR}\\ENGINE_REPLACE.txt"
|
||||||
COMMAND echo "LCC_UI_SORTING_GROUP pre"
|
# COMMAND echo "LCC_UI_SORTING_GROUP pre"
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
# WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
)
|
#)
|
||||||
add_custom_target(LCC_UI_SORTING_GROUP_ENGINE_REPLACE DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ENGINE_REPLACE.txt)
|
#add_custom_target(LCC_UI_SORTING_GROUP_ENGINE_REPLACE DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ENGINE_REPLACE.txt)
|
||||||
add_dependencies(${ENGINE_NAME} LCC_UI_SORTING_GROUP_ENGINE_REPLACE)
|
#add_dependencies(${ENGINE_NAME} LCC_UI_SORTING_GROUP_ENGINE_REPLACE)
|
||||||
|
|
||||||
# 引擎编译恢复源文件
|
# 引擎编译恢复源文件
|
||||||
add_custom_command(TARGET ${ENGINE_NAME}
|
#add_custom_command(TARGET ${ENGINE_NAME}
|
||||||
POST_BUILD
|
# POST_BUILD
|
||||||
COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\backup\\Batcher2d.h\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\Batcher2d.h\""
|
# COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\backup\\Batcher2d.h\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\Batcher2d.h\""
|
||||||
COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\backup\\Batcher2d.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\Batcher2d.cpp\""
|
# COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\backup\\Batcher2d.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\Batcher2d.cpp\""
|
||||||
COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\backup\\RenderEntity.h\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.h\""
|
# COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\backup\\RenderEntity.h\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.h\""
|
||||||
COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\backup\\RenderEntity.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.cpp\""
|
# COMMAND copy /y "\"${CMD_CMAKE_CURRENT_LIST_DIR}\\backup\\RenderEntity.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.cpp\""
|
||||||
COMMAND del "${CMD_CMAKE_CURRENT_LIST_DIR}\\ENGINE_REPLACE.txt"
|
# COMMAND del "${CMD_CMAKE_CURRENT_LIST_DIR}\\ENGINE_REPLACE.txt"
|
||||||
COMMAND echo "LCC_UI_SORTING_GROUP post"
|
# COMMAND echo "LCC_UI_SORTING_GROUP post"
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
# WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
)
|
#)
|
||||||
|
|
||||||
|
if(NOT DEFINED COCOS_SOURCE_PLUGIN_EXCULDE)
|
||||||
|
set(COCOS_SOURCE_PLUGIN_EXCULDE)
|
||||||
|
endif()
|
||||||
|
if(NOT DEFINED COCOS_SOURCE_PLUGIN_LIST)
|
||||||
|
set(COCOS_SOURCE_PLUGIN_LIST)
|
||||||
|
endif()
|
||||||
|
if(NOT DEFINED COCOS_SOURCE_PLUGIN_INCLUDES)
|
||||||
|
set(COCOS_SOURCE_PLUGIN_INCLUDES)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 排除替换源文件
|
||||||
|
list(APPEND COCOS_SOURCE_PLUGIN_EXCULDE "${COCOS_X_PATH}/cocos/2d/renderer/Batcher2d.h" "${COCOS_X_PATH}/cocos/2d/renderer/Batcher2d.cpp" "${COCOS_X_PATH}/cocos/2d/renderer/RenderEntity.h" "${COCOS_X_PATH}/cocos/2d/renderer/RenderEntity.cpp")
|
||||||
|
|
||||||
|
# 添加替换源文件
|
||||||
|
list(APPEND COCOS_SOURCE_PLUGIN_LIST "${CMAKE_CURRENT_LIST_DIR}/native/cocos/2d/renderer/Batcher2d.h" "${CMAKE_CURRENT_LIST_DIR}/native/cocos/2d/renderer/Batcher2d.cpp" "${CMAKE_CURRENT_LIST_DIR}/native/cocos/2d/renderer/RenderEntity.h" "${CMAKE_CURRENT_LIST_DIR}/native/cocos/2d/renderer/RenderEntity.cpp")
|
||||||
|
|
||||||
|
# 添加替换源文件
|
||||||
|
list(APPEND COCOS_SOURCE_PLUGIN_INCLUDES "${CMAKE_CURRENT_LIST_DIR}/native" "${CMAKE_CURRENT_LIST_DIR}/native/cocos")
|
||||||
|
@ -1,609 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
Copyright (c) 2019-2021 Xiamen Yaji Software Co., Ltd.
|
|
||||||
|
|
||||||
http://www.cocos.com
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated engine source code (the "Software"), a limited,
|
|
||||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
|
||||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
|
||||||
not use Cocos Creator software for developing other software or tools that's
|
|
||||||
used for developing games. You are not granted to publish, distribute,
|
|
||||||
sublicense, and/or sell copies of Cocos Creator.
|
|
||||||
|
|
||||||
The software or tools in this License Agreement are licensed, not sold.
|
|
||||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
|
||||||
|
|
||||||
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 "2d/renderer/Batcher2d.h"
|
|
||||||
#include "application/ApplicationManager.h"
|
|
||||||
#include "base/TypeDef.h"
|
|
||||||
#include "core/Root.h"
|
|
||||||
#include "editor-support/MiddlewareManager.h"
|
|
||||||
#include "renderer/pipeline/Define.h"
|
|
||||||
#include "scene/Pass.h"
|
|
||||||
|
|
||||||
namespace cc {
|
|
||||||
|
|
||||||
Batcher2d::Batcher2d() : Batcher2d(nullptr) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Batcher2d::Batcher2d(Root* root)
|
|
||||||
: _drawBatchPool([]() { return ccnew scene::DrawBatch2D(); }, [](auto* obj) { delete obj; }, 10U) {
|
|
||||||
if (root == nullptr) {
|
|
||||||
root = Root::getInstance();
|
|
||||||
}
|
|
||||||
_root = root;
|
|
||||||
_device = _root->getDevice();
|
|
||||||
_stencilManager = StencilManager::getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
Batcher2d::~Batcher2d() { // NOLINT
|
|
||||||
_drawBatchPool.destroy();
|
|
||||||
|
|
||||||
for (auto iter : _descriptorSetCache) {
|
|
||||||
delete iter.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto* drawBatch : _batches) {
|
|
||||||
delete drawBatch;
|
|
||||||
}
|
|
||||||
_attributes.clear();
|
|
||||||
|
|
||||||
if(_maskClearModel != nullptr) {
|
|
||||||
Root::getInstance()->destroyModel(_maskClearModel);
|
|
||||||
_maskClearModel = nullptr;
|
|
||||||
}
|
|
||||||
if (_maskModelMesh != nullptr) {
|
|
||||||
_maskModelMesh->destroy();
|
|
||||||
_maskModelMesh = nullptr;
|
|
||||||
}
|
|
||||||
_maskClearMtl = nullptr;
|
|
||||||
_maskAttributes.clear();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::syncMeshBuffersToNative(uint16_t accId, ccstd::vector<UIMeshBuffer*>&& buffers) {
|
|
||||||
_meshBuffersMap[accId] = std::move(buffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
UIMeshBuffer* Batcher2d::getMeshBuffer(uint16_t accId, uint16_t bufferId) { // NOLINT(bugprone-easily-swappable-parameters)
|
|
||||||
const auto& map = _meshBuffersMap[accId];
|
|
||||||
return map[bufferId];
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Device* Batcher2d::getDevice() {
|
|
||||||
if (_device == nullptr) {
|
|
||||||
_device = Root::getInstance()->getDevice();
|
|
||||||
}
|
|
||||||
return _device;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::updateDescriptorSet() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::syncRootNodesToNative(ccstd::vector<Node*>&& rootNodes) {
|
|
||||||
_rootNodeArr = std::move(rootNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::fillBuffersAndMergeBatches() {
|
|
||||||
for (auto* rootNode : _rootNodeArr) {
|
|
||||||
walk(rootNode, 1);
|
|
||||||
generateBatch(_currEntity, _currDrawInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::walk(Node* node, float parentOpacity) { // NOLINT(misc-no-recursion)
|
|
||||||
if (!node->isActiveInHierarchy()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool breakWalk = false;
|
|
||||||
auto* entity = static_cast<RenderEntity*>(node->getUserData());
|
|
||||||
if (entity) {
|
|
||||||
if (entity->getColorDirty()) {
|
|
||||||
float localOpacity = entity->getLocalOpacity();
|
|
||||||
float localColorAlpha = entity->getColorAlpha();
|
|
||||||
entity->setOpacity(parentOpacity * localOpacity * localColorAlpha);
|
|
||||||
entity->setColorDirty(false);
|
|
||||||
entity->setVBColorDirty(true);
|
|
||||||
}
|
|
||||||
if (entity->isEnabled()) {
|
|
||||||
uint32_t size = entity->getRenderDrawInfosSize();
|
|
||||||
for (uint32_t i = 0; i < size; i++) {
|
|
||||||
auto* drawInfo = entity->getRenderDrawInfoAt(i);
|
|
||||||
handleDrawInfo(entity, drawInfo, node);
|
|
||||||
}
|
|
||||||
entity->setVBColorDirty(false);
|
|
||||||
}
|
|
||||||
if (entity->getRenderEntityType() == RenderEntityType::CROSSED) {
|
|
||||||
breakWalk = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!breakWalk) {
|
|
||||||
const auto& children = node->getChildren();
|
|
||||||
float thisOpacity = entity ? entity->getOpacity() : parentOpacity;
|
|
||||||
for (const auto& child : children) {
|
|
||||||
// we should find parent opacity recursively upwards if it doesn't have an entity.
|
|
||||||
walk(child, thisOpacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// post assembler
|
|
||||||
if (_stencilManager->getMaskStackSize() > 0 && entity && entity->isEnabled()) {
|
|
||||||
handlePostRender(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::handlePostRender(RenderEntity* entity) {
|
|
||||||
bool isMask = entity->getIsMask();
|
|
||||||
if (isMask) {
|
|
||||||
generateBatch(_currEntity, _currDrawInfo);
|
|
||||||
resetRenderStates();
|
|
||||||
_stencilManager->exitMask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CC_FORCE_INLINE void Batcher2d::handleComponentDraw(RenderEntity* entity, RenderDrawInfo* drawInfo, Node* node) {
|
|
||||||
ccstd::hash_t dataHash = drawInfo->getDataHash();
|
|
||||||
if (drawInfo->getIsMeshBuffer()) {
|
|
||||||
dataHash = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// may slow
|
|
||||||
bool isMask = entity->getIsMask();
|
|
||||||
if (isMask) {
|
|
||||||
// Mask subComp
|
|
||||||
insertMaskBatch(entity);
|
|
||||||
} else {
|
|
||||||
entity->setEnumStencilStage(_stencilManager->getStencilStage());
|
|
||||||
}
|
|
||||||
auto tempStage = static_cast<StencilStage>(entity->getStencilStage());
|
|
||||||
|
|
||||||
if (_currHash != dataHash || dataHash == 0 || _currMaterial != drawInfo->getMaterial() || _currStencilStage != tempStage) {
|
|
||||||
// Generate a batch if not batching
|
|
||||||
generateBatch(_currEntity, _currDrawInfo);
|
|
||||||
|
|
||||||
if (!drawInfo->getIsMeshBuffer()) {
|
|
||||||
UIMeshBuffer* buffer = drawInfo->getMeshBuffer();
|
|
||||||
if (_currMeshBuffer != buffer) {
|
|
||||||
_currMeshBuffer = buffer;
|
|
||||||
_indexStart = _currMeshBuffer->getIndexOffset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_currHash = dataHash;
|
|
||||||
_currMaterial = drawInfo->getMaterial();
|
|
||||||
_currStencilStage = tempStage;
|
|
||||||
_currLayer = entity->getNode()->getLayer();
|
|
||||||
_currEntity = entity;
|
|
||||||
_currDrawInfo = drawInfo;
|
|
||||||
|
|
||||||
_currTexture = drawInfo->getTexture();
|
|
||||||
_currSampler = drawInfo->getSampler();
|
|
||||||
if (_currSampler == nullptr) {
|
|
||||||
_currSamplerHash = 0;
|
|
||||||
} else {
|
|
||||||
_currSamplerHash = _currSampler->getHash();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!drawInfo->getIsMeshBuffer()) {
|
|
||||||
if (node->getChangedFlags() || drawInfo->getVertDirty()) {
|
|
||||||
fillVertexBuffers(entity, drawInfo);
|
|
||||||
drawInfo->setVertDirty(false);
|
|
||||||
}
|
|
||||||
if (entity->getVBColorDirty()) {
|
|
||||||
fillColors(entity, drawInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
fillIndexBuffers(drawInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMask) {
|
|
||||||
_stencilManager->enableMask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CC_FORCE_INLINE void Batcher2d::handleModelDraw(RenderEntity* entity, RenderDrawInfo* drawInfo) {
|
|
||||||
generateBatch(_currEntity, _currDrawInfo);
|
|
||||||
resetRenderStates();
|
|
||||||
|
|
||||||
// stencil stage
|
|
||||||
gfx::DepthStencilState* depthStencil = nullptr;
|
|
||||||
ccstd::hash_t dssHash = 0;
|
|
||||||
Material* renderMat = drawInfo->getMaterial();
|
|
||||||
|
|
||||||
bool isMask = entity->getIsMask();
|
|
||||||
if (isMask) {
|
|
||||||
//Mask Comp
|
|
||||||
insertMaskBatch(entity);
|
|
||||||
} else {
|
|
||||||
entity->setEnumStencilStage(_stencilManager->getStencilStage());
|
|
||||||
}
|
|
||||||
|
|
||||||
StencilStage entityStage = entity->getEnumStencilStage();
|
|
||||||
depthStencil = _stencilManager->getDepthStencilState(entityStage, renderMat);
|
|
||||||
dssHash = _stencilManager->getStencilHash(entityStage);
|
|
||||||
|
|
||||||
// Model
|
|
||||||
auto* model = drawInfo->getModel();
|
|
||||||
if (model == nullptr) return;
|
|
||||||
auto stamp = CC_CURRENT_ENGINE()->getTotalFrames();
|
|
||||||
model->updateTransform(stamp);
|
|
||||||
model->updateUBOs(stamp);
|
|
||||||
|
|
||||||
const auto& subModelList = model->getSubModels();
|
|
||||||
for (const auto& submodel : subModelList) {
|
|
||||||
auto* curdrawBatch = _drawBatchPool.alloc();
|
|
||||||
curdrawBatch->setVisFlags(entity->getNode()->getLayer());
|
|
||||||
curdrawBatch->setModel(model);
|
|
||||||
curdrawBatch->setInputAssembler(submodel->getInputAssembler());
|
|
||||||
curdrawBatch->setDescriptorSet(submodel->getDescriptorSet());
|
|
||||||
|
|
||||||
curdrawBatch->fillPass(renderMat, depthStencil, dssHash, &(submodel->getPatches()));
|
|
||||||
_batches.push_back(curdrawBatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isMask) {
|
|
||||||
_stencilManager->enableMask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CC_FORCE_INLINE void Batcher2d::handleMiddlewareDraw(RenderEntity* entity, RenderDrawInfo* drawInfo) {
|
|
||||||
auto layer = entity->getNode()->getLayer();
|
|
||||||
Material* material = drawInfo->getMaterial();
|
|
||||||
auto* texture = drawInfo->getTexture();
|
|
||||||
auto* sampler = drawInfo->getSampler();
|
|
||||||
auto* meshBuffer = drawInfo->getMeshBuffer();
|
|
||||||
|
|
||||||
// check for merge draw
|
|
||||||
auto enableBatch = !entity->getUseLocal();
|
|
||||||
if (enableBatch && _currTexture == texture && _currMeshBuffer == meshBuffer
|
|
||||||
&& !_currEntity->getUseLocal()
|
|
||||||
&& material->getHash() == _currMaterial->getHash()
|
|
||||||
&& drawInfo->getIndexOffset() == _currDrawInfo->getIndexOffset() + _currDrawInfo->getIbCount()
|
|
||||||
&& layer == _currLayer) {
|
|
||||||
auto ibCount = _currDrawInfo->getIbCount();
|
|
||||||
_currDrawInfo->setIbCount(ibCount + drawInfo->getIbCount());
|
|
||||||
} else {
|
|
||||||
generateBatch(_currEntity, _currDrawInfo);
|
|
||||||
_currLayer = layer;
|
|
||||||
_currMaterial = material;
|
|
||||||
_currTexture = texture;
|
|
||||||
_currMeshBuffer = meshBuffer;
|
|
||||||
_currEntity = entity;
|
|
||||||
_currDrawInfo = drawInfo;
|
|
||||||
_currHash = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CC_FORCE_INLINE void Batcher2d::handleSubNode(RenderEntity* entity, RenderDrawInfo* drawInfo) { // NOLINT
|
|
||||||
if (drawInfo->getSubNode()) {
|
|
||||||
walk(drawInfo->getSubNode(), entity->getOpacity());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CC_FORCE_INLINE void Batcher2d::handleDrawInfo(RenderEntity* entity, RenderDrawInfo* drawInfo, Node* node) { //NOLINT(misc-no-recursion)
|
|
||||||
CC_ASSERT(entity);
|
|
||||||
CC_ASSERT(drawInfo);
|
|
||||||
RenderDrawInfoType drawInfoType = drawInfo->getEnumDrawInfoType();
|
|
||||||
|
|
||||||
switch (drawInfoType) {
|
|
||||||
case RenderDrawInfoType::COMP:
|
|
||||||
handleComponentDraw(entity, drawInfo, node);
|
|
||||||
break;
|
|
||||||
case RenderDrawInfoType::MODEL:
|
|
||||||
handleModelDraw(entity, drawInfo);
|
|
||||||
break;
|
|
||||||
case RenderDrawInfoType::MIDDLEWARE:
|
|
||||||
handleMiddlewareDraw(entity, drawInfo);
|
|
||||||
break;
|
|
||||||
case RenderDrawInfoType::SUB_NODE:
|
|
||||||
handleSubNode(entity, drawInfo);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::generateBatch(RenderEntity* entity, RenderDrawInfo* drawInfo) {
|
|
||||||
if (drawInfo == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (drawInfo->getEnumDrawInfoType() == RenderDrawInfoType::MIDDLEWARE) {
|
|
||||||
generateBatchForMiddleware(entity, drawInfo);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_currMaterial == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gfx::InputAssembler* ia = nullptr;
|
|
||||||
if (drawInfo->getIsMeshBuffer()) {
|
|
||||||
// Todo MeshBuffer RenderData
|
|
||||||
ia = drawInfo->requestIA(getDevice());
|
|
||||||
_meshRenderDrawInfo.emplace_back(drawInfo);
|
|
||||||
} else {
|
|
||||||
UIMeshBuffer* currMeshBuffer = drawInfo->getMeshBuffer();
|
|
||||||
|
|
||||||
currMeshBuffer->setDirty(true);
|
|
||||||
|
|
||||||
ia = currMeshBuffer->requireFreeIA(getDevice());
|
|
||||||
uint32_t indexCount = currMeshBuffer->getIndexOffset() - _indexStart;
|
|
||||||
if (ia == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ia->setFirstIndex(_indexStart);
|
|
||||||
ia->setIndexCount(indexCount);
|
|
||||||
_indexStart = currMeshBuffer->getIndexOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
_currMeshBuffer = nullptr;
|
|
||||||
|
|
||||||
// stencilStage
|
|
||||||
gfx::DepthStencilState* depthStencil = nullptr;
|
|
||||||
ccstd::hash_t dssHash = 0;
|
|
||||||
StencilStage entityStage = entity->getEnumStencilStage();
|
|
||||||
depthStencil = _stencilManager->getDepthStencilState(entityStage, _currMaterial);
|
|
||||||
dssHash = _stencilManager->getStencilHash(entityStage);
|
|
||||||
|
|
||||||
auto* curdrawBatch = _drawBatchPool.alloc();
|
|
||||||
curdrawBatch->setVisFlags(_currLayer);
|
|
||||||
curdrawBatch->setInputAssembler(ia);
|
|
||||||
curdrawBatch->fillPass(_currMaterial, depthStencil, dssHash);
|
|
||||||
const auto& pass = curdrawBatch->getPasses().at(0);
|
|
||||||
|
|
||||||
if (entity->getUseLocal()) {
|
|
||||||
drawInfo->updateLocalDescriptorSet(entity->getRenderTransform(), pass->getLocalSetLayout());
|
|
||||||
curdrawBatch->setDescriptorSet(drawInfo->getLocalDes());
|
|
||||||
} else {
|
|
||||||
curdrawBatch->setDescriptorSet(getDescriptorSet(_currTexture, _currSampler, pass->getLocalSetLayout()));
|
|
||||||
}
|
|
||||||
_batches.push_back(curdrawBatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::generateBatchForMiddleware(RenderEntity* entity, RenderDrawInfo* drawInfo) {
|
|
||||||
auto layer = entity->getNode()->getLayer();
|
|
||||||
auto* material = drawInfo->getMaterial();
|
|
||||||
auto* texture = drawInfo->getTexture();
|
|
||||||
auto* sampler = drawInfo->getSampler();
|
|
||||||
auto* meshBuffer = drawInfo->getMeshBuffer();
|
|
||||||
//set meshbuffer offset
|
|
||||||
auto indexOffset = drawInfo->getIndexOffset();
|
|
||||||
auto indexCount = drawInfo->getIbCount();
|
|
||||||
indexOffset += indexCount;
|
|
||||||
if (meshBuffer->getIndexOffset() < indexOffset) {
|
|
||||||
meshBuffer->setIndexOffset(indexOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
meshBuffer->setDirty(true);
|
|
||||||
gfx::InputAssembler* ia = meshBuffer->requireFreeIA(getDevice());
|
|
||||||
ia->setFirstIndex(drawInfo->getIndexOffset());
|
|
||||||
ia->setIndexCount(drawInfo->getIbCount());
|
|
||||||
|
|
||||||
// stencilstage
|
|
||||||
auto stencilStage = _stencilManager->getStencilStage();
|
|
||||||
gfx::DepthStencilState* depthStencil = _stencilManager->getDepthStencilState(stencilStage, material);
|
|
||||||
ccstd::hash_t dssHash = _stencilManager->getStencilHash(stencilStage);
|
|
||||||
|
|
||||||
auto* curdrawBatch = _drawBatchPool.alloc();
|
|
||||||
curdrawBatch->setVisFlags(_currLayer);
|
|
||||||
curdrawBatch->setInputAssembler(ia);
|
|
||||||
curdrawBatch->fillPass(material, depthStencil, dssHash);
|
|
||||||
const auto& pass = curdrawBatch->getPasses().at(0);
|
|
||||||
if (entity->getUseLocal()) {
|
|
||||||
drawInfo->updateLocalDescriptorSet(entity->getNode(), pass->getLocalSetLayout());
|
|
||||||
curdrawBatch->setDescriptorSet(drawInfo->getLocalDes());
|
|
||||||
} else {
|
|
||||||
curdrawBatch->setDescriptorSet(getDescriptorSet(texture, sampler, pass->getLocalSetLayout()));
|
|
||||||
}
|
|
||||||
_batches.push_back(curdrawBatch);
|
|
||||||
// make sure next generateBatch return.
|
|
||||||
resetRenderStates();
|
|
||||||
_currMeshBuffer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::resetRenderStates() {
|
|
||||||
_currMaterial = nullptr;
|
|
||||||
_currTexture = nullptr;
|
|
||||||
_currSampler = nullptr;
|
|
||||||
_currSamplerHash = 0;
|
|
||||||
_currLayer = 0;
|
|
||||||
_currEntity = nullptr;
|
|
||||||
_currDrawInfo = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::DescriptorSet* Batcher2d::getDescriptorSet(gfx::Texture* texture, gfx::Sampler* sampler, gfx::DescriptorSetLayout* dsLayout) {
|
|
||||||
ccstd::hash_t hash = 2;
|
|
||||||
size_t textureHash;
|
|
||||||
if (texture != nullptr) {
|
|
||||||
textureHash = boost::hash_value(texture);
|
|
||||||
ccstd::hash_combine(hash, textureHash);
|
|
||||||
}
|
|
||||||
if (sampler != nullptr) {
|
|
||||||
ccstd::hash_combine(hash, sampler->getHash());
|
|
||||||
}
|
|
||||||
auto iter = _descriptorSetCache.find(hash);
|
|
||||||
if (iter != _descriptorSetCache.end()) {
|
|
||||||
if (texture != nullptr && sampler != nullptr) {
|
|
||||||
iter->second->bindTexture(static_cast<uint32_t>(pipeline::ModelLocalBindings::SAMPLER_SPRITE), texture);
|
|
||||||
iter->second->bindSampler(static_cast<uint32_t>(pipeline::ModelLocalBindings::SAMPLER_SPRITE), sampler);
|
|
||||||
}
|
|
||||||
iter->second->forceUpdate();
|
|
||||||
return iter->second;
|
|
||||||
}
|
|
||||||
_dsInfo.layout = dsLayout;
|
|
||||||
auto* ds = getDevice()->createDescriptorSet(_dsInfo);
|
|
||||||
|
|
||||||
if (texture != nullptr && sampler != nullptr) {
|
|
||||||
ds->bindTexture(static_cast<uint32_t>(pipeline::ModelLocalBindings::SAMPLER_SPRITE), texture);
|
|
||||||
ds->bindSampler(static_cast<uint32_t>(pipeline::ModelLocalBindings::SAMPLER_SPRITE), sampler);
|
|
||||||
}
|
|
||||||
ds->update();
|
|
||||||
_descriptorSetCache.emplace(hash, ds);
|
|
||||||
|
|
||||||
return ds;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::releaseDescriptorSetCache(gfx::Texture* texture, gfx::Sampler* sampler) {
|
|
||||||
ccstd::hash_t hash = 2;
|
|
||||||
size_t textureHash;
|
|
||||||
if (texture != nullptr) {
|
|
||||||
textureHash = boost::hash_value(texture);
|
|
||||||
ccstd::hash_combine(hash, textureHash);
|
|
||||||
}
|
|
||||||
if (sampler != nullptr) {
|
|
||||||
ccstd::hash_combine(hash, sampler->getHash());
|
|
||||||
}
|
|
||||||
auto iter = _descriptorSetCache.find(hash);
|
|
||||||
if (iter != _descriptorSetCache.end()) {
|
|
||||||
delete iter->second;
|
|
||||||
_descriptorSetCache.erase(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Batcher2d::initialize() {
|
|
||||||
_isInit = true;
|
|
||||||
return _isInit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::update() {
|
|
||||||
fillBuffersAndMergeBatches();
|
|
||||||
resetRenderStates();
|
|
||||||
|
|
||||||
for (const auto& scene : Root::getInstance()->getScenes()) {
|
|
||||||
for (auto* batch : _batches) {
|
|
||||||
scene->addBatch(batch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::uploadBuffers() {
|
|
||||||
if (_batches.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& meshRenderData : _meshRenderDrawInfo) {
|
|
||||||
meshRenderData->uploadBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& map : _meshBuffersMap) {
|
|
||||||
for (auto& buffer : map.second) {
|
|
||||||
buffer->uploadBuffers();
|
|
||||||
buffer->reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateDescriptorSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::reset() {
|
|
||||||
for (auto& batch : _batches) {
|
|
||||||
batch->clear();
|
|
||||||
_drawBatchPool.free(batch);
|
|
||||||
}
|
|
||||||
_batches.clear();
|
|
||||||
|
|
||||||
for (auto& meshRenderData : _meshRenderDrawInfo) {
|
|
||||||
meshRenderData->resetMeshIA();
|
|
||||||
}
|
|
||||||
_meshRenderDrawInfo.clear();
|
|
||||||
|
|
||||||
// meshDataArray
|
|
||||||
for (auto& map : _meshBuffersMap) {
|
|
||||||
for (auto& buffer : map.second) {
|
|
||||||
if (buffer) {
|
|
||||||
buffer->resetIA();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//meshBuffer cannot clear because it is not transported at every frame.
|
|
||||||
|
|
||||||
_currMeshBuffer = nullptr;
|
|
||||||
_indexStart = 0;
|
|
||||||
_currHash = 0;
|
|
||||||
_currLayer = 0;
|
|
||||||
_currMaterial = nullptr;
|
|
||||||
_currTexture = nullptr;
|
|
||||||
_currSampler = nullptr;
|
|
||||||
|
|
||||||
// stencilManager
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::insertMaskBatch(RenderEntity* entity){
|
|
||||||
generateBatch(_currEntity, _currDrawInfo);
|
|
||||||
resetRenderStates();
|
|
||||||
createClearModel();
|
|
||||||
_maskClearModel->setNode(entity->getNode());
|
|
||||||
_maskClearModel->setTransform(entity->getNode());
|
|
||||||
_stencilManager->pushMask();
|
|
||||||
auto stage = _stencilManager->clear(entity);
|
|
||||||
|
|
||||||
gfx::DepthStencilState* depthStencil = nullptr;
|
|
||||||
ccstd::hash_t dssHash = 0;
|
|
||||||
if(_maskClearMtl != nullptr){
|
|
||||||
depthStencil = _stencilManager->getDepthStencilState(stage, _maskClearMtl);
|
|
||||||
dssHash = _stencilManager->getStencilHash(stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Model
|
|
||||||
if (_maskClearModel == nullptr) return;
|
|
||||||
auto stamp = CC_CURRENT_ENGINE()->getTotalFrames();
|
|
||||||
_maskClearModel->updateTransform(stamp);
|
|
||||||
_maskClearModel->updateUBOs(stamp);
|
|
||||||
|
|
||||||
const auto& subModelList = _maskClearModel->getSubModels();
|
|
||||||
for (const auto& submodel : subModelList) {
|
|
||||||
auto* curdrawBatch = _drawBatchPool.alloc();
|
|
||||||
curdrawBatch->setVisFlags(entity->getNode()->getLayer());
|
|
||||||
curdrawBatch->setModel(_maskClearModel);
|
|
||||||
curdrawBatch->setInputAssembler(submodel->getInputAssembler());
|
|
||||||
curdrawBatch->setDescriptorSet(submodel->getDescriptorSet());
|
|
||||||
|
|
||||||
curdrawBatch->fillPass(_maskClearMtl, depthStencil, dssHash, &(submodel->getPatches()));
|
|
||||||
_batches.push_back(curdrawBatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
_stencilManager->enterLevel(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Batcher2d::createClearModel() {
|
|
||||||
if (_maskClearModel == nullptr) {
|
|
||||||
_maskClearMtl = BuiltinResMgr::getInstance()->get<Material>(ccstd::string("default-clear-stencil"));
|
|
||||||
|
|
||||||
_maskClearModel = Root::getInstance()->createModel<scene::Model>();
|
|
||||||
uint32_t stride = 12;// vfmt
|
|
||||||
|
|
||||||
auto* vertexBuffer = _device->createBuffer({
|
|
||||||
gfx::BufferUsageBit::VERTEX | gfx::BufferUsageBit::TRANSFER_DST,
|
|
||||||
gfx::MemoryUsageBit::DEVICE,
|
|
||||||
4 * stride,
|
|
||||||
stride,
|
|
||||||
});
|
|
||||||
const float vertices[] = {-1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0};
|
|
||||||
vertexBuffer->update(vertices);
|
|
||||||
auto* indexBuffer = _device->createBuffer({
|
|
||||||
gfx::BufferUsageBit::INDEX | gfx::BufferUsageBit::TRANSFER_DST,
|
|
||||||
gfx::MemoryUsageBit::DEVICE,
|
|
||||||
6 * sizeof(uint16_t),
|
|
||||||
sizeof(uint16_t),
|
|
||||||
});
|
|
||||||
const uint16_t indices[] = {0, 2, 1, 2, 1, 3};
|
|
||||||
indexBuffer->update(indices);
|
|
||||||
|
|
||||||
gfx::BufferList vbReference;
|
|
||||||
vbReference.emplace_back(vertexBuffer);
|
|
||||||
_maskModelMesh = ccnew RenderingSubMesh(vbReference, _maskAttributes, _primitiveMode, indexBuffer);
|
|
||||||
_maskModelMesh->setSubMeshIdx(0);
|
|
||||||
|
|
||||||
_maskClearModel->initSubModel(0, _maskModelMesh, _maskClearMtl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace cc
|
|
@ -1,203 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
Copyright (c) 2019-2021 Xiamen Yaji Software Co., Ltd.
|
|
||||||
|
|
||||||
http://www.cocos.com
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated engine source code (the "Software"), a limited,
|
|
||||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
|
||||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
|
||||||
not use Cocos Creator software for developing other software or tools that's
|
|
||||||
used for developing games. You are not granted to publish, distribute,
|
|
||||||
sublicense, and/or sell copies of Cocos Creator.
|
|
||||||
|
|
||||||
The software or tools in this License Agreement are licensed, not sold.
|
|
||||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
|
||||||
|
|
||||||
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 "2d/renderer/RenderDrawInfo.h"
|
|
||||||
#include "2d/renderer/RenderEntity.h"
|
|
||||||
#include "2d/renderer/UIMeshBuffer.h"
|
|
||||||
#include "base/Macros.h"
|
|
||||||
#include "base/Ptr.h"
|
|
||||||
#include "base/TypeDef.h"
|
|
||||||
#include "core/assets/Material.h"
|
|
||||||
#include "core/memop/Pool.h"
|
|
||||||
#include "renderer/gfx-base/GFXTexture.h"
|
|
||||||
#include "renderer/gfx-base/states/GFXSampler.h"
|
|
||||||
#include "scene/DrawBatch2D.h"
|
|
||||||
|
|
||||||
namespace cc {
|
|
||||||
class Root;
|
|
||||||
using UIMeshBufferArray = ccstd::vector<UIMeshBuffer*>;
|
|
||||||
using UIMeshBufferMap = ccstd::unordered_map<uint16_t, UIMeshBufferArray>;
|
|
||||||
|
|
||||||
class Batcher2d final {
|
|
||||||
public:
|
|
||||||
Batcher2d();
|
|
||||||
explicit Batcher2d(Root* root);
|
|
||||||
~Batcher2d();
|
|
||||||
|
|
||||||
void syncMeshBuffersToNative(uint16_t accId, ccstd::vector<UIMeshBuffer*>&& buffers);
|
|
||||||
|
|
||||||
bool initialize();
|
|
||||||
void update();
|
|
||||||
void uploadBuffers();
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void syncRootNodesToNative(ccstd::vector<Node*>&& rootNodes);
|
|
||||||
void releaseDescriptorSetCache(gfx::Texture* texture, gfx::Sampler* sampler);
|
|
||||||
|
|
||||||
UIMeshBuffer* getMeshBuffer(uint16_t accId, uint16_t bufferId);
|
|
||||||
gfx::Device* getDevice();
|
|
||||||
inline ccstd::vector<gfx::Attribute>* getDefaultAttribute() { return &_attributes; }
|
|
||||||
|
|
||||||
void updateDescriptorSet();
|
|
||||||
|
|
||||||
void fillBuffersAndMergeBatches();
|
|
||||||
void walk(Node* node, float parentOpacity);
|
|
||||||
void handlePostRender(RenderEntity* entity);
|
|
||||||
void handleDrawInfo(RenderEntity* entity, RenderDrawInfo* drawInfo, Node* node);
|
|
||||||
void handleComponentDraw(RenderEntity* entity, RenderDrawInfo* drawInfo, Node* node);
|
|
||||||
void handleModelDraw(RenderEntity* entity, RenderDrawInfo* drawInfo);
|
|
||||||
void handleMiddlewareDraw(RenderEntity* entity, RenderDrawInfo* drawInfo);
|
|
||||||
void handleSubNode(RenderEntity* entity, RenderDrawInfo* drawInfo);
|
|
||||||
void generateBatch(RenderEntity* entity, RenderDrawInfo* drawInfo);
|
|
||||||
void generateBatchForMiddleware(RenderEntity* entity, RenderDrawInfo* drawInfo);
|
|
||||||
void resetRenderStates();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _isInit = false;
|
|
||||||
|
|
||||||
inline void fillIndexBuffers(RenderDrawInfo* drawInfo) { // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
uint16_t* ib = drawInfo->getIDataBuffer();
|
|
||||||
|
|
||||||
UIMeshBuffer* buffer = drawInfo->getMeshBuffer();
|
|
||||||
uint32_t indexOffset = buffer->getIndexOffset();
|
|
||||||
|
|
||||||
uint16_t* indexb = drawInfo->getIbBuffer();
|
|
||||||
uint32_t indexCount = drawInfo->getIbCount();
|
|
||||||
|
|
||||||
memcpy(&ib[indexOffset], indexb, indexCount * sizeof(uint16_t));
|
|
||||||
indexOffset += indexCount;
|
|
||||||
|
|
||||||
buffer->setIndexOffset(indexOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void fillVertexBuffers(RenderEntity* entity, RenderDrawInfo* drawInfo) { // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
Node* node = entity->getNode();
|
|
||||||
const Mat4& matrix = node->getWorldMatrix();
|
|
||||||
uint8_t stride = drawInfo->getStride();
|
|
||||||
uint32_t size = drawInfo->getVbCount() * stride;
|
|
||||||
float* vbBuffer = drawInfo->getVbBuffer();
|
|
||||||
for (int i = 0; i < size; i += stride) {
|
|
||||||
Render2dLayout* curLayout = drawInfo->getRender2dLayout(i);
|
|
||||||
// make sure that the layout of Vec3 is three consecutive floats
|
|
||||||
static_assert(sizeof(Vec3) == 3 * sizeof(float));
|
|
||||||
// cast to reduce value copy instructions
|
|
||||||
reinterpret_cast<Vec3*>(vbBuffer + i)->transformMat4(curLayout->position, matrix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setIndexRange(RenderDrawInfo* drawInfo) { // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
UIMeshBuffer* buffer = drawInfo->getMeshBuffer();
|
|
||||||
uint32_t indexOffset = drawInfo->getIndexOffset();
|
|
||||||
uint32_t indexCount = drawInfo->getIbCount();
|
|
||||||
indexOffset += indexCount;
|
|
||||||
if (buffer->getIndexOffset() < indexOffset) {
|
|
||||||
buffer->setIndexOffset(indexOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void fillColors(RenderEntity* entity, RenderDrawInfo* drawInfo) { // NOLINT(readability-convert-member-functions-to-static)
|
|
||||||
Color temp = entity->getColor();
|
|
||||||
|
|
||||||
uint8_t stride = drawInfo->getStride();
|
|
||||||
uint32_t size = drawInfo->getVbCount() * stride;
|
|
||||||
float* vbBuffer = drawInfo->getVbBuffer();
|
|
||||||
|
|
||||||
uint32_t offset = 0;
|
|
||||||
for (int i = 0; i < size; i += stride) {
|
|
||||||
offset = i + 5;
|
|
||||||
vbBuffer[offset++] = static_cast<float>(temp.r) / 255.0F;
|
|
||||||
vbBuffer[offset++] = static_cast<float>(temp.g) / 255.0F;
|
|
||||||
vbBuffer[offset++] = static_cast<float>(temp.b) / 255.0F;
|
|
||||||
vbBuffer[offset++] = entity->getOpacity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void insertMaskBatch(RenderEntity* entity);
|
|
||||||
void createClearModel ();
|
|
||||||
|
|
||||||
gfx::DescriptorSet* getDescriptorSet(gfx::Texture* texture, gfx::Sampler* sampler, gfx::DescriptorSetLayout* dsLayout);
|
|
||||||
|
|
||||||
StencilManager* _stencilManager{nullptr};
|
|
||||||
|
|
||||||
// weak reference
|
|
||||||
Root* _root{nullptr};
|
|
||||||
// weak reference
|
|
||||||
ccstd::vector<Node*> _rootNodeArr;
|
|
||||||
|
|
||||||
// manage memory manually
|
|
||||||
ccstd::vector<scene::DrawBatch2D*> _batches;
|
|
||||||
memop::Pool<scene::DrawBatch2D> _drawBatchPool;
|
|
||||||
|
|
||||||
// weak reference
|
|
||||||
gfx::Device* _device{nullptr}; // use getDevice()
|
|
||||||
|
|
||||||
// weak reference
|
|
||||||
RenderEntity* _currEntity{nullptr};
|
|
||||||
// weak reference
|
|
||||||
RenderDrawInfo* _currDrawInfo{nullptr};
|
|
||||||
// weak reference
|
|
||||||
UIMeshBuffer* _currMeshBuffer{nullptr};
|
|
||||||
uint32_t _indexStart{0};
|
|
||||||
ccstd::hash_t _currHash{0};
|
|
||||||
uint32_t _currLayer{0};
|
|
||||||
StencilStage _currStencilStage{StencilStage::DISABLED};
|
|
||||||
|
|
||||||
// weak reference
|
|
||||||
Material* _currMaterial{nullptr};
|
|
||||||
// weak reference
|
|
||||||
gfx::Texture* _currTexture{nullptr};
|
|
||||||
// weak reference
|
|
||||||
gfx::Sampler* _currSampler{nullptr};
|
|
||||||
ccstd::hash_t _currSamplerHash{0};
|
|
||||||
|
|
||||||
// weak reference
|
|
||||||
ccstd::vector<RenderDrawInfo*> _meshRenderDrawInfo;
|
|
||||||
|
|
||||||
// manage memory manually
|
|
||||||
ccstd::unordered_map<ccstd::hash_t, gfx::DescriptorSet*> _descriptorSetCache;
|
|
||||||
gfx::DescriptorSetInfo _dsInfo;
|
|
||||||
|
|
||||||
UIMeshBufferMap _meshBuffersMap;
|
|
||||||
|
|
||||||
// DefaultAttribute
|
|
||||||
ccstd::vector<gfx::Attribute> _attributes{
|
|
||||||
gfx::Attribute{gfx::ATTR_NAME_POSITION, gfx::Format::RGB32F},
|
|
||||||
gfx::Attribute{gfx::ATTR_NAME_TEX_COORD, gfx::Format::RG32F},
|
|
||||||
gfx::Attribute{gfx::ATTR_NAME_COLOR, gfx::Format::RGBA32F},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mask use
|
|
||||||
IntrusivePtr<scene::Model> _maskClearModel;
|
|
||||||
IntrusivePtr<Material> _maskClearMtl;
|
|
||||||
IntrusivePtr<RenderingSubMesh> _maskModelMesh;
|
|
||||||
ccstd::vector<gfx::Attribute> _maskAttributes{
|
|
||||||
gfx::Attribute{gfx::ATTR_NAME_POSITION, gfx::Format::RGB32F},
|
|
||||||
};
|
|
||||||
gfx::PrimitiveMode _primitiveMode{gfx::PrimitiveMode::TRIANGLE_LIST};
|
|
||||||
|
|
||||||
CC_DISALLOW_COPY_MOVE_ASSIGN(Batcher2d);
|
|
||||||
};
|
|
||||||
} // namespace cc
|
|
3189
native/engine/lcc-ui-sorting-group-native/backup/CMakeLists.txt
Normal file
3189
native/engine/lcc-ui-sorting-group-native/backup/CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,159 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
Copyright (c) 2019-2021 Xiamen Yaji Software Co., Ltd.
|
|
||||||
|
|
||||||
http://www.cocos.com
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated engine source code (the "Software"), a limited,
|
|
||||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
|
||||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
|
||||||
not use Cocos Creator software for developing other software or tools that's
|
|
||||||
used for developing games. You are not granted to publish, distribute,
|
|
||||||
sublicense, and/or sell copies of Cocos Creator.
|
|
||||||
|
|
||||||
The software or tools in this License Agreement are licensed, not sold.
|
|
||||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
|
||||||
|
|
||||||
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 <array>
|
|
||||||
#include "2d/renderer/RenderDrawInfo.h"
|
|
||||||
#include "2d/renderer/StencilManager.h"
|
|
||||||
#include "base/Macros.h"
|
|
||||||
#include "base/TypeDef.h"
|
|
||||||
#include "bindings/utils/BindingUtils.h"
|
|
||||||
#include "core/ArrayBuffer.h"
|
|
||||||
#include "core/scene-graph/Node.h"
|
|
||||||
|
|
||||||
namespace cc {
|
|
||||||
class Batcher2d;
|
|
||||||
|
|
||||||
enum class RenderEntityType : uint8_t {
|
|
||||||
STATIC,
|
|
||||||
DYNAMIC,
|
|
||||||
CROSSED,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class MaskMode : uint8_t {
|
|
||||||
NONE,
|
|
||||||
MASK,
|
|
||||||
MASK_INVERTED,
|
|
||||||
MASK_NODE,
|
|
||||||
MASK_NODE_INVERTED
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EntityAttrLayout {
|
|
||||||
float localOpacity{1.0F};
|
|
||||||
uint8_t colorR{255};
|
|
||||||
uint8_t colorG{255};
|
|
||||||
uint8_t colorB{255};
|
|
||||||
uint8_t colorA{255};
|
|
||||||
uint8_t maskMode{0};
|
|
||||||
uint8_t colorDirtyBit{1};
|
|
||||||
uint8_t enabledIndex{0};
|
|
||||||
uint8_t useLocal{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
class RenderEntity final : public Node::UserData {
|
|
||||||
public:
|
|
||||||
static constexpr uint32_t STATIC_DRAW_INFO_CAPACITY = 4;
|
|
||||||
|
|
||||||
explicit RenderEntity(RenderEntityType type);
|
|
||||||
~RenderEntity() override;
|
|
||||||
|
|
||||||
void addDynamicRenderDrawInfo(RenderDrawInfo* drawInfo);
|
|
||||||
void setDynamicRenderDrawInfo(RenderDrawInfo* drawInfo, uint32_t index);
|
|
||||||
void removeDynamicRenderDrawInfo();
|
|
||||||
void clearDynamicRenderDrawInfos();
|
|
||||||
void clearStaticRenderDrawInfos();
|
|
||||||
|
|
||||||
inline bool getIsMask() const {
|
|
||||||
return static_cast<MaskMode>(_entityAttrLayout.maskMode) == MaskMode::MASK || static_cast<MaskMode>(_entityAttrLayout.maskMode) == MaskMode::MASK_INVERTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool getIsSubMask() const {
|
|
||||||
return static_cast<MaskMode>(_entityAttrLayout.maskMode) == MaskMode::MASK_NODE || static_cast<MaskMode>(_entityAttrLayout.maskMode) == MaskMode::MASK_NODE_INVERTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool getIsMaskInverted() const {
|
|
||||||
return static_cast<MaskMode>(_entityAttrLayout.maskMode) == MaskMode::MASK_INVERTED || static_cast<MaskMode>(_entityAttrLayout.maskMode) == MaskMode::MASK_NODE_INVERTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool getUseLocal() const { return _entityAttrLayout.useLocal; }
|
|
||||||
inline void setUseLocal(bool useLocal) {
|
|
||||||
_entityAttrLayout.useLocal = useLocal;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Node* getNode() const { return _node; }
|
|
||||||
void setNode(Node* node);
|
|
||||||
|
|
||||||
inline Node* getRenderTransform() const { return _renderTransform; }
|
|
||||||
void setRenderTransform(Node* renderTransform);
|
|
||||||
|
|
||||||
inline uint32_t getStencilStage() const { return static_cast<uint32_t>(_stencilStage); }
|
|
||||||
inline void setStencilStage(uint32_t stage) {
|
|
||||||
_stencilStage = static_cast<StencilStage>(stage);
|
|
||||||
}
|
|
||||||
inline StencilStage getEnumStencilStage() const { return _stencilStage; }
|
|
||||||
inline void setEnumStencilStage(StencilStage stage) {
|
|
||||||
_stencilStage = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline RenderEntityType getRenderEntityType() const { return _renderEntityType; };
|
|
||||||
|
|
||||||
inline uint32_t getStaticDrawInfoSize() const { return _staticDrawInfoSize; };
|
|
||||||
void setStaticDrawInfoSize(uint32_t size);
|
|
||||||
|
|
||||||
RenderDrawInfo* getStaticRenderDrawInfo(uint32_t index);
|
|
||||||
std::array<RenderDrawInfo, RenderEntity::STATIC_DRAW_INFO_CAPACITY>& getStaticRenderDrawInfos();
|
|
||||||
RenderDrawInfo* getDynamicRenderDrawInfo(uint32_t index);
|
|
||||||
ccstd::vector<RenderDrawInfo*>& getDynamicRenderDrawInfos();
|
|
||||||
|
|
||||||
inline se::Object* getEntitySharedBufferForJS() const { return _entitySharedBufferActor.getSharedArrayBufferObject(); }
|
|
||||||
inline bool getColorDirty() const { return _entityAttrLayout.colorDirtyBit != 0; }
|
|
||||||
inline void setColorDirty(bool dirty) { _entityAttrLayout.colorDirtyBit = dirty ? 1 : 0; }
|
|
||||||
inline bool getVBColorDirty() const { return _vbColorDirty; }
|
|
||||||
inline void setVBColorDirty(bool vbColorDirty) { _vbColorDirty = vbColorDirty; }
|
|
||||||
inline Color getColor() const { return Color(_entityAttrLayout.colorR, _entityAttrLayout.colorG, _entityAttrLayout.colorB, _entityAttrLayout.colorA); }
|
|
||||||
inline float getColorAlpha() const { return static_cast<float>(_entityAttrLayout.colorA) / 255.F; }
|
|
||||||
inline float getLocalOpacity() const { return _entityAttrLayout.localOpacity; }
|
|
||||||
inline float getOpacity() const { return _opacity; }
|
|
||||||
inline void setOpacity(float opacity) { _opacity = opacity; }
|
|
||||||
inline bool isEnabled() const { return _entityAttrLayout.enabledIndex != 0; }
|
|
||||||
inline uint32_t getRenderDrawInfosSize() const {
|
|
||||||
return _renderEntityType == RenderEntityType::STATIC ? _staticDrawInfoSize : static_cast<uint32_t>(_dynamicDrawInfos.size());
|
|
||||||
}
|
|
||||||
inline RenderDrawInfo* getRenderDrawInfoAt(uint32_t index) {
|
|
||||||
return _renderEntityType == RenderEntityType::STATIC ? &(_staticDrawInfos[index]) : _dynamicDrawInfos[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CC_DISALLOW_COPY_MOVE_ASSIGN(RenderEntity);
|
|
||||||
// weak reference
|
|
||||||
Node* _node{nullptr};
|
|
||||||
|
|
||||||
// weak reference
|
|
||||||
Node* _renderTransform{nullptr};
|
|
||||||
|
|
||||||
EntityAttrLayout _entityAttrLayout;
|
|
||||||
float _opacity{1.0F};
|
|
||||||
|
|
||||||
bindings::NativeMemorySharedToScriptActor _entitySharedBufferActor;
|
|
||||||
union {
|
|
||||||
std::array<RenderDrawInfo, RenderEntity::STATIC_DRAW_INFO_CAPACITY> _staticDrawInfos;
|
|
||||||
ccstd::vector<RenderDrawInfo*> _dynamicDrawInfos;
|
|
||||||
};
|
|
||||||
StencilStage _stencilStage{StencilStage::DISABLED};
|
|
||||||
RenderEntityType _renderEntityType{RenderEntityType::STATIC};
|
|
||||||
uint8_t _staticDrawInfoSize{0};
|
|
||||||
bool _vbColorDirty{true};
|
|
||||||
};
|
|
||||||
} // namespace cc
|
|
@ -635,7 +635,7 @@ void Batcher2d::createClearModel() {
|
|||||||
void Batcher2d::flushRendererCache() {
|
void Batcher2d::flushRendererCache() {
|
||||||
if(rendererCache.size() > 0){
|
if(rendererCache.size() > 0){
|
||||||
if(rendererOrder){
|
if(rendererOrder){
|
||||||
std::sort(rendererCache.begin(), rendererCache.end(), [](RenderEntity* a, RenderEntity* b) { return a->getSortingPriority() < b->getSortingPriority(); });
|
std::stable_sort(rendererCache.begin(), rendererCache.end(), [](RenderEntity* a, RenderEntity* b) { return a->getSortingPriority() < b->getSortingPriority(); });
|
||||||
}
|
}
|
||||||
// CC_LOG_INFO("flushRendererCache %d", rendererCache.size());
|
// CC_LOG_INFO("flushRendererCache %d", rendererCache.size());
|
||||||
for(ccstd::vector<RenderEntity*>::iterator it = rendererCache.begin(); it != rendererCache.end(); it++)
|
for(ccstd::vector<RenderEntity*>::iterator it = rendererCache.begin(); it != rendererCache.end(); it++)
|
@ -1 +1,7 @@
|
|||||||
cocos creator 3.6.3
|
当前版本: cocos creator 3.6.3
|
||||||
|
|
||||||
|
涉及源文件:
|
||||||
|
cocos/2d/renderer/Batcher2d.h
|
||||||
|
cocos/2d/renderer/Batcher2d.cpp
|
||||||
|
cocos/2d/renderer/RenderEntity.h
|
||||||
|
cocos/2d/renderer/RenderEntity.cpp
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"files.associations": {
|
|
||||||
"array": "cpp",
|
|
||||||
"initializer_list": "cpp",
|
|
||||||
"xutility": "cpp",
|
|
||||||
"algorithm": "cpp"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
Copyright (c) 2019-2021 Xiamen Yaji Software Co., Ltd.
|
|
||||||
|
|
||||||
http://www.cocos.com
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated engine source code (the "Software"), a limited,
|
|
||||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
|
||||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
|
||||||
not use Cocos Creator software for developing other software or tools that's
|
|
||||||
used for developing games. You are not granted to publish, distribute,
|
|
||||||
sublicense, and/or sell copies of Cocos Creator.
|
|
||||||
|
|
||||||
The software or tools in this License Agreement are licensed, not sold.
|
|
||||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
|
||||||
|
|
||||||
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 "2d/renderer/RenderEntity.h"
|
|
||||||
#include "2d/renderer/Batcher2d.h"
|
|
||||||
#include "bindings/utils/BindingUtils.h"
|
|
||||||
|
|
||||||
namespace cc {
|
|
||||||
RenderEntity::RenderEntity(RenderEntityType type) : _renderEntityType(type) {
|
|
||||||
if (type == RenderEntityType::STATIC) {
|
|
||||||
ccnew_placement(&_staticDrawInfos) std::array<RenderDrawInfo, RenderEntity::STATIC_DRAW_INFO_CAPACITY>();
|
|
||||||
} else {
|
|
||||||
ccnew_placement(&_dynamicDrawInfos) ccstd::vector<RenderDrawInfo*>();
|
|
||||||
}
|
|
||||||
_entitySharedBufferActor.initialize(&_entityAttrLayout, sizeof(EntityAttrLayout));
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderEntity::~RenderEntity() {
|
|
||||||
if (_renderEntityType == RenderEntityType::STATIC) {
|
|
||||||
_staticDrawInfos.~array();
|
|
||||||
} else {
|
|
||||||
_dynamicDrawInfos.~vector();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void RenderEntity::addDynamicRenderDrawInfo(RenderDrawInfo* drawInfo) {
|
|
||||||
CC_ASSERT(_renderEntityType != RenderEntityType::STATIC);
|
|
||||||
_dynamicDrawInfos.push_back(drawInfo);
|
|
||||||
}
|
|
||||||
void RenderEntity::setDynamicRenderDrawInfo(RenderDrawInfo* drawInfo, uint32_t index) {
|
|
||||||
CC_ASSERT(_renderEntityType != RenderEntityType::STATIC);
|
|
||||||
if (index < _dynamicDrawInfos.size()) {
|
|
||||||
_dynamicDrawInfos[index] = drawInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void RenderEntity::removeDynamicRenderDrawInfo() {
|
|
||||||
CC_ASSERT(_renderEntityType != RenderEntityType::STATIC);
|
|
||||||
if (_dynamicDrawInfos.empty()) return;
|
|
||||||
_dynamicDrawInfos.pop_back(); // warning: memory leaking & crash
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderEntity::clearDynamicRenderDrawInfos() {
|
|
||||||
CC_ASSERT(_renderEntityType != RenderEntityType::STATIC);
|
|
||||||
_dynamicDrawInfos.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderEntity::clearStaticRenderDrawInfos() {
|
|
||||||
CC_ASSERT(_renderEntityType == RenderEntityType::STATIC);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < _staticDrawInfoSize; i++) {
|
|
||||||
RenderDrawInfo& drawInfo = _staticDrawInfos[i];
|
|
||||||
drawInfo.resetDrawInfo();
|
|
||||||
}
|
|
||||||
_staticDrawInfoSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderEntity::setNode(Node* node) {
|
|
||||||
if (_node) {
|
|
||||||
_node->setUserData(nullptr);
|
|
||||||
}
|
|
||||||
_node = node;
|
|
||||||
if (_node) {
|
|
||||||
_node->setUserData(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderEntity::setRenderTransform(Node* renderTransform) {
|
|
||||||
_renderTransform = renderTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderDrawInfo* RenderEntity::getDynamicRenderDrawInfo(uint32_t index) {
|
|
||||||
CC_ASSERT(_renderEntityType != RenderEntityType::STATIC);
|
|
||||||
if (index >= _dynamicDrawInfos.size()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return _dynamicDrawInfos[index];
|
|
||||||
}
|
|
||||||
ccstd::vector<RenderDrawInfo*>& RenderEntity::getDynamicRenderDrawInfos() {
|
|
||||||
CC_ASSERT(_renderEntityType != RenderEntityType::STATIC);
|
|
||||||
return _dynamicDrawInfos;
|
|
||||||
}
|
|
||||||
void RenderEntity::setStaticDrawInfoSize(uint32_t size) {
|
|
||||||
CC_ASSERT(_renderEntityType == RenderEntityType::STATIC && size <= RenderEntity::STATIC_DRAW_INFO_CAPACITY);
|
|
||||||
_staticDrawInfoSize = size;
|
|
||||||
}
|
|
||||||
RenderDrawInfo* RenderEntity::getStaticRenderDrawInfo(uint32_t index) {
|
|
||||||
CC_ASSERT(_renderEntityType == RenderEntityType::STATIC && index < _staticDrawInfoSize);
|
|
||||||
return &(_staticDrawInfos[index]);
|
|
||||||
}
|
|
||||||
std::array<RenderDrawInfo, RenderEntity::STATIC_DRAW_INFO_CAPACITY>& RenderEntity::getStaticRenderDrawInfos() {
|
|
||||||
CC_ASSERT(_renderEntityType == RenderEntityType::STATIC);
|
|
||||||
return _staticDrawInfos;
|
|
||||||
}
|
|
||||||
} // namespace cc
|
|
43
readme.md
43
readme.md
@ -6,21 +6,44 @@
|
|||||||
# 效果对比
|
# 效果对比
|
||||||
在ScrollView下生成200个项目测试对比。
|
在ScrollView下生成200个项目测试对比。
|
||||||
|
|
||||||
测试平台:web-mobile
|
|
||||||
|
|
||||||
测试设备:HUAWEI P30 Pro
|
测试设备:HUAWEI P30 Pro
|
||||||
|
|
||||||
项目预制体结构:![QQ截图20230205190757|225x258](./docs/images/QQ截图20230205190757.png)
|
项目预制体结构:![QQ截图20230205190757|225x258](./docs/images/QQ截图20230205190757.png)
|
||||||
|
|
||||||
* 未使用UI渲染优化:![Screenshot_20230205_172414|230x500](./docs/images/Screenshot_20230205_172414.jpg)
|
* ## 测试平台:web-mobile
|
||||||
* 使用UI渲染优化:![Screenshot_20230205_172320|230x500](./docs/images/Screenshot_20230205_172320.jpg)
|
|
||||||
|
`未使用UI渲染优化`:![Screenshot_20230205_172414|230x500](./docs/images/Screenshot_20230205_172414.jpg)
|
||||||
|
`使用UI渲染优化`:![Screenshot_20230205_172320|230x500](./docs/images/Screenshot_20230205_172320.jpg)
|
||||||
|
|
||||||
|
* ## 测试平台:android
|
||||||
|
|
||||||
|
`未使用UI渲染优化`:![Screenshot_20230205_172414|230x500](./docs/images/Screenshot_20230207_103552.jpg)
|
||||||
|
`使用UI渲染优化`:![Screenshot_20230205_172320|230x500](./docs/images/Screenshot_20230207_103431.jpg)
|
||||||
|
|
||||||
项目越多,差距越明显。
|
项目越多,差距越明显。
|
||||||
|
|
||||||
# 使用方式 (当前不支持原生平台)
|
# 使用方式
|
||||||
看到标题的时候,相信使用过Unity的同学就差不多知道使用方式了。API设计其实就是照搬的Unity的SortingGroup。使用步骤如下;
|
看到标题的时候,相信使用过Unity的同学就差不多知道使用方式了。API设计其实就是照搬的Unity的SortingGroup。使用步骤如下; (下面用到的扩展包,可以在后面的示例工程中获得)
|
||||||
1. 导入扩展包到项目assets目录内,扩展包其实就是包含了几个ts文件的文件夹(下面会上传示例工程,直接可以在工程里面获得)
|
1. 导入扩展包`lcc-ui-sorting-group`到项目assets目录内
|
||||||
2. 定义排序层枚举,扩展包目录如下 ![QQ截图20230205173234|277x153](./docs/images/QQ截图20230205173234.png) ,打开sorting-define.ts文件,添加或修改SortingLayer枚举
|
|
||||||
|
2. 如果是原生项目,需要进行以下步骤;
|
||||||
|
* 构建原生项目,在根目录生成`native`目录
|
||||||
|
* 导入Native扩展包`lcc-ui-sorting-group-native`到`native/engine`目录下
|
||||||
|
* 检查Native扩展包的`readme.txt`文件,以确保匹配creator版本
|
||||||
|
* 复制`lcc-ui-sorting-group-native/backup/CMakeLists.txt`文件到引擎Native目录替换。主要是引擎的`CMakeLists.txt`文件没有提供自定义接口。扩展包的`CMakeLists.txt`只是添加了部分自定义接口,在删除此插件的时候可以选择保留,不会有其他影响。
|
||||||
|
* 修改`native/engine/common/CMakeLists.txt`文件,在代码`include(${COCOS_X_PATH}/CMakeLists.txt)`上面添加插件配置,具体如下;
|
||||||
|
```
|
||||||
|
...
|
||||||
|
|
||||||
|
# 插件配置 引入lcc-ui-sorting-group native部分
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/../lcc-ui-sorting-group-native/CMakeLists.txt)
|
||||||
|
|
||||||
|
include(${COCOS_X_PATH}/CMakeLists.txt) #在这一行上面插入插件配置
|
||||||
|
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 定义排序层枚举,扩展包目录如下 ![QQ截图20230205173234|277x153](./docs/images/QQ截图20230205173234.png) ,打开sorting-define.ts文件,添加或修改SortingLayer枚举
|
||||||
```
|
```
|
||||||
/**
|
/**
|
||||||
* 排序层级
|
* 排序层级
|
||||||
@ -45,10 +68,10 @@ export enum SortingLayer {
|
|||||||
*/
|
*/
|
||||||
export const ORDER_IN_LAYER_MAX = 100000;
|
export const ORDER_IN_LAYER_MAX = 100000;
|
||||||
```
|
```
|
||||||
3. 在需要排序的UI渲染器上(Sprite或者Label等),添加SortingGroup组件,并设置排序层和排序值 ![QQ截图20230205173334|524x176](./docs/images/QQ截图20230205173334.png)
|
4. 在需要排序的UI渲染器上(Sprite或者Label等),添加SortingGroup组件,并设置排序层和排序值 ![QQ截图20230205173334|524x176](./docs/images/QQ截图20230205173334.png)
|
||||||
和Unity不同的是`Order In Layer`不必是整数,这里可以使用小数。
|
和Unity不同的是`Order In Layer`不必是整数,这里可以使用小数。
|
||||||
不同`Sorting Layer`的情况下,`Sorting Layer`枚举越小越先渲染;相同`Sorting Layer`的情况下,`Order In Layer`的值越小越先渲染。
|
不同`Sorting Layer`的情况下,`Sorting Layer`枚举越小越先渲染;相同`Sorting Layer`的情况下,`Order In Layer`的值越小越先渲染。
|
||||||
|
|
||||||
# 注意
|
# 注意
|
||||||
1. 该扩展包对引擎进行过小改,如果想移除这个功能,在删除扩展包目录后需要重启编辑器。
|
1. 该扩展包对引擎进行过小改,如果想移除这个功能,在删除扩展包目录后需要重启编辑器。
|
||||||
2. 该扩展包应该很长一段时间不会支持原生平台。 看源码的时候感觉3.6的UI渲染系统是临时的,可能官方什么时候是要重构,而且原生平台修改麻烦。
|
2. 由于没有MacOS设备,Native扩展CMakeLists.txt目前只支持Windows平台
|
||||||
|
Loading…
Reference in New Issue
Block a user