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
f9c85e9b81
commit
934207d732
@ -67,6 +67,7 @@ export function UpdateRenderEntity(renderEntity:__private._cocos_2d_renderer_ren
|
|||||||
},
|
},
|
||||||
set: function(value) {
|
set: function(value) {
|
||||||
this._sortingPriority = value;
|
this._sortingPriority = value;
|
||||||
|
// console.log(`JSB sortingPriority ${value}`);
|
||||||
if (JSB) {
|
if (JSB) {
|
||||||
this._floatSharedBuffer[RenderEntityFloatSharedBufferView.sortingPriority] = value;
|
this._floatSharedBuffer[RenderEntityFloatSharedBufferView.sortingPriority] = value;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ if(!('sortingPriority' in UIRenderer.prototype)){
|
|||||||
},
|
},
|
||||||
set: function(value) {
|
set: function(value) {
|
||||||
this._sortingPriority = value;
|
this._sortingPriority = value;
|
||||||
|
this._renderEntity.sortingPriority = value;
|
||||||
},
|
},
|
||||||
enumerable: true
|
enumerable: true
|
||||||
});
|
});
|
||||||
|
@ -66,7 +66,9 @@ UI.prototype.flushRendererCache = function(){
|
|||||||
if(this.rendererOrder){
|
if(this.rendererOrder){
|
||||||
rendererCache.sort((a, b)=>{ return a._sortingPriority - b._sortingPriority; });
|
rendererCache.sort((a, b)=>{ return a._sortingPriority - b._sortingPriority; });
|
||||||
}
|
}
|
||||||
|
// console.log(`flushRendererCache ${rendererCache.length}`);
|
||||||
for(let render of rendererCache){
|
for(let render of rendererCache){
|
||||||
|
// console.log(`${render.node.name} render hash ${render.renderData.dataHash}`);
|
||||||
render.fillBuffers(this);
|
render.fillBuffers(this);
|
||||||
if(render.sortingOpacity >= 0){
|
if(render.sortingOpacity >= 0){
|
||||||
updateOpacity(render.renderData, render.sortingOpacity);
|
updateOpacity(render.renderData, render.sortingOpacity);
|
||||||
|
@ -945,7 +945,7 @@
|
|||||||
"__expectedType__": "cc.SpriteFrame"
|
"__expectedType__": "cc.SpriteFrame"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"listItemMax": 200,
|
"listItemMax": 2,
|
||||||
"_id": "9fuu+PfOFHPqnvdYJwsexB"
|
"_id": "9fuu+PfOFHPqnvdYJwsexB"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
15
native/engine/android/CMakeLists.txt
Normal file
15
native/engine/android/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
|
||||||
|
option(APP_NAME "Project Name" "ui-sorting-group")
|
||||||
|
project(${APP_NAME} CXX)
|
||||||
|
set(CC_LIB_NAME cocos)
|
||||||
|
set(CC_PROJECT_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
set(CC_PROJ_SOURCES)
|
||||||
|
set(CC_COMMON_SOURCES)
|
||||||
|
set(CC_ALL_SOURCES)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/../common/CMakeLists.txt)
|
||||||
|
|
||||||
|
cc_android_before_target(${CC_LIB_NAME})
|
||||||
|
add_library(${CC_LIB_NAME} SHARED ${CC_ALL_SOURCES})
|
||||||
|
cc_android_after_target(${CC_LIB_NAME})
|
1
native/engine/android/Post-service.cmake
Normal file
1
native/engine/android/Post-service.cmake
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Supported for Cocos Service!
|
1
native/engine/android/Pre-service.cmake
Normal file
1
native/engine/android/Pre-service.cmake
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Supported for Cocos Service!
|
43
native/engine/android/app/AndroidManifest.xml
Normal file
43
native/engine/android/app/AndroidManifest.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.lcc.test"
|
||||||
|
android:installLocation="auto">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:extractNativeLibs="true"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:usesCleartextTraffic="true"
|
||||||
|
android:icon="@mipmap/ic_launcher">
|
||||||
|
|
||||||
|
<!-- Tell CocosNativeActivity the name of our .so -->
|
||||||
|
<meta-data android:name="android.app.lib_name"
|
||||||
|
android:value="cocos" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.cocos.game.AppActivity"
|
||||||
|
android:screenOrientation="sensorLandscape"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:exported="true">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name="com.cocos.lib.CocosEditBoxActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
|
||||||
|
android:screenOrientation="behind"
|
||||||
|
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
104
native/engine/android/app/build.gradle
Normal file
104
native/engine/android/app/build.gradle
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
RES_PATH = RES_PATH.replace("\\", "/")
|
||||||
|
COCOS_ENGINE_PATH = COCOS_ENGINE_PATH.replace("\\", "/")
|
||||||
|
|
||||||
|
buildDir = "${RES_PATH}/proj/build/$project.name"
|
||||||
|
android {
|
||||||
|
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||||
|
buildToolsVersion PROP_BUILD_TOOLS_VERSION
|
||||||
|
ndkPath PROP_NDK_PATH
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId APPLICATION_ID
|
||||||
|
minSdkVersion PROP_MIN_SDK_VERSION
|
||||||
|
targetSdkVersion PROP_TARGET_SDK_VERSION
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
targets "cocos"
|
||||||
|
arguments "-DRES_DIR=${RES_PATH}", "-DCOCOS_X_PATH=${COCOS_ENGINE_PATH}", "-DANDROID_STL=c++_static", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_NEON=TRUE", "-DANDROID_LD=gold"
|
||||||
|
}
|
||||||
|
ndk { abiFilters PROP_APP_ABI.split(':') }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.main {
|
||||||
|
java.srcDirs "../src", "src"
|
||||||
|
res.srcDirs "../res", 'res'
|
||||||
|
jniLibs.srcDirs "../libs", 'libs'
|
||||||
|
manifest.srcFile "AndroidManifest.xml"
|
||||||
|
assets.srcDir "${RES_PATH}/data"
|
||||||
|
jniLibs {
|
||||||
|
// Vulkan validation layer
|
||||||
|
// srcDir "${android.ndkDirectory}/sources/third_party/vulkan/src/build-android/jniLibs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
path "../CMakeLists.txt"
|
||||||
|
buildStagingDirectory "${RES_PATH}/proj/build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
|
||||||
|
release {
|
||||||
|
if (project.hasProperty("RELEASE_STORE_FILE") && !RELEASE_STORE_FILE.isEmpty()) {
|
||||||
|
storeFile file(RELEASE_STORE_FILE)
|
||||||
|
storePassword RELEASE_STORE_PASSWORD
|
||||||
|
keyAlias RELEASE_KEY_ALIAS
|
||||||
|
keyPassword RELEASE_KEY_PASSWORD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
debuggable false
|
||||||
|
jniDebuggable false
|
||||||
|
renderscriptDebuggable false
|
||||||
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
if (project.hasProperty("RELEASE_STORE_FILE")) {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
// switch HIDE_SYMBOLS to OFF to skip compilation flag `-fvisibility=hidden`
|
||||||
|
arguments "-DHIDE_SYMBOLS=ON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// resValue "string", "app_name", PROP_APP_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
debug {
|
||||||
|
debuggable true
|
||||||
|
jniDebuggable true
|
||||||
|
renderscriptDebuggable true
|
||||||
|
// resValue "string", "app_name", "${PROP_APP_NAME}-dbg"
|
||||||
|
// applicationIdSuffix ".debug"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: '../libs', include: ['*.jar','*.aar'])
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
|
||||||
|
implementation fileTree(dir: "${COCOS_ENGINE_PATH}/cocos/platform/android/java/libs", include: ['*.jar'])
|
||||||
|
implementation project(':libservice')
|
||||||
|
implementation project(':libcocos')
|
||||||
|
}
|
42
native/engine/android/app/proguard-rules.pro
vendored
Normal file
42
native/engine/android/app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in E:\developSoftware\Android\SDK/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Proguard Cocos2d-x-lite for release
|
||||||
|
-keep public class com.cocos.** { *; }
|
||||||
|
-dontwarn com.cocos.**
|
||||||
|
|
||||||
|
# Proguard Apache HTTP for release
|
||||||
|
-keep class org.apache.http.** { *; }
|
||||||
|
-dontwarn org.apache.http.**
|
||||||
|
|
||||||
|
# Proguard okhttp for release
|
||||||
|
-keep class okhttp3.** { *; }
|
||||||
|
-dontwarn okhttp3.**
|
||||||
|
|
||||||
|
-keep class okio.** { *; }
|
||||||
|
-dontwarn okio.**
|
||||||
|
|
||||||
|
# Proguard Android Webivew for release. you can comment if you are not using a webview
|
||||||
|
-keep public class android.net.http.SslError
|
||||||
|
-keep public class android.webkit.WebViewClient
|
||||||
|
|
||||||
|
-keep public class com.google.** { *; }
|
||||||
|
|
||||||
|
-dontwarn android.webkit.WebView
|
||||||
|
-dontwarn android.net.http.SslError
|
||||||
|
-dontwarn android.webkit.WebViewClient
|
125
native/engine/android/app/src/com/cocos/game/AppActivity.java
Normal file
125
native/engine/android/app/src/com/cocos/game/AppActivity.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2015-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-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.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.game;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
|
||||||
|
import com.cocos.service.SDKWrapper;
|
||||||
|
import com.cocos.lib.CocosActivity;
|
||||||
|
|
||||||
|
public class AppActivity extends CocosActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
// DO OTHER INITIALIZATION BELOW
|
||||||
|
SDKWrapper.shared().init(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
SDKWrapper.shared().onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
SDKWrapper.shared().onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
// Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
|
||||||
|
if (!isTaskRoot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SDKWrapper.shared().onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
SDKWrapper.shared().onActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNewIntent(Intent intent) {
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
SDKWrapper.shared().onNewIntent(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart() {
|
||||||
|
super.onRestart();
|
||||||
|
SDKWrapper.shared().onRestart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
SDKWrapper.shared().onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
SDKWrapper.shared().onBackPressed();
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
SDKWrapper.shared().onConfigurationChanged(newConfig);
|
||||||
|
super.onConfigurationChanged(newConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||||
|
SDKWrapper.shared().onRestoreInstanceState(savedInstanceState);
|
||||||
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
|
SDKWrapper.shared().onSaveInstanceState(outState);
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
SDKWrapper.shared().onStart();
|
||||||
|
super.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLowMemory() {
|
||||||
|
SDKWrapper.shared().onLowMemory();
|
||||||
|
super.onLowMemory();
|
||||||
|
}
|
||||||
|
}
|
8
native/engine/android/build-cfg.json
Normal file
8
native/engine/android/build-cfg.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"ndk_module_path" :[
|
||||||
|
"${COCOS_ROOT}",
|
||||||
|
"${COCOS_ROOT}/cocos",
|
||||||
|
"${COCOS_ROOT}/external"
|
||||||
|
],
|
||||||
|
"copy_resources": []
|
||||||
|
}
|
31
native/engine/android/build.gradle
Normal file
31
native/engine/android/build.gradle
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
// jcenter() // keeped as anchor, will be removed soon
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
// jcenter() // keeped as anchor, will be removed soon
|
||||||
|
flatDir {
|
||||||
|
dirs 'libs'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
53
native/engine/android/instantapp/AndroidManifest.xml
Normal file
53
native/engine/android/instantapp/AndroidManifest.xml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:dist="http://schemas.android.com/apk/distribution"
|
||||||
|
package="com.lcc.test"
|
||||||
|
android:installLocation="auto">
|
||||||
|
<dist:module dist:instant="true" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:extractNativeLibs="true"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:icon="@mipmap/ic_launcher">
|
||||||
|
<meta-data
|
||||||
|
android:name="aia-compat-api-min-version"
|
||||||
|
android:value="1" />
|
||||||
|
<!-- Tell CocosNativeActivity the name of our .so -->
|
||||||
|
<meta-data android:name="android.app.lib_name"
|
||||||
|
android:value="cocos" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.cocos.game.InstantActivity"
|
||||||
|
android:screenOrientation="sensorLandscape"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:exported="true">
|
||||||
|
|
||||||
|
<intent-filter android:order="1">
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name="com.cocos.lib.CocosEditBoxActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
|
||||||
|
android:screenOrientation="behind"
|
||||||
|
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
101
native/engine/android/instantapp/build.gradle
Normal file
101
native/engine/android/instantapp/build.gradle
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
RES_PATH = RES_PATH.replace("\\", "/")
|
||||||
|
COCOS_ENGINE_PATH = COCOS_ENGINE_PATH.replace("\\", "/")
|
||||||
|
buildDir = "${RES_PATH}/proj/build/$project.name"
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||||
|
buildToolsVersion PROP_BUILD_TOOLS_VERSION
|
||||||
|
ndkPath PROP_NDK_PATH
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.lcc.test"
|
||||||
|
minSdkVersion PROP_MIN_SDK_VERSION
|
||||||
|
targetSdkVersion PROP_TARGET_SDK_VERSION
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
targets "cocos"
|
||||||
|
arguments "-DRES_DIR=${RES_PATH}", "-DCOCOS_X_PATH=${COCOS_ENGINE_PATH}","-DANDROID_STL=c++_static", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_NEON=TRUE", "-DANDROID_LD=gold"
|
||||||
|
cppFlags "-frtti -fexceptions -fsigned-char -DANDROID_INSTANT=1"
|
||||||
|
}
|
||||||
|
ndk { abiFilters PROP_APP_ABI.split(':') }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.main {
|
||||||
|
java.srcDirs "../src", "src"
|
||||||
|
res.srcDirs "../res", 'res'
|
||||||
|
jniLibs.srcDirs "../libs", 'libs'
|
||||||
|
manifest.srcFile "AndroidManifest.xml"
|
||||||
|
assets.srcDir "${RES_PATH}/data"
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
path "../CMakeLists.txt"
|
||||||
|
buildStagingDirectory "${RES_PATH}/proj/build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
|
||||||
|
release {
|
||||||
|
if (project.hasProperty("RELEASE_STORE_FILE") && !RELEASE_STORE_FILE.isEmpty()) {
|
||||||
|
storeFile file(RELEASE_STORE_FILE)
|
||||||
|
storePassword RELEASE_STORE_PASSWORD
|
||||||
|
keyAlias RELEASE_KEY_ALIAS
|
||||||
|
keyPassword RELEASE_KEY_PASSWORD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
debuggable false
|
||||||
|
jniDebuggable false
|
||||||
|
renderscriptDebuggable false
|
||||||
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
if (project.hasProperty("RELEASE_STORE_FILE")) {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
// switch HIDE_SYMBOLS to OFF to skip compilation flag `-fvisibility=hidden`
|
||||||
|
arguments "-DHIDE_SYMBOLS=ON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// resValue "string", "app_name", PROP_APP_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
debug {
|
||||||
|
debuggable true
|
||||||
|
jniDebuggable true
|
||||||
|
renderscriptDebuggable true
|
||||||
|
// resValue "string", "app_name", "${PROP_APP_NAME}-dbg"
|
||||||
|
// applicationIdSuffix ".debug"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: '../libs', include: ['*.jar','*.aar'])
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
|
||||||
|
implementation fileTree(dir: "${COCOS_ENGINE_PATH}/cocos/platform/android/java/libs", include: ['*.jar'])
|
||||||
|
implementation project(':libservice')
|
||||||
|
implementation project(':libcocos')
|
||||||
|
}
|
42
native/engine/android/instantapp/proguard-rules.pro
vendored
Normal file
42
native/engine/android/instantapp/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in E:\developSoftware\Android\SDK/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Proguard Cocos2d-x-lite for release
|
||||||
|
-keep public class com.cocos.** { *; }
|
||||||
|
-dontwarn com.cocos.**
|
||||||
|
|
||||||
|
# Proguard Apache HTTP for release
|
||||||
|
-keep class org.apache.http.** { *; }
|
||||||
|
-dontwarn org.apache.http.**
|
||||||
|
|
||||||
|
# Proguard okhttp for release
|
||||||
|
-keep class okhttp3.** { *; }
|
||||||
|
-dontwarn okhttp3.**
|
||||||
|
|
||||||
|
-keep class okio.** { *; }
|
||||||
|
-dontwarn okio.**
|
||||||
|
|
||||||
|
# Proguard Android Webivew for release. you can comment if you are not using a webview
|
||||||
|
-keep public class android.net.http.SslError
|
||||||
|
-keep public class android.webkit.WebViewClient
|
||||||
|
|
||||||
|
-keep public class com.google.** { *; }
|
||||||
|
|
||||||
|
-dontwarn android.webkit.WebView
|
||||||
|
-dontwarn android.net.http.SslError
|
||||||
|
-dontwarn android.webkit.WebViewClient
|
@ -0,0 +1,125 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2015-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-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.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.game;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
|
||||||
|
import com.cocos.service.SDKWrapper;
|
||||||
|
import com.cocos.lib.CocosActivity;
|
||||||
|
|
||||||
|
public class InstantActivity extends CocosActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
// DO OTHER INITIALIZATION BELOW
|
||||||
|
SDKWrapper.shared().init(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
SDKWrapper.shared().onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
SDKWrapper.shared().onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
// Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
|
||||||
|
if (!isTaskRoot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SDKWrapper.shared().onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
SDKWrapper.shared().onActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onNewIntent(Intent intent) {
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
SDKWrapper.shared().onNewIntent(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart() {
|
||||||
|
super.onRestart();
|
||||||
|
SDKWrapper.shared().onRestart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
SDKWrapper.shared().onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
SDKWrapper.shared().onBackPressed();
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
SDKWrapper.shared().onConfigurationChanged(newConfig);
|
||||||
|
super.onConfigurationChanged(newConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||||
|
SDKWrapper.shared().onRestoreInstanceState(savedInstanceState);
|
||||||
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
|
SDKWrapper.shared().onSaveInstanceState(outState);
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
SDKWrapper.shared().onStart();
|
||||||
|
super.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLowMemory() {
|
||||||
|
SDKWrapper.shared().onLowMemory();
|
||||||
|
super.onLowMemory();
|
||||||
|
}
|
||||||
|
}
|
BIN
native/engine/android/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
native/engine/android/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
BIN
native/engine/android/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
native/engine/android/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
native/engine/android/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
native/engine/android/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
BIN
native/engine/android/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
native/engine/android/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
native/engine/android/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
native/engine/android/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
3
native/engine/android/res/values/strings.xml
Normal file
3
native/engine/android/res/values/strings.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name" translatable="false">ui-sorting-group</string>
|
||||||
|
</resources>
|
54
native/engine/common/CMakeLists.txt
Normal file
54
native/engine/common/CMakeLists.txt
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
enable_language(C ASM)
|
||||||
|
set(DEVELOPMENT_TEAM "" CACHE STRING "APPLE Developtment Team")
|
||||||
|
set(RES_DIR "" CACHE STRING "Resource path")
|
||||||
|
set(COCOS_X_PATH "" CACHE STRING "Path to engine/native/")
|
||||||
|
|
||||||
|
set(TARGET_OSX_VERSION "10.14" CACHE STRING "Target MacOSX version" FORCE)
|
||||||
|
set(TARGET_IOS_VERSION "11.0" CACHE STRING "Target iOS version" FORCE)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
option(CC_DEBUG_FORCE "Force enable CC_DEBUG in release mode" OFF)
|
||||||
|
option(USE_SE_V8 "Use V8 JavaScript Engine" ON)
|
||||||
|
option(USE_V8_DEBUGGER "Compile v8 inspector ws server" ON)
|
||||||
|
option(USE_V8_DEBUGGER_FORCE "Force enable debugger in release mode" OFF)
|
||||||
|
option(USE_SOCKET "Enable WebSocket & SocketIO" ON)
|
||||||
|
option(USE_AUDIO "Enable Audio" ON) #Enable AudioEngine
|
||||||
|
option(USE_EDIT_BOX "Enable EditBox" ON)
|
||||||
|
option(USE_SE_JSC "Use JavaScriptCore on MacOSX/iOS" OFF)
|
||||||
|
option(USE_VIDEO "Enable VideoPlayer Component" ON)
|
||||||
|
option(USE_WEBVIEW "Enable WebView Component" ON)
|
||||||
|
option(USE_MIDDLEWARE "Enable Middleware" ON)
|
||||||
|
option(USE_DRAGONBONES "Enable Dragonbones" ON)
|
||||||
|
option(USE_SPINE "Enable Spine" ON)
|
||||||
|
option(USE_WEBSOCKET_SERVER "Enable WebSocket Server" OFF)
|
||||||
|
option(USE_JOB_SYSTEM_TASKFLOW "Use taskflow as job system backend" OFF)
|
||||||
|
option(USE_JOB_SYSTEM_TBB "Use tbb as job system backend" OFF)
|
||||||
|
option(USE_PHYSICS_PHYSX "Use PhysX Physics" ON)
|
||||||
|
option(USE_OCCLUSION_QUERY "Use Occlusion Query" ON)
|
||||||
|
option(USE_DEBUG_RENDERER "Use Debug Renderer" ON)
|
||||||
|
option(USE_GEOMETRY_RENDERER "Use Geometry Renderer" ON)
|
||||||
|
option(USE_WEBP "Use Webp" ON)
|
||||||
|
|
||||||
|
if(NOT RES_DIR)
|
||||||
|
message(FATAL_ERROR "RES_DIR is not set!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(${RES_DIR}/proj/cfg.cmake)
|
||||||
|
|
||||||
|
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/localCfg.cmake)
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/localCfg.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT COCOS_X_PATH)
|
||||||
|
message(FATAL_ERROR "COCOS_X_PATH is not set!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(${COCOS_X_PATH}/CMakeLists.txt)
|
||||||
|
|
||||||
|
list(APPEND CC_COMMON_SOURCES
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/Classes/Game.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/Classes/Game.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# 引入lcc-ui-sorting-group native部分
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/../lcc-ui-sorting-group-native/CMakeLists.txt)
|
65
native/engine/common/Classes/Game.cpp
Normal file
65
native/engine/common/Classes/Game.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2017-2018 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 "Game.h"
|
||||||
|
|
||||||
|
#ifndef GAME_NAME
|
||||||
|
#define GAME_NAME "CocosGame";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SCRIPT_XXTEAKEY
|
||||||
|
#define SCRIPT_XXTEAKEY "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Game::Game() = default;
|
||||||
|
|
||||||
|
int Game::init() {
|
||||||
|
_windowInfo.title = GAME_NAME;
|
||||||
|
// configurate window size
|
||||||
|
// _windowInfo.height = 600;
|
||||||
|
// _windowInfo.width = 800;
|
||||||
|
|
||||||
|
#if CC_DEBUG
|
||||||
|
_debuggerInfo.enabled = true;
|
||||||
|
#else
|
||||||
|
_debuggerInfo.enabled = false;
|
||||||
|
#endif
|
||||||
|
_debuggerInfo.port = 6086;
|
||||||
|
_debuggerInfo.address = "0.0.0.0";
|
||||||
|
_debuggerInfo.pauseOnStart = false;
|
||||||
|
|
||||||
|
_xxteaKey = SCRIPT_XXTEAKEY;
|
||||||
|
|
||||||
|
BaseGame::init();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::onPause() { BaseGame::onPause(); }
|
||||||
|
|
||||||
|
void Game::onResume() { BaseGame::onResume(); }
|
||||||
|
|
||||||
|
void Game::onClose() { BaseGame::onClose(); }
|
||||||
|
|
||||||
|
CC_REGISTER_APPLICATION(Game);
|
44
native/engine/common/Classes/Game.h
Normal file
44
native/engine/common/Classes/Game.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2018 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 "cocos/cocos.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief The cocos2d Application.
|
||||||
|
|
||||||
|
The reason for implement as private inheritance is to hide some interface call
|
||||||
|
by Director.
|
||||||
|
*/
|
||||||
|
class Game : public cc::BaseGame {
|
||||||
|
public:
|
||||||
|
Game();
|
||||||
|
int init() override;
|
||||||
|
// bool init() override;
|
||||||
|
void onPause() override;
|
||||||
|
void onResume() override;
|
||||||
|
void onClose() override;
|
||||||
|
};
|
1
native/engine/common/cocos-version.json
Normal file
1
native/engine/common/cocos-version.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":"3.6.3","skipCheck":false}
|
3
native/engine/common/localCfg.cmake
Normal file
3
native/engine/common/localCfg.cmake
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
## Add or overwrite options from cfg.cmake.
|
||||||
|
## This file is ignored from git.
|
||||||
|
# set(NODE_EXECUTABLE /opt/...)
|
29
native/engine/lcc-ui-sorting-group-native/CMakeLists.txt
Normal file
29
native/engine/lcc-ui-sorting-group-native/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
string(REPLACE "/" "\\" CMD_COCOS_X_PATH "${COCOS_X_PATH}")
|
||||||
|
string(REPLACE "/" "\\" CMD_CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||||
|
|
||||||
|
# 引擎编译添加源文件替换依赖目标
|
||||||
|
add_custom_command(
|
||||||
|
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.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.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.cpp\""
|
||||||
|
COMMAND echo "ENGINE_REPLACE" >> "${CMD_CMAKE_CURRENT_LIST_DIR}\\ENGINE_REPLACE.txt"
|
||||||
|
COMMAND echo "LCC_UI_SORTING_GROUP pre"
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
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_custom_command(TARGET ${ENGINE_NAME}
|
||||||
|
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.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.cpp\"" "\"${CMD_COCOS_X_PATH}\\cocos\\2d\\renderer\\RenderEntity.cpp\""
|
||||||
|
COMMAND del "${CMD_CMAKE_CURRENT_LIST_DIR}\\ENGINE_REPLACE.txt"
|
||||||
|
COMMAND echo "LCC_UI_SORTING_GROUP post"
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
609
native/engine/lcc-ui-sorting-group-native/backup/Batcher2d.cpp
Normal file
609
native/engine/lcc-ui-sorting-group-native/backup/Batcher2d.cpp
Normal file
@ -0,0 +1,609 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
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
|
203
native/engine/lcc-ui-sorting-group-native/backup/Batcher2d.h
Normal file
203
native/engine/lcc-ui-sorting-group-native/backup/Batcher2d.h
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
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
|
@ -0,0 +1,116 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
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
|
159
native/engine/lcc-ui-sorting-group-native/backup/RenderEntity.h
Normal file
159
native/engine/lcc-ui-sorting-group-native/backup/RenderEntity.h
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
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
|
1
native/engine/lcc-ui-sorting-group-native/readme.txt
Normal file
1
native/engine/lcc-ui-sorting-group-native/readme.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
cocos creator 3.6.3
|
8
native/engine/lcc-ui-sorting-group-native/replace/.vscode/settings.json
vendored
Normal file
8
native/engine/lcc-ui-sorting-group-native/replace/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"xutility": "cpp",
|
||||||
|
"algorithm": "cpp"
|
||||||
|
}
|
||||||
|
}
|
657
native/engine/lcc-ui-sorting-group-native/replace/Batcher2d.cpp
Normal file
657
native/engine/lcc-ui-sorting-group-native/replace/Batcher2d.cpp
Normal file
@ -0,0 +1,657 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
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"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
// LCC_UI_SORTING_GROUP
|
||||||
|
rendererCache.reserve(1024);
|
||||||
|
rendererOrder = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
// CC_LOG_INFO("-------------- flushRendererCache 1 -------------- %d", _rootNodeArr.size());
|
||||||
|
flushRendererCache(); // LCC_UI_SORTING_GROUP
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LCC_UI_SORTING_GROUP
|
||||||
|
if (entity->isEnabled()) {
|
||||||
|
if(entity->getIsMask()){
|
||||||
|
// CC_LOG_INFO("-------------- flushRendererCache 2 --------------");
|
||||||
|
flushRendererCache();
|
||||||
|
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);
|
||||||
|
}else{
|
||||||
|
rendererCache.push_back(entity);
|
||||||
|
if(entity->getSortingPriority() != 0){
|
||||||
|
rendererOrder = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
// CC_LOG_INFO("-------------- flushRendererCache 3 --------------");
|
||||||
|
flushRendererCache(); // LCC_UI_SORTING_GROUP
|
||||||
|
|
||||||
|
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) {
|
||||||
|
// CC_LOG_INFO("handleComponentDraw break %u-%u %p-%p %d-%d", _currHash,dataHash, _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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LCC_UI_SORTING_GROUP
|
||||||
|
void Batcher2d::flushRendererCache() {
|
||||||
|
if(rendererCache.size() > 0){
|
||||||
|
if(rendererOrder){
|
||||||
|
std::sort(rendererCache.begin(), rendererCache.end(), [](RenderEntity* a, RenderEntity* b) { return a->getSortingPriority() < b->getSortingPriority(); });
|
||||||
|
}
|
||||||
|
// CC_LOG_INFO("flushRendererCache %d", rendererCache.size());
|
||||||
|
for(ccstd::vector<RenderEntity*>::iterator it = rendererCache.begin(); it != rendererCache.end(); it++)
|
||||||
|
{
|
||||||
|
RenderEntity* entity = *it;
|
||||||
|
// CC_LOG_INFO("%f", entity->getSortingPriority());
|
||||||
|
uint32_t size = entity->getRenderDrawInfosSize();
|
||||||
|
for (uint32_t i = 0; i < size; i++) {
|
||||||
|
auto* drawInfo = entity->getRenderDrawInfoAt(i);
|
||||||
|
handleDrawInfo(entity, drawInfo, entity->getNode());
|
||||||
|
}
|
||||||
|
entity->setVBColorDirty(false);
|
||||||
|
}
|
||||||
|
rendererCache.clear();
|
||||||
|
}
|
||||||
|
rendererOrder = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cc
|
208
native/engine/lcc-ui-sorting-group-native/replace/Batcher2d.h
Normal file
208
native/engine/lcc-ui-sorting-group-native/replace/Batcher2d.h
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
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 ();
|
||||||
|
|
||||||
|
// LCC_UI_SORTING_GROUP
|
||||||
|
ccstd::vector<RenderEntity*> rendererCache;
|
||||||
|
bool rendererOrder;
|
||||||
|
void flushRendererCache();
|
||||||
|
|
||||||
|
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
|
@ -0,0 +1,116 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
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
|
161
native/engine/lcc-ui-sorting-group-native/replace/RenderEntity.h
Normal file
161
native/engine/lcc-ui-sorting-group-native/replace/RenderEntity.h
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
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};
|
||||||
|
float sortingPriority{0.0F}; // LCC_UI_SORTING_GROUP
|
||||||
|
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 getSortingPriority() const { return _entityAttrLayout.sortingPriority; } // LCC_UI_SORTING_GROUP
|
||||||
|
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
|
Loading…
Reference in New Issue
Block a user