1. 完全解耦了Live2D的LApp部分,使其可以接入任何GUI库
2. 初步尝试合并嵌入式Linux平台支持的相关代码,预计在下一次提交完整支持。
This commit is contained in:
@@ -0,0 +1,195 @@
|
|||||||
|
## Framework模块说明
|
||||||
|
|
||||||
|
由于嵌入式Linux的硬件差异性导致的不同嵌入式板子的sysroot不同,导致不同的板子环境差异很大,
|
||||||
|
因此对于framework这个模块,需要自行根据自己板子的sysroot或者sdk进行交叉编译。
|
||||||
|
|
||||||
|
#### 如何交叉编译Framework模块
|
||||||
|
在本项目当中,有一个适用于rk3566的framework模块,
|
||||||
|
因为framework模块一般不会使用到一些特别的硬件或者是后端(音频后端之类的),
|
||||||
|
所以理论上其他rk3566的板子也可以使用我预编译的模块。
|
||||||
|
|
||||||
|
给出交叉编译步骤(以编译我的rk3566为例):
|
||||||
|
```shell
|
||||||
|
cmake -S ../Framework -B . \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=~/MisakiCodes/Env/rk3566-sdk/qt_toolchain.cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug \
|
||||||
|
-DFRAMEWORK_SOURCE=OpenGL \
|
||||||
|
-DRENDER_INCLUDE_PATH="${CMAKE_SOURCE_DIR}/Framework/src/Rendering/OpenGL" \
|
||||||
|
-DFRAMEWORK_DEFINITIOINS="CSM_TARGET_HARMONYOS_ES3"
|
||||||
|
```
|
||||||
|
|
||||||
|
预期的配置输出:
|
||||||
|
```shell
|
||||||
|
CMake Warning (dev) in CMakeLists.txt:
|
||||||
|
No project() command is present. The top-level CMakeLists.txt file must
|
||||||
|
contain a literal, direct call to the project() command. Add a line of
|
||||||
|
code such as
|
||||||
|
|
||||||
|
project(ProjectName)
|
||||||
|
|
||||||
|
near the top of the file, but after cmake_minimum_required().
|
||||||
|
|
||||||
|
CMake is pretending there is a "project(Project)" command on the first
|
||||||
|
line.
|
||||||
|
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||||
|
|
||||||
|
CMake Warning (dev) in CMakeLists.txt:
|
||||||
|
cmake_minimum_required() should be called prior to this top-level project()
|
||||||
|
call. Please see the cmake-commands(7) manual for usage documentation of
|
||||||
|
both commands.
|
||||||
|
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||||
|
|
||||||
|
-- The C compiler identification is GNU 12.3.0
|
||||||
|
-- The CXX compiler identification is GNU 12.3.0
|
||||||
|
-- Detecting C compiler ABI info
|
||||||
|
-- Detecting C compiler ABI info - done
|
||||||
|
-- Check for working C compiler: /home/misaki/MisakiCodes/Env/rk3566-sdk/toolchain/aarch64--glibc--stable-2023.08-1/bin/aarch64-linux-gcc - skipped
|
||||||
|
-- Detecting C compile features
|
||||||
|
-- Detecting C compile features - done
|
||||||
|
-- Detecting CXX compiler ABI info
|
||||||
|
-- Detecting CXX compiler ABI info - done
|
||||||
|
-- Check for working CXX compiler: /home/misaki/MisakiCodes/Env/rk3566-sdk/toolchain/aarch64--glibc--stable-2023.08-1/bin/aarch64-linux-g++ - skipped
|
||||||
|
-- Detecting CXX compile features
|
||||||
|
-- Detecting CXX compile features - done
|
||||||
|
-- Configuring done (0.5s)
|
||||||
|
-- Generating done (0.0s)
|
||||||
|
-- Build files have been written to: /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/build_framework
|
||||||
|
```
|
||||||
|
|
||||||
|
观察上述命令可知,首先你肯定需要准备Live2D的SDK,这可以在官网下载,不在此过多赘述。
|
||||||
|
|
||||||
|
接着在与Framework的同级目录下新建一个xxx_build目录,如果你不知道这是什么,那么最好借助一下AI来帮助你。
|
||||||
|
|
||||||
|
之后就是cd到build目录里面。
|
||||||
|
|
||||||
|
Framework模块承担了Live2D的很多功能,其中唯一一个平台有关的就是Render模块,
|
||||||
|
也就是渲染功能,不过Live2D的库的渲染部分写的比较好,统一使用了OpenGL ES,同时兼容主机平台和arm移动平台。
|
||||||
|
|
||||||
|
你需要准备一个编译工具链,也就toolchain.cmake脚本的内容,这个编译工具链描述了编译器信息,sysroot信息等等。
|
||||||
|
下面给出我自己的工具链作为参考。
|
||||||
|
```cmake
|
||||||
|
set(CMAKE_SYSTEM_NAME Linux)
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||||
|
|
||||||
|
set(TOOLCHAIN_ROOT /home/misaki/MisakiCodes/Env/rk3566-sdk/toolchain/aarch64--glibc--stable-2023.08-1)
|
||||||
|
set(CMAKE_C_COMPILER ${TOOLCHAIN_ROOT}/bin/aarch64-linux-gcc)
|
||||||
|
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_ROOT}/bin/aarch64-linux-g++)
|
||||||
|
set(CMAKE_AR ${TOOLCHAIN_ROOT}/bin/aarch64-linux-ar)
|
||||||
|
set(CMAKE_RANLIB ${TOOLCHAIN_ROOT}/bin/aarch64-linux-ranlib)
|
||||||
|
set(CMAKE_STRIP ${TOOLCHAIN_ROOT}/bin/aarch64-linux-strip)
|
||||||
|
|
||||||
|
set(SYSROOT /home/misaki/MisakiCodes/Env/rk3566-sdk/host/aarch64-buildroot-linux-gnu/sysroot)
|
||||||
|
set(VPET_SDK /home/misaki/MisakiCodes/Env/rk3566-sdk/vpet-deps)
|
||||||
|
set(QT_HOST_PATH /home/misaki/Qt/6.6.3/gcc_64)
|
||||||
|
|
||||||
|
set(CMAKE_FIND_ROOT_PATH ${SYSROOT} ${VPET_SDK})
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) # 不使用only,否则会导致CMake找不到其他库的包,例如Qt的,会直接导致FindPackage失效,只能找sysroot里面的包
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "-march=armv8.2-a -mtune=cortex-a55 -O2 -pipe --sysroot=${SYSROOT}")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++17")
|
||||||
|
|
||||||
|
# === 关键:强制链接 Mali 驱动和 EGL/GLES ===
|
||||||
|
set(MALI_LIBS "-lmali-hook -Wl,--whole-archive -lmali-hook-injector -Wl,--no-whole-archive -lmali -ldrm")
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS
|
||||||
|
"-Wl,-dynamic-linker=/lib/ld-linux-aarch64.so.1 \
|
||||||
|
-Wl,-rpath,/data/vpet/deps/lib:/usr/lib:/lib \
|
||||||
|
--sysroot=${SYSROOT} \
|
||||||
|
${MALI_LIBS}"
|
||||||
|
)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
|
||||||
|
# === 包含路径 ===
|
||||||
|
include_directories(
|
||||||
|
${VPET_SDK}/include
|
||||||
|
${VPET_SDK}/include/libdrm
|
||||||
|
${SYSROOT}/usr/include
|
||||||
|
)
|
||||||
|
|
||||||
|
# === 库路径 ===
|
||||||
|
link_directories(
|
||||||
|
${VPET_SDK}/lib
|
||||||
|
${SYSROOT}/usr/lib
|
||||||
|
${SYSROOT}/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
# === pkg-config ===
|
||||||
|
set(ENV{PKG_CONFIG} "/usr/bin/pkg-config")
|
||||||
|
set(ENV{PKG_CONFIG_LIBDIR} "/home/misaki/MisakiCodes/Env/rk3566-sdk/qt-pkgconfig")
|
||||||
|
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${SYSROOT}")
|
||||||
|
set(ENV{PKG_CONFIG_PATH} "")
|
||||||
|
|
||||||
|
# === 线程 ===
|
||||||
|
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
```
|
||||||
|
|
||||||
|
你需要根据自己的实际情况进行调整。
|
||||||
|
|
||||||
|
之前的命令是配置CMake的,编译还需:
|
||||||
|
```shell
|
||||||
|
cmake --build . --target Framework -j$(nproc)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
预期的编译日志输出:
|
||||||
|
```shell
|
||||||
|
[ 7%] Building CXX object CMakeFiles/Framework.dir/src/CubismModelSettingJson.cpp.o
|
||||||
|
[ 7%] Building CXX object CMakeFiles/Framework.dir/src/CubismDefaultParameterId.cpp.o
|
||||||
|
[ 7%] Building CXX object CMakeFiles/Framework.dir/src/CubismCdiJson.cpp.o
|
||||||
|
[ 10%] Building CXX object CMakeFiles/Framework.dir/src/CubismFramework.cpp.o
|
||||||
|
[ 12%] Building CXX object CMakeFiles/Framework.dir/src/Effect/CubismEyeBlink.cpp.o
|
||||||
|
[ 15%] Building CXX object CMakeFiles/Framework.dir/src/Id/CubismId.cpp.o
|
||||||
|
[ 17%] Building CXX object CMakeFiles/Framework.dir/src/Effect/CubismPose.cpp.o
|
||||||
|
[ 20%] Building CXX object CMakeFiles/Framework.dir/src/Effect/CubismBreath.cpp.o
|
||||||
|
[ 22%] Building CXX object CMakeFiles/Framework.dir/src/Id/CubismIdManager.cpp.o
|
||||||
|
[ 25%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismMath.cpp.o
|
||||||
|
[ 27%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismMatrix44.cpp.o
|
||||||
|
[ 30%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismModelMatrix.cpp.o
|
||||||
|
[ 32%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismTargetPoint.cpp.o
|
||||||
|
[ 35%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismViewMatrix.cpp.o
|
||||||
|
[ 37%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismVector2.cpp.o
|
||||||
|
[ 40%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismMoc.cpp.o
|
||||||
|
[ 42%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismModel.cpp.o
|
||||||
|
[ 45%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismModelUserData.cpp.o
|
||||||
|
[ 47%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismModelUserDataJson.cpp.o
|
||||||
|
[ 50%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismUserModel.cpp.o
|
||||||
|
[ 52%] Building CXX object CMakeFiles/Framework.dir/src/Motion/ACubismMotion.cpp.o
|
||||||
|
[ 55%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismExpressionMotion.cpp.o
|
||||||
|
[ 57%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismExpressionMotionManager.cpp.o
|
||||||
|
[ 60%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotion.cpp.o
|
||||||
|
[ 62%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotionJson.cpp.o
|
||||||
|
[ 65%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotionManager.cpp.o
|
||||||
|
[ 67%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotionQueueEntry.cpp.o
|
||||||
|
[ 70%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotionQueueManager.cpp.o
|
||||||
|
[ 72%] Building CXX object CMakeFiles/Framework.dir/src/Physics/CubismPhysics.cpp.o
|
||||||
|
[ 75%] Building CXX object CMakeFiles/Framework.dir/src/Rendering/CubismRenderer.cpp.o
|
||||||
|
[ 77%] Building CXX object CMakeFiles/Framework.dir/src/Physics/CubismPhysicsJson.cpp.o
|
||||||
|
[ 80%] Building CXX object CMakeFiles/Framework.dir/src/Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.cpp.o
|
||||||
|
[ 82%] Building CXX object CMakeFiles/Framework.dir/src/Rendering/OpenGL/CubismShader_OpenGLES2.cpp.o
|
||||||
|
[ 85%] Building CXX object CMakeFiles/Framework.dir/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.cpp.o
|
||||||
|
[ 87%] Building CXX object CMakeFiles/Framework.dir/src/Type/csmRectF.cpp.o
|
||||||
|
[ 90%] Building CXX object CMakeFiles/Framework.dir/src/Type/csmString.cpp.o
|
||||||
|
[ 92%] Building CXX object CMakeFiles/Framework.dir/src/Utils/CubismDebug.cpp.o
|
||||||
|
[ 95%] Building CXX object CMakeFiles/Framework.dir/src/Utils/CubismJson.cpp.o
|
||||||
|
[ 97%] Building CXX object CMakeFiles/Framework.dir/src/Utils/CubismString.cpp.o
|
||||||
|
In file included from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/../CubismClippingManager.hpp:152,
|
||||||
|
from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.hpp:11,
|
||||||
|
from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.cpp:8:
|
||||||
|
/home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/../CubismClippingManager.tpp: In instantiation of ‘Live2D::Cubism::Framework::Rendering::CubismClippingManager<T_ClippingContext, T_OffscreenSurface>::~CubismClippingManager() [with T_ClippingContext = Live2D::Cubism::Framework::Rendering::CubismClippingContext_OpenGLES2; T_OffscreenSurface = Live2D::Cubism::Framework::Rendering::CubismOffscreenSurface_OpenGLES2]’:
|
||||||
|
/home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.hpp:61:7: required from here
|
||||||
|
/home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/../CubismClippingManager.tpp:66:33: warning: passing NULL to non-pointer argument 1 of ‘Live2D::Cubism::Framework::csmVector<T>::csmVector(Live2D::Cubism::Framework::csmInt32, Live2D::Cubism::Framework::csmBool) [with T = bool; Live2D::Cubism::Framework::csmInt32 = int; Live2D::Cubism::Framework::csmBool = bool]’ [-Wconversion-null]
|
||||||
|
66 | _clearedMaskBufferFlags = NULL;
|
||||||
|
| ^
|
||||||
|
In file included from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/../CubismRenderer.hpp:12,
|
||||||
|
from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.hpp:10:
|
||||||
|
/home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Type/csmVector.hpp:559:34: note: declared here
|
||||||
|
559 | csmVector<T>::csmVector(csmInt32 initialCapacity, csmBool zeroClear)
|
||||||
|
| ~~~~~~~~~^~~~~~~~~~~~~~~
|
||||||
|
[100%] Linking CXX static library libFramework.a
|
||||||
|
[100%] Built target Framework
|
||||||
|
```
|
||||||
Binary file not shown.
@@ -0,0 +1,195 @@
|
|||||||
|
## Framework模块说明
|
||||||
|
|
||||||
|
由于嵌入式Linux的硬件差异性导致的不同嵌入式板子的sysroot不同,导致不同的板子环境差异很大,
|
||||||
|
因此对于framework这个模块,需要自行根据自己板子的sysroot或者sdk进行交叉编译。
|
||||||
|
|
||||||
|
#### 如何交叉编译Framework模块
|
||||||
|
在本项目当中,有一个适用于rk3566的framework模块,
|
||||||
|
因为framework模块一般不会使用到一些特别的硬件或者是后端(音频后端之类的),
|
||||||
|
所以理论上其他rk3566的板子也可以使用我预编译的模块。
|
||||||
|
|
||||||
|
给出交叉编译步骤(以编译我的rk3566为例):
|
||||||
|
```shell
|
||||||
|
cmake -S ../Framework -B . \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=~/MisakiCodes/Env/rk3566-sdk/qt_toolchain.cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug \
|
||||||
|
-DFRAMEWORK_SOURCE=OpenGL \
|
||||||
|
-DRENDER_INCLUDE_PATH="${CMAKE_SOURCE_DIR}/Framework/src/Rendering/OpenGL" \
|
||||||
|
-DFRAMEWORK_DEFINITIOINS="CSM_TARGET_HARMONYOS_ES3"
|
||||||
|
```
|
||||||
|
|
||||||
|
预期的配置输出:
|
||||||
|
```shell
|
||||||
|
CMake Warning (dev) in CMakeLists.txt:
|
||||||
|
No project() command is present. The top-level CMakeLists.txt file must
|
||||||
|
contain a literal, direct call to the project() command. Add a line of
|
||||||
|
code such as
|
||||||
|
|
||||||
|
project(ProjectName)
|
||||||
|
|
||||||
|
near the top of the file, but after cmake_minimum_required().
|
||||||
|
|
||||||
|
CMake is pretending there is a "project(Project)" command on the first
|
||||||
|
line.
|
||||||
|
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||||
|
|
||||||
|
CMake Warning (dev) in CMakeLists.txt:
|
||||||
|
cmake_minimum_required() should be called prior to this top-level project()
|
||||||
|
call. Please see the cmake-commands(7) manual for usage documentation of
|
||||||
|
both commands.
|
||||||
|
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||||
|
|
||||||
|
-- The C compiler identification is GNU 12.3.0
|
||||||
|
-- The CXX compiler identification is GNU 12.3.0
|
||||||
|
-- Detecting C compiler ABI info
|
||||||
|
-- Detecting C compiler ABI info - done
|
||||||
|
-- Check for working C compiler: /home/misaki/MisakiCodes/Env/rk3566-sdk/toolchain/aarch64--glibc--stable-2023.08-1/bin/aarch64-linux-gcc - skipped
|
||||||
|
-- Detecting C compile features
|
||||||
|
-- Detecting C compile features - done
|
||||||
|
-- Detecting CXX compiler ABI info
|
||||||
|
-- Detecting CXX compiler ABI info - done
|
||||||
|
-- Check for working CXX compiler: /home/misaki/MisakiCodes/Env/rk3566-sdk/toolchain/aarch64--glibc--stable-2023.08-1/bin/aarch64-linux-g++ - skipped
|
||||||
|
-- Detecting CXX compile features
|
||||||
|
-- Detecting CXX compile features - done
|
||||||
|
-- Configuring done (0.5s)
|
||||||
|
-- Generating done (0.0s)
|
||||||
|
-- Build files have been written to: /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/build_framework
|
||||||
|
```
|
||||||
|
|
||||||
|
观察上述命令可知,首先你肯定需要准备Live2D的SDK,这可以在官网下载,不在此过多赘述。
|
||||||
|
|
||||||
|
接着在与Framework的同级目录下新建一个xxx_build目录,如果你不知道这是什么,那么最好借助一下AI来帮助你。
|
||||||
|
|
||||||
|
之后就是cd到build目录里面。
|
||||||
|
|
||||||
|
Framework模块承担了Live2D的很多功能,其中唯一一个平台有关的就是Render模块,
|
||||||
|
也就是渲染功能,不过Live2D的库的渲染部分写的比较好,统一使用了OpenGL ES,同时兼容主机平台和arm移动平台。
|
||||||
|
|
||||||
|
你需要准备一个编译工具链,也就toolchain.cmake脚本的内容,这个编译工具链描述了编译器信息,sysroot信息等等。
|
||||||
|
下面给出我自己的工具链作为参考。
|
||||||
|
```cmake
|
||||||
|
set(CMAKE_SYSTEM_NAME Linux)
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||||
|
|
||||||
|
set(TOOLCHAIN_ROOT /home/misaki/MisakiCodes/Env/rk3566-sdk/toolchain/aarch64--glibc--stable-2023.08-1)
|
||||||
|
set(CMAKE_C_COMPILER ${TOOLCHAIN_ROOT}/bin/aarch64-linux-gcc)
|
||||||
|
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_ROOT}/bin/aarch64-linux-g++)
|
||||||
|
set(CMAKE_AR ${TOOLCHAIN_ROOT}/bin/aarch64-linux-ar)
|
||||||
|
set(CMAKE_RANLIB ${TOOLCHAIN_ROOT}/bin/aarch64-linux-ranlib)
|
||||||
|
set(CMAKE_STRIP ${TOOLCHAIN_ROOT}/bin/aarch64-linux-strip)
|
||||||
|
|
||||||
|
set(SYSROOT /home/misaki/MisakiCodes/Env/rk3566-sdk/host/aarch64-buildroot-linux-gnu/sysroot)
|
||||||
|
set(VPET_SDK /home/misaki/MisakiCodes/Env/rk3566-sdk/vpet-deps)
|
||||||
|
set(QT_HOST_PATH /home/misaki/Qt/6.6.3/gcc_64)
|
||||||
|
|
||||||
|
set(CMAKE_FIND_ROOT_PATH ${SYSROOT} ${VPET_SDK})
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) # 不使用only,否则会导致CMake找不到其他库的包,例如Qt的,会直接导致FindPackage失效,只能找sysroot里面的包
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "-march=armv8.2-a -mtune=cortex-a55 -O2 -pipe --sysroot=${SYSROOT}")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++17")
|
||||||
|
|
||||||
|
# === 关键:强制链接 Mali 驱动和 EGL/GLES ===
|
||||||
|
set(MALI_LIBS "-lmali-hook -Wl,--whole-archive -lmali-hook-injector -Wl,--no-whole-archive -lmali -ldrm")
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS
|
||||||
|
"-Wl,-dynamic-linker=/lib/ld-linux-aarch64.so.1 \
|
||||||
|
-Wl,-rpath,/data/vpet/deps/lib:/usr/lib:/lib \
|
||||||
|
--sysroot=${SYSROOT} \
|
||||||
|
${MALI_LIBS}"
|
||||||
|
)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
|
||||||
|
# === 包含路径 ===
|
||||||
|
include_directories(
|
||||||
|
${VPET_SDK}/include
|
||||||
|
${VPET_SDK}/include/libdrm
|
||||||
|
${SYSROOT}/usr/include
|
||||||
|
)
|
||||||
|
|
||||||
|
# === 库路径 ===
|
||||||
|
link_directories(
|
||||||
|
${VPET_SDK}/lib
|
||||||
|
${SYSROOT}/usr/lib
|
||||||
|
${SYSROOT}/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
# === pkg-config ===
|
||||||
|
set(ENV{PKG_CONFIG} "/usr/bin/pkg-config")
|
||||||
|
set(ENV{PKG_CONFIG_LIBDIR} "/home/misaki/MisakiCodes/Env/rk3566-sdk/qt-pkgconfig")
|
||||||
|
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${SYSROOT}")
|
||||||
|
set(ENV{PKG_CONFIG_PATH} "")
|
||||||
|
|
||||||
|
# === 线程 ===
|
||||||
|
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
```
|
||||||
|
|
||||||
|
你需要根据自己的实际情况进行调整。
|
||||||
|
|
||||||
|
之前的命令是配置CMake的,编译还需:
|
||||||
|
```shell
|
||||||
|
cmake --build . --target Framework -j$(nproc)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
预期的编译日志输出:
|
||||||
|
```shell
|
||||||
|
[ 7%] Building CXX object CMakeFiles/Framework.dir/src/CubismModelSettingJson.cpp.o
|
||||||
|
[ 7%] Building CXX object CMakeFiles/Framework.dir/src/CubismDefaultParameterId.cpp.o
|
||||||
|
[ 7%] Building CXX object CMakeFiles/Framework.dir/src/CubismCdiJson.cpp.o
|
||||||
|
[ 10%] Building CXX object CMakeFiles/Framework.dir/src/CubismFramework.cpp.o
|
||||||
|
[ 12%] Building CXX object CMakeFiles/Framework.dir/src/Effect/CubismEyeBlink.cpp.o
|
||||||
|
[ 15%] Building CXX object CMakeFiles/Framework.dir/src/Id/CubismId.cpp.o
|
||||||
|
[ 17%] Building CXX object CMakeFiles/Framework.dir/src/Effect/CubismPose.cpp.o
|
||||||
|
[ 20%] Building CXX object CMakeFiles/Framework.dir/src/Effect/CubismBreath.cpp.o
|
||||||
|
[ 22%] Building CXX object CMakeFiles/Framework.dir/src/Id/CubismIdManager.cpp.o
|
||||||
|
[ 25%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismMath.cpp.o
|
||||||
|
[ 27%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismMatrix44.cpp.o
|
||||||
|
[ 30%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismModelMatrix.cpp.o
|
||||||
|
[ 32%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismTargetPoint.cpp.o
|
||||||
|
[ 35%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismViewMatrix.cpp.o
|
||||||
|
[ 37%] Building CXX object CMakeFiles/Framework.dir/src/Math/CubismVector2.cpp.o
|
||||||
|
[ 40%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismMoc.cpp.o
|
||||||
|
[ 42%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismModel.cpp.o
|
||||||
|
[ 45%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismModelUserData.cpp.o
|
||||||
|
[ 47%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismModelUserDataJson.cpp.o
|
||||||
|
[ 50%] Building CXX object CMakeFiles/Framework.dir/src/Model/CubismUserModel.cpp.o
|
||||||
|
[ 52%] Building CXX object CMakeFiles/Framework.dir/src/Motion/ACubismMotion.cpp.o
|
||||||
|
[ 55%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismExpressionMotion.cpp.o
|
||||||
|
[ 57%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismExpressionMotionManager.cpp.o
|
||||||
|
[ 60%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotion.cpp.o
|
||||||
|
[ 62%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotionJson.cpp.o
|
||||||
|
[ 65%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotionManager.cpp.o
|
||||||
|
[ 67%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotionQueueEntry.cpp.o
|
||||||
|
[ 70%] Building CXX object CMakeFiles/Framework.dir/src/Motion/CubismMotionQueueManager.cpp.o
|
||||||
|
[ 72%] Building CXX object CMakeFiles/Framework.dir/src/Physics/CubismPhysics.cpp.o
|
||||||
|
[ 75%] Building CXX object CMakeFiles/Framework.dir/src/Rendering/CubismRenderer.cpp.o
|
||||||
|
[ 77%] Building CXX object CMakeFiles/Framework.dir/src/Physics/CubismPhysicsJson.cpp.o
|
||||||
|
[ 80%] Building CXX object CMakeFiles/Framework.dir/src/Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.cpp.o
|
||||||
|
[ 82%] Building CXX object CMakeFiles/Framework.dir/src/Rendering/OpenGL/CubismShader_OpenGLES2.cpp.o
|
||||||
|
[ 85%] Building CXX object CMakeFiles/Framework.dir/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.cpp.o
|
||||||
|
[ 87%] Building CXX object CMakeFiles/Framework.dir/src/Type/csmRectF.cpp.o
|
||||||
|
[ 90%] Building CXX object CMakeFiles/Framework.dir/src/Type/csmString.cpp.o
|
||||||
|
[ 92%] Building CXX object CMakeFiles/Framework.dir/src/Utils/CubismDebug.cpp.o
|
||||||
|
[ 95%] Building CXX object CMakeFiles/Framework.dir/src/Utils/CubismJson.cpp.o
|
||||||
|
[ 97%] Building CXX object CMakeFiles/Framework.dir/src/Utils/CubismString.cpp.o
|
||||||
|
In file included from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/../CubismClippingManager.hpp:152,
|
||||||
|
from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.hpp:11,
|
||||||
|
from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.cpp:8:
|
||||||
|
/home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/../CubismClippingManager.tpp: In instantiation of ‘Live2D::Cubism::Framework::Rendering::CubismClippingManager<T_ClippingContext, T_OffscreenSurface>::~CubismClippingManager() [with T_ClippingContext = Live2D::Cubism::Framework::Rendering::CubismClippingContext_OpenGLES2; T_OffscreenSurface = Live2D::Cubism::Framework::Rendering::CubismOffscreenSurface_OpenGLES2]’:
|
||||||
|
/home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.hpp:61:7: required from here
|
||||||
|
/home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/../CubismClippingManager.tpp:66:33: warning: passing NULL to non-pointer argument 1 of ‘Live2D::Cubism::Framework::csmVector<T>::csmVector(Live2D::Cubism::Framework::csmInt32, Live2D::Cubism::Framework::csmBool) [with T = bool; Live2D::Cubism::Framework::csmInt32 = int; Live2D::Cubism::Framework::csmBool = bool]’ [-Wconversion-null]
|
||||||
|
66 | _clearedMaskBufferFlags = NULL;
|
||||||
|
| ^
|
||||||
|
In file included from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/../CubismRenderer.hpp:12,
|
||||||
|
from /home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Rendering/OpenGL/CubismRenderer_OpenGLES2.hpp:10:
|
||||||
|
/home/misaki/Downloads/CubismSdkForNative-5-r.4.1/Framework/src/Type/csmVector.hpp:559:34: note: declared here
|
||||||
|
559 | csmVector<T>::csmVector(csmInt32 initialCapacity, csmBool zeroClear)
|
||||||
|
| ~~~~~~~~~^~~~~~~~~~~~~~~
|
||||||
|
[100%] Linking CXX static library libFramework.a
|
||||||
|
[100%] Built target Framework
|
||||||
|
```
|
||||||
Binary file not shown.
+42
@@ -0,0 +1,42 @@
|
|||||||
|
# LAppLive2D — Live2D SDK 示例应用层,编译为静态库
|
||||||
|
# 依赖:Framework(libFramework.a) + Live2DCubismCore(libLive2DCubismCore.a)
|
||||||
|
# 无 Qt 依赖 — 完全解耦,仅依赖 OpenGL/GLES 头文件 + Cubism SDK
|
||||||
|
|
||||||
|
file(GLOB_RECURSE LAppLive2D_SOURCES
|
||||||
|
CONFIGURE_DEPENDS
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/Src/*.cpp"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/Inc/*.hpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(lapp_live2d STATIC ${LAppLive2D_SOURCES})
|
||||||
|
|
||||||
|
# =============================================
|
||||||
|
# 自身的公开头文件目录
|
||||||
|
# =============================================
|
||||||
|
target_include_directories(lapp_live2d
|
||||||
|
PUBLIC
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/Inc"
|
||||||
|
)
|
||||||
|
|
||||||
|
# =============================================
|
||||||
|
# Live2D SDK 头文件(Framework + Core + stb)
|
||||||
|
# 这些是 lapp_live2d 编译时必需的,通过 PUBLIC 发布给最终链接目标
|
||||||
|
# =============================================
|
||||||
|
target_include_directories(lapp_live2d
|
||||||
|
PUBLIC
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../Framework/src"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../Core/include"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../stb"
|
||||||
|
)
|
||||||
|
|
||||||
|
# =============================================
|
||||||
|
# 链接依赖 — 注意链接顺序!
|
||||||
|
# lapp_live2d → Framework → Live2DCubismCore
|
||||||
|
# Framework 内部使用了 Live2DCubismCore 的符号,所以 Core 必须在 Framework 之后
|
||||||
|
# lapp_live2d 无 Qt 依赖,开发者可自由选择 UI 后端(Qt/SDL/GLFW等)
|
||||||
|
# =============================================
|
||||||
|
target_link_libraries(lapp_live2d
|
||||||
|
PUBLIC
|
||||||
|
Framework # Live2D Framework 静态库(IMPORTED,由父CMakeLists定义)
|
||||||
|
Live2DCubismCore # Live2D Core 静态库(IMPORTED,由父CMakeLists定义)
|
||||||
|
)
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2026/6/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "IRenderContext.hpp"
|
||||||
|
#include "LAppOpenGL.hpp"
|
||||||
|
|
||||||
|
class GLRenderContext final : public IRenderContext {
|
||||||
|
public:
|
||||||
|
void Clear(float r, float g, float b, float a) override {
|
||||||
|
glClearColor(r, g, b, a);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearDepth(float depth) override {
|
||||||
|
LAPP_GL_CLEAR_DEPTH(depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetViewport(int x, int y, int w, int h) override {
|
||||||
|
glViewport(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t CreateShaderProgram() override {
|
||||||
|
return CompileShader();
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t GetShaderProgram() const override {
|
||||||
|
return _programId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeGLState() override {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint _programId = 0;
|
||||||
|
|
||||||
|
GLuint CompileShader() {
|
||||||
|
if (_programId) return _programId;
|
||||||
|
|
||||||
|
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES_3) || defined(EMBEDDED_LINUX)
|
||||||
|
const char* vertexShader =
|
||||||
|
"#version 100\n"
|
||||||
|
"attribute vec3 position;\n"
|
||||||
|
"attribute vec2 uv;\n"
|
||||||
|
"varying vec2 vuv;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" gl_Position = vec4(position, 1.0);\n"
|
||||||
|
" vuv = uv;\n"
|
||||||
|
"}\n";
|
||||||
|
const char* fragmentShader =
|
||||||
|
"#version 100\n"
|
||||||
|
"precision mediump float;\n"
|
||||||
|
"varying vec2 vuv;\n"
|
||||||
|
"uniform sampler2D texture;\n"
|
||||||
|
"uniform vec4 baseColor;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" gl_FragColor = texture2D(texture, vuv) * baseColor;\n"
|
||||||
|
"}\n";
|
||||||
|
#else
|
||||||
|
const char* vertexShader =
|
||||||
|
"#version 120\n"
|
||||||
|
"attribute vec3 position;\n"
|
||||||
|
"attribute vec2 uv;\n"
|
||||||
|
"varying vec2 vuv;\n"
|
||||||
|
"void main(void) {\n"
|
||||||
|
" gl_Position = vec4(position, 1.0);\n"
|
||||||
|
" vuv = uv;\n"
|
||||||
|
"}\n";
|
||||||
|
const char* fragmentShader =
|
||||||
|
"#version 120\n"
|
||||||
|
"varying vec2 vuv;\n"
|
||||||
|
"uniform sampler2D texture;\n"
|
||||||
|
"uniform vec4 baseColor;\n"
|
||||||
|
"void main(void) {\n"
|
||||||
|
" gl_FragColor = texture2D(texture, vuv) * baseColor;\n"
|
||||||
|
"}\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GLuint vertId = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(vertId, 1, &vertexShader, nullptr);
|
||||||
|
glCompileShader(vertId);
|
||||||
|
|
||||||
|
GLuint fragId = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(fragId, 1, &fragmentShader, nullptr);
|
||||||
|
glCompileShader(fragId);
|
||||||
|
|
||||||
|
_programId = glCreateProgram();
|
||||||
|
glAttachShader(_programId, vertId);
|
||||||
|
glAttachShader(_programId, fragId);
|
||||||
|
glLinkProgram(_programId);
|
||||||
|
glUseProgram(_programId);
|
||||||
|
|
||||||
|
glDeleteShader(vertId);
|
||||||
|
glDeleteShader(fragId);
|
||||||
|
return _programId;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2026/6/23.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class IRenderContext {
|
||||||
|
public:
|
||||||
|
virtual ~IRenderContext() = default;
|
||||||
|
|
||||||
|
virtual void Clear(float r, float g, float b, float a) = 0;
|
||||||
|
virtual void ClearDepth(float depth) = 0;
|
||||||
|
virtual void SetViewport(int x, int y, int w, int h) = 0;
|
||||||
|
virtual uintptr_t CreateShaderProgram() = 0;
|
||||||
|
virtual uintptr_t GetShaderProgram() const = 0;
|
||||||
|
virtual void InitializeGLState() = 0;
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2026/6/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class ISpriteRenderer {
|
||||||
|
public:
|
||||||
|
virtual ~ISpriteRenderer() = default;
|
||||||
|
|
||||||
|
virtual void SetColor(float r, float g, float b, float a) = 0;
|
||||||
|
virtual void SetWindowSize(int w, int h) = 0;
|
||||||
|
virtual void RenderImmidiate(uintptr_t textureId,
|
||||||
|
const float uvVertex[8]) const = 0;
|
||||||
|
virtual bool IsHit(float px, float py) const = 0;
|
||||||
|
virtual void ResetRect(float x, float y, float w, float h) = 0;
|
||||||
|
virtual uintptr_t GetTextureId() const = 0;
|
||||||
|
};
|
||||||
+50
-30
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include "LAppOpenGL.hpp"
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include "LAppAllocator.hpp"
|
#include "LAppAllocator.hpp"
|
||||||
#include "GLCore.h"
|
#include "IRenderContext.hpp"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
class LAppView;
|
class LAppView;
|
||||||
class LAppTextureManager;
|
class LAppTextureManager;
|
||||||
@@ -37,17 +37,29 @@ public:
|
|||||||
static void ReleaseInstance();
|
static void ReleaseInstance();
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
|
// resize 由应用层(GLCore::resizeGL)调用,通知LApp窗口尺寸变更
|
||||||
void resize(int width, int height);
|
void resize(int width, int height);
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
IRenderContext* GetRenderContext() const { return _renderContext; }
|
||||||
|
void SetRenderContext(IRenderContext* ctx) { _renderContext = ctx; }
|
||||||
|
|
||||||
|
// 窗口大小变更回调 解耦 AppContext/GLCore 依赖
|
||||||
|
// 当模型加载后需要调整窗口大小时,LAppLive2DManager 通过此回调通知应用层
|
||||||
|
using WindowResizeFunc = std::function<void(int width, int height)>;
|
||||||
|
void SetWindowResizeCallback(WindowResizeFunc cb) { _onResizeWindow = std::move(cb); }
|
||||||
|
void NotifyWindowResize(int width, int height) { if (_onResizeWindow) _onResizeWindow(width, height); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief APPに必要なものを初期化する。
|
* @brief APPに必要なものを初期化する。
|
||||||
|
* @param windowWidth 窗口宽度(像素)
|
||||||
|
* @param windowHeight 窗口高度(像素)
|
||||||
*/
|
*/
|
||||||
//bool Initialize();
|
// bool Initialize(GLCore* window); // 原
|
||||||
bool Initialize(GLCore* window);
|
// bool Initialize(QWidget* window); // 中间解耦版本
|
||||||
|
bool Initialize(int windowWidth, int windowHeight); // 完全解耦Qt,仅传入尺寸
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 解放する。
|
* @brief 解放する。
|
||||||
@@ -67,7 +79,8 @@ public:
|
|||||||
* @param[in] action 実行結果
|
* @param[in] action 実行結果
|
||||||
* @param[in] modify
|
* @param[in] modify
|
||||||
*/
|
*/
|
||||||
void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify);
|
// void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify);
|
||||||
|
void OnMouseCallBack(int button, int action, int modify);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief OpenGL用 glfwSetCursorPosCallback用関数。
|
* @brief OpenGL用 glfwSetCursorPosCallback用関数。
|
||||||
@@ -76,7 +89,8 @@ public:
|
|||||||
* @param[in] x x座標
|
* @param[in] x x座標
|
||||||
* @param[in] y x座標
|
* @param[in] y x座標
|
||||||
*/
|
*/
|
||||||
void OnMouseCallBack(GLFWwindow* window, double x, double y);
|
// void OnMouseCallBack(GLFWwindow* window, double x, double y);
|
||||||
|
void OnMouseCallBack(double x, double y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief シェーダーを登録する。
|
* @brief シェーダーを登録する。
|
||||||
@@ -84,9 +98,12 @@ public:
|
|||||||
GLuint CreateShader();
|
GLuint CreateShader();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Window情報を取得する。
|
* @brief Window尺寸を取得する。
|
||||||
*/
|
*/
|
||||||
GLCore* GetWindow() { return _window; } // Misaki 修改
|
// GLCore* GetWindow() { return _window; } // 原
|
||||||
|
// QWidget* GetWindow() { return _window; } // 中间版本
|
||||||
|
int GetWindowWidth() const { return _windowWidth; } // 完全解耦Qt
|
||||||
|
int GetWindowHeight() const { return _windowHeight; } // 完全解耦Qt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief View情報を取得する。
|
* @brief View情報を取得する。
|
||||||
@@ -126,10 +143,13 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool CheckShader(GLuint shaderId);
|
bool CheckShader(GLuint shaderId);
|
||||||
|
|
||||||
|
IRenderContext* _renderContext = nullptr;
|
||||||
|
WindowResizeFunc _onResizeWindow; ///< 窗口大小回调
|
||||||
LAppAllocator _cubismAllocator; ///< Cubism SDK Allocator
|
LAppAllocator _cubismAllocator; ///< Cubism SDK Allocator
|
||||||
Csm::CubismFramework::Option _cubismOption; ///< Cubism SDK Option
|
Csm::CubismFramework::Option _cubismOption; ///< Cubism SDK Option
|
||||||
//GLFWwindow* _window; ///< OpenGL ウィンドウ
|
//GLFWwindow* _window; ///< OpenGL ウィンドウ
|
||||||
GLCore* _window; ///< Misaki 修改
|
// GLCore* _window; ///< Misaki 修改
|
||||||
|
// QWidget* _window; ///< 使用QWidget基类,解耦GLCore
|
||||||
LAppView* _view; ///< View情報
|
LAppView* _view; ///< View情報
|
||||||
bool _captured; ///< クリックしているか
|
bool _captured; ///< クリックしているか
|
||||||
float _mouseX; ///< マウスX座標
|
float _mouseX; ///< マウスX座標
|
||||||
@@ -141,23 +161,23 @@ private:
|
|||||||
int _windowHeight; ///< Initialize関数で設定したウィンドウ高さ
|
int _windowHeight; ///< Initialize関数で設定したウィンドウ高さ
|
||||||
};
|
};
|
||||||
|
|
||||||
class EventHandler
|
// class EventHandler
|
||||||
{
|
// {
|
||||||
public:
|
// public:
|
||||||
/**
|
// /**
|
||||||
* @brief glfwSetMouseButtonCallback用コールバック関数。
|
// * @brief glfwSetMouseButtonCallback用コールバック関数。
|
||||||
*/
|
// */
|
||||||
static void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
|
// static void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
|
||||||
{
|
// {
|
||||||
LAppDelegate::GetInstance()->OnMouseCallBack(window, button, action, modify);
|
// LAppDelegate::GetInstance()->OnMouseCallBack(window, button, action, modify);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* @brief glfwSetCursorPosCallback用コールバック関数。
|
// * @brief glfwSetCursorPosCallback用コールバック関数。
|
||||||
*/
|
// */
|
||||||
static void OnMouseCallBack(GLFWwindow* window, double x, double y)
|
// static void OnMouseCallBack(GLFWwindow* window, double x, double y)
|
||||||
{
|
// {
|
||||||
LAppDelegate::GetInstance()->OnMouseCallBack(window, x, y);
|
// LAppDelegate::GetInstance()->OnMouseCallBack(window, x, y);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
};
|
// };
|
||||||
|
|||||||
+3
-1
@@ -17,6 +17,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "LAppOpenGL.hpp"
|
||||||
/**
|
/**
|
||||||
* @brief ユーザーが実際に使用するモデルの実装クラス<br>
|
* @brief ユーザーが実際に使用するモデルの実装クラス<br>
|
||||||
* モデル生成、機能コンポーネント生成、更新処理とレンダリングの呼び出しを行う。
|
* モデル生成、機能コンポーネント生成、更新処理とレンダリングの呼び出しを行う。
|
||||||
@@ -286,5 +287,6 @@ private:
|
|||||||
Live2D::Cubism::Framework::csmFloat32 alpha = 0.8f; // 滤波系数,范围在0到1之间,值越小,平滑效果越强
|
Live2D::Cubism::Framework::csmFloat32 alpha = 0.8f; // 滤波系数,范围在0到1之间,值越小,平滑效果越强
|
||||||
Live2D::Cubism::Framework::csmFloat32 filteredValue = 0.0f; // 滤波后的值
|
Live2D::Cubism::Framework::csmFloat32 filteredValue = 0.0f; // 滤波后的值
|
||||||
|
|
||||||
Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
|
// Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
|
||||||
|
CUBISM_OFFSCREEN_TYPE _renderBuffer;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2026/5/13.
|
||||||
|
//
|
||||||
|
|
||||||
|
// LAppOpenGL.hpp
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// 根据是否嵌入式选择 OpenGL 头
|
||||||
|
#if !defined(EMBEDDED_LINUX)
|
||||||
|
// 桌面 OpenGL
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#else
|
||||||
|
// 嵌入式 OpenGL ES
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
#include <GLES2/gl2ext.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 统一深度清除函数
|
||||||
|
#if defined(EMBEDDED_LINUX)
|
||||||
|
#define LAPP_GL_CLEAR_DEPTH(d) glClearDepthf(d)
|
||||||
|
#else
|
||||||
|
#define LAPP_GL_CLEAR_DEPTH(d) glClearDepth(d)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONCAT_IMPL(a, b) a##b
|
||||||
|
|
||||||
|
#define CONCAT(a, b) CONCAT_IMPL(a, b)
|
||||||
|
|
||||||
|
// 渲染后端编译期类型选择 与 Cubism SDK 的 CubismRenderer::Create() 条件编译对齐
|
||||||
|
#if defined(RENDER_BACKEND_VULKAN)
|
||||||
|
#define RENDERER_BACKEND_TAG Vulkan
|
||||||
|
#elif defined(RENDER_BACKEND_D3D11)
|
||||||
|
#define RENDERER_BACKEND_TAG D3D11
|
||||||
|
#elif defined(RENDER_BACKEND_D3D9)
|
||||||
|
#define RENDERER_BACKEND_TAG D3D9
|
||||||
|
#elif defined(RENDER_BACKEND_METAL)
|
||||||
|
#define RENDERER_BACKEND_TAG Metal
|
||||||
|
#else
|
||||||
|
#define RENDERER_BACKEND_TAG OpenGLES2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 类型别名宏,用于 Csm 命名空间下的后端特定类型
|
||||||
|
#define CUBISM_RENDERER_TYPE CONCAT(Csm::Rendering::CubismRenderer_, RENDERER_BACKEND_TAG)
|
||||||
|
#define CUBISM_OFFSCREEN_TYPE CONCAT(Csm::Rendering::CubismOffscreenSurface_, RENDERER_BACKEND_TAG)
|
||||||
+20
-11
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include "LAppOpenGL.hpp"
|
||||||
#include <GLFW/glfw3.h>
|
#include "ISpriteRenderer.hpp" // 渲染后端抽象
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief スプライトを実装するクラス。
|
* @brief スプライトを実装するクラス。
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
* テクスチャID、Rectの管理。
|
* テクスチャID、Rectの管理。
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class LAppSprite
|
// class LAppSprite // 原
|
||||||
|
class LAppSprite : public ISpriteRenderer // 继承渲染抽象接口
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +42,8 @@ public:
|
|||||||
* @param[in] textureId テクスチャID
|
* @param[in] textureId テクスチャID
|
||||||
* @param[in] programId シェーダID
|
* @param[in] programId シェーダID
|
||||||
*/
|
*/
|
||||||
LAppSprite(float x, float y, float width, float height, GLuint textureId, GLuint programId);
|
// LAppSprite(float x, float y, float width, float height, GLuint textureId, GLuint programId); // 原
|
||||||
|
LAppSprite(float x, float y, float width, float height, uintptr_t textureId, uintptr_t programId); // 抽象类型
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief デストラクタ
|
* @brief デストラクタ
|
||||||
@@ -52,7 +54,8 @@ public:
|
|||||||
* @brief Getter テクスチャID
|
* @brief Getter テクスチャID
|
||||||
* @return テクスチャIDを返す
|
* @return テクスチャIDを返す
|
||||||
*/
|
*/
|
||||||
GLuint GetTextureId() { return _textureId; }
|
// GLuint GetTextureId() { return _textureId; } // 原
|
||||||
|
uintptr_t GetTextureId() const override { return _textureId; } // 抽象类型
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 描画する
|
* @brief 描画する
|
||||||
@@ -64,7 +67,8 @@ public:
|
|||||||
* @brief テクスチャIDを指定して描画する
|
* @brief テクスチャIDを指定して描画する
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void RenderImmidiate(GLuint textureId, const GLfloat uvVertex[8]) const;
|
// void RenderImmidiate(GLuint textureId, const GLfloat uvVertex[8]) const; // 原
|
||||||
|
void RenderImmidiate(uintptr_t textureId, const float uvVertex[8]) const override; // 抽象类型
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief コンストラクタ
|
* @brief コンストラクタ
|
||||||
@@ -72,7 +76,8 @@ public:
|
|||||||
* @param[in] pointX x座標
|
* @param[in] pointX x座標
|
||||||
* @param[in] pointY y座標
|
* @param[in] pointY y座標
|
||||||
*/
|
*/
|
||||||
bool IsHit(float pointX, float pointY) const;
|
// bool IsHit(float pointX, float pointY) const; // 原
|
||||||
|
bool IsHit(float pointX, float pointY) const override; // 接口实现
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 色設定
|
* @brief 色設定
|
||||||
@@ -82,7 +87,8 @@ public:
|
|||||||
* @param[in] b (0.0~1.0)
|
* @param[in] b (0.0~1.0)
|
||||||
* @param[in] a (0.0~1.0)
|
* @param[in] a (0.0~1.0)
|
||||||
*/
|
*/
|
||||||
void SetColor(float r, float g, float b, float a);
|
// void SetColor(float r, float g, float b, float a); // 原
|
||||||
|
void SetColor(float r, float g, float b, float a) override; // 接口实现
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief サイズ再設定
|
* @brief サイズ再設定
|
||||||
@@ -92,7 +98,8 @@ public:
|
|||||||
* @param[in] width 横幅
|
* @param[in] width 横幅
|
||||||
* @param[in] height 高さ
|
* @param[in] height 高さ
|
||||||
*/
|
*/
|
||||||
void ResetRect(float x, float y, float width, float height);
|
// void ResetRect(float x, float y, float width, float height); // 原
|
||||||
|
void ResetRect(float x, float y, float width, float height) override; // 接口实现
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ウインドウサイズ設定
|
* @brief ウインドウサイズ設定
|
||||||
@@ -100,10 +107,12 @@ public:
|
|||||||
* @param[in] width 横幅
|
* @param[in] width 横幅
|
||||||
* @param[in] height 高さ
|
* @param[in] height 高さ
|
||||||
*/
|
*/
|
||||||
void SetWindowSize(int width, int height);
|
// void SetWindowSize(int width, int height); // 原
|
||||||
|
void SetWindowSize(int width, int height) override; // 接口实现
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint _textureId; ///< テクスチャID
|
// GLuint _textureId; ///< テクスチャID 原
|
||||||
|
uintptr_t _textureId; ///< テクスチャID 抽象类型
|
||||||
Rect _rect; ///< 矩形
|
Rect _rect; ///< 矩形
|
||||||
int _positionLocation; ///< 位置アトリビュート
|
int _positionLocation; ///< 位置アトリビュート
|
||||||
int _uvLocation; ///< UVアトリビュート
|
int _uvLocation; ///< UVアトリビュート
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <GL/glew.h>
|
#include "LAppOpenGL.hpp"
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <Type/csmVector.hpp>
|
#include <Type/csmVector.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +25,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
struct TextureInfo
|
struct TextureInfo
|
||||||
{
|
{
|
||||||
GLuint id; ///< テクスチャID
|
// GLuint id; ///< テクスチャID
|
||||||
|
uintptr_t id;
|
||||||
int width; ///< 横幅
|
int width; ///< 横幅
|
||||||
int height; ///< 高さ
|
int height; ///< 高さ
|
||||||
std::string fileName; ///< ファイル名
|
std::string fileName; ///< ファイル名
|
||||||
|
|||||||
+8
-5
@@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include "LAppOpenGL.hpp"
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <Math/CubismMatrix44.hpp>
|
#include <Math/CubismMatrix44.hpp>
|
||||||
#include <Math/CubismViewMatrix.hpp>
|
#include <Math/CubismViewMatrix.hpp>
|
||||||
#include "CubismFramework.hpp"
|
#include "CubismFramework.hpp"
|
||||||
#include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
|
#include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
|
||||||
|
#include "ISpriteRenderer.hpp" // 绘制接口抽象
|
||||||
|
|
||||||
class TouchManager;
|
class TouchManager;
|
||||||
class LAppSprite;
|
class LAppSprite;
|
||||||
@@ -158,14 +158,17 @@ private:
|
|||||||
TouchManager* _touchManager; ///< タッチマネージャー
|
TouchManager* _touchManager; ///< タッチマネージャー
|
||||||
Csm::CubismMatrix44* _deviceToScreen; ///< デバイスからスクリーンへの行列
|
Csm::CubismMatrix44* _deviceToScreen; ///< デバイスからスクリーンへの行列
|
||||||
Csm::CubismViewMatrix* _viewMatrix; ///< viewMatrix
|
Csm::CubismViewMatrix* _viewMatrix; ///< viewMatrix
|
||||||
GLuint _programId; ///< シェーダID
|
// GLuint _programId; ///< シェーダID
|
||||||
|
uintptr_t _programId; ///< 顶点着色器ID
|
||||||
//LAppSprite* _back; ///< 背景画像
|
//LAppSprite* _back; ///< 背景画像
|
||||||
//LAppSprite* _gear; ///< ギア画像
|
//LAppSprite* _gear; ///< ギア画像
|
||||||
//LAppSprite* _power; ///< 電源画像
|
//LAppSprite* _power; ///< 電源画像
|
||||||
|
|
||||||
// レンダリング先を別ターゲットにする方式の場合に使用
|
// レンダリング先を別ターゲットにする方式の場合に使用
|
||||||
LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
|
// LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
|
||||||
Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< モードによってはCubismモデル結果をこっちにレンダリング
|
ISpriteRenderer* _renderSprite; ///< 绘制接口抽象
|
||||||
|
// Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< モードによってはCubismモデル結果をこっちにレンダリング
|
||||||
|
CUBISM_OFFSCREEN_TYPE _renderBuffer;
|
||||||
SelectTarget _renderTarget; ///< レンダリング先の選択肢
|
SelectTarget _renderTarget; ///< レンダリング先の選択肢
|
||||||
float _clearColor[4]; ///< レンダリングターゲットのクリアカラー
|
float _clearColor[4]; ///< レンダリングターゲットのクリアカラー
|
||||||
};
|
};
|
||||||
|
|||||||
+283
@@ -0,0 +1,283 @@
|
|||||||
|
# LAppLive2D — 独立 Live2D 渲染库
|
||||||
|
本文档是将相关代码投喂给AI所生成的,已经过人工审阅,未发现错误。
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
`lapp_live2d` 是对 [Live2D Cubism SDK for Native](https://www.live2d.com/download/cubism-sdk/) 的封装层。
|
||||||
|
它将原 SDK 示例代码中的 OpenGL 硬编码抽离为抽象接口,使库本身**不依赖任何窗口框架**(Qt / SDL / GLFW / 自研引擎均可接入)。
|
||||||
|
|
||||||
|
**核心设计原则**:
|
||||||
|
- 零 Qt / GLFW / SDL 依赖 — 仅依赖 C++ 标准库 + OpenGL 头文件 + Cubism SDK
|
||||||
|
- 渲染后端通过 `IRenderContext` / `ISpriteRenderer` 抽象接口注入
|
||||||
|
- 窗口尺寸变更通过 `std::function` 回调通知,不持有窗口指针
|
||||||
|
- 开发者可自由选择窗口框架,编写自己的 `GLCore`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 依赖
|
||||||
|
|
||||||
|
| 依赖 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| **Live2D Cubism Framework** | `libFramework.a`(静态库,Live2D 官方) |
|
||||||
|
| **Live2D Cubism Core** | `libLive2DCubismCore.a`(静态库,Live2D 官方) |
|
||||||
|
| **OpenGL / OpenGL ES 头文件** | 桌面: `GLEW` + `GLFW`头文件;嵌入式: `EGL` + `GLES2` |
|
||||||
|
| **C++ 标准库** | `std::function`, `cstdint` 等 |
|
||||||
|
|
||||||
|
不依赖任何 Qt / SDL / GLFW 链接库。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌───────────────────────────────────────────────────────────┐
|
||||||
|
│ LAppDelegate (单例,应用入口) │
|
||||||
|
│ Initialize(w, h) — 仅需传入窗口尺寸 │
|
||||||
|
│ resize(w, h) — 窗口变更通知 │
|
||||||
|
│ update() — 每帧渲染 │
|
||||||
|
│ SetRenderContext() — 注入渲染后端 │
|
||||||
|
│ SetWindowResizeCallback() — 窗口尺寸变更回调 │
|
||||||
|
│ NotifyWindowResize() — LApp内部通知应用层调整窗口 │
|
||||||
|
│ GetWindowWidth/Height() — 获取当前存储的窗口尺寸 │
|
||||||
|
└──────────────┬────────────────┬────────────────────────────┘
|
||||||
|
│ 持有 │ 持有
|
||||||
|
┌──────────▼──────┐ ┌─────▼──────────────────────────┐
|
||||||
|
│ LAppView │ │ LAppLive2DManager │
|
||||||
|
│ 渲染管理 │ │ 模型生命周期(加载/切换/更新) │
|
||||||
|
│ - 触摸事件 │ │ - OnTap / OnDrag │
|
||||||
|
│ - 坐标变换 │ │ - ModelSizeChange → 回调通知 │
|
||||||
|
│ - Sprite绘制 │ │ │
|
||||||
|
└────────┬─────────┘ └─────┬──────────────────────────┘
|
||||||
|
│ │ 管理
|
||||||
|
┌────────▼───────────────────▼──────┐
|
||||||
|
│ LAppModel : CubismUserModel │
|
||||||
|
│ 单个Live2D模型实例 │
|
||||||
|
│ - 加载(.moc3 / .model3.json) │
|
||||||
|
│ - 动画、物理、口型同步 │
|
||||||
|
│ - 命中检测 (HitTest) │
|
||||||
|
│ - 渲染 (Draw → CubismRenderer) │
|
||||||
|
└───────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 抽象接口
|
||||||
|
|
||||||
|
```
|
||||||
|
IRenderContext ISpriteRenderer
|
||||||
|
│ │
|
||||||
|
├─ Clear(r,g,b,a) ├─ SetColor(r,g,b,a)
|
||||||
|
├─ ClearDepth(d) ├─ SetWindowSize(w,h)
|
||||||
|
├─ SetViewport(x,y,w,h) ├─ RenderImmidiate(texId, uv)
|
||||||
|
├─ CreateShaderProgram() ├─ IsHit(px, py)
|
||||||
|
├─ GetShaderProgram() ├─ ResetRect(x,y,w,h)
|
||||||
|
├─ InitializeGLState() └─ GetTextureId()
|
||||||
|
│
|
||||||
|
└── GLRenderContext (OpenGL实现)
|
||||||
|
- CompileShader() 内部编译 GLSL
|
||||||
|
- Clear → glClear / glClearColor
|
||||||
|
- SetViewport → glViewport
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 接入方式(CMake)
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
# 1. 在父 CMakeLists.txt 中配置 Framework 和 Core(IMPORTED)
|
||||||
|
add_library(Framework STATIC IMPORTED GLOBAL)
|
||||||
|
set_target_properties(Framework PROPERTIES IMPORTED_LOCATION "/path/to/libFramework.a")
|
||||||
|
|
||||||
|
add_library(Live2DCubismCore STATIC IMPORTED GLOBAL)
|
||||||
|
set_target_properties(Live2DCubismCore PROPERTIES IMPORTED_LOCATION "/path/to/libLive2DCubismCore.a")
|
||||||
|
|
||||||
|
# 2. 导入 LAppLive2D 子项目
|
||||||
|
add_subdirectory(3rdparty/Live2D/Src/LAppLive2D)
|
||||||
|
|
||||||
|
# 3. 链接到你的可执行目标
|
||||||
|
target_link_libraries(your_app PRIVATE lapp_live2d)
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意**:LAppLive2D 内部引用 `<GL/glew.h>`(桌面)或 `<GLES2/gl2.h>`(嵌入式),需确保对应的头文件路径可用。参见父项目的 `CMakeLists.txt` 中如何为 `lapp_live2d` 补充平台 GL 头文件路径。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 编写自定义窗口(以 Qt 为例)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <QOpenGLWidget>
|
||||||
|
#include "LAppDelegate.hpp"
|
||||||
|
#include "GLRenderContext.hpp"
|
||||||
|
|
||||||
|
class MyGLCore final : public QOpenGLWidget
|
||||||
|
{
|
||||||
|
void initializeGL() override
|
||||||
|
{
|
||||||
|
// 1. 注入 IRenderContext(OpenGL 实现)
|
||||||
|
LAppDelegate::GetInstance()->SetRenderContext(new GLRenderContext());
|
||||||
|
|
||||||
|
// 2. 注册窗口大小变更回调(模型加载时 LApp 通知你调整窗口)
|
||||||
|
LAppDelegate::GetInstance()->SetWindowResizeCallback([this](int w, int h) {
|
||||||
|
setFixedSize(w, h);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. 初始化 LApp(传入当前窗口尺寸)
|
||||||
|
LAppDelegate::GetInstance()->Initialize(width(), height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void resizeGL(int w, int h) override
|
||||||
|
{
|
||||||
|
LAppDelegate::GetInstance()->resize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void paintGL() override
|
||||||
|
{
|
||||||
|
LAppDelegate::GetInstance()->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mousePressEvent(QMouseEvent *ev) override {
|
||||||
|
LAppDelegate::GetInstance()->GetView()->OnTouchesBegan(ev->position().x(), ev->position().y());
|
||||||
|
}
|
||||||
|
void mouseMoveEvent(QMouseEvent *ev) override {
|
||||||
|
LAppDelegate::GetInstance()->GetView()->OnTouchesMoved(ev->position().x(), ev->position().y());
|
||||||
|
}
|
||||||
|
void mouseReleaseEvent(QMouseEvent *ev) override {
|
||||||
|
LAppDelegate::GetInstance()->GetView()->OnTouchesEnded(ev->position().x(), ev->position().y());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 切换渲染后端
|
||||||
|
|
||||||
|
### 当前支持
|
||||||
|
|
||||||
|
| 后端 | 宏定义 | 说明 |
|
||||||
|
|------|--------|------|
|
||||||
|
| OpenGL ES2 | `RENDER_BACKEND_GLES2` | 嵌入式(RK3566 等) |
|
||||||
|
| OpenGL | `RENDER_BACKEND_OPENGL` | 桌面 Windows / Linux |
|
||||||
|
|
||||||
|
### 添加新后端
|
||||||
|
|
||||||
|
**第 1 步** — 在 `LAppOpenGL.hpp` 的宏分支中加一条:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#elif defined(RENDER_BACKEND_VULKAN)
|
||||||
|
#define RENDERER_BACKEND_TAG Vulkan
|
||||||
|
```
|
||||||
|
|
||||||
|
**第 2 步** — 实现 `VulkanRenderContext`(继承 `IRenderContext`),并在其中实现 `Clear` / `SetViewport` / `CreateShaderProgram` 等方法。
|
||||||
|
|
||||||
|
**第 3 步** — CMake 中 `add_definitions(-DRENDER_BACKEND_VULKAN)`。
|
||||||
|
|
||||||
|
**第 4 步** — 在你的窗口 `initializeGL()` 等价函数中创建 `VulkanRenderContext` 注入即可。
|
||||||
|
|
||||||
|
切换后端时 `LAppModel` 和 `LAppView` 中的 `CUBISM_RENDERER_TYPE` / `CUBISM_OFFSCREEN_TYPE` 宏会自动跟随编译宏切换对应的 Cubism SDK 后端类型。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API 参考
|
||||||
|
|
||||||
|
### LAppDelegate(单例)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// 初始化(必须在 OpenGL 上下文就绪后调用)
|
||||||
|
bool Initialize(int windowWidth, int windowHeight);
|
||||||
|
|
||||||
|
// 每帧调用
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// 窗口尺寸变更
|
||||||
|
void resize(int width, int height);
|
||||||
|
|
||||||
|
// 注入渲染后端
|
||||||
|
void SetRenderContext(IRenderContext* ctx);
|
||||||
|
IRenderContext* GetRenderContext() const;
|
||||||
|
|
||||||
|
// 窗口尺寸回调(模型加载时LApp通知应用层调整窗口)
|
||||||
|
using WindowResizeFunc = std::function<void(int width, int height)>;
|
||||||
|
void SetWindowResizeCallback(WindowResizeFunc cb);
|
||||||
|
|
||||||
|
// 获取当前存储的窗口尺寸
|
||||||
|
int GetWindowWidth() const;
|
||||||
|
int GetWindowHeight() const;
|
||||||
|
|
||||||
|
// 获取 View / TextureManager
|
||||||
|
LAppView* GetView();
|
||||||
|
LAppTextureManager* GetTextureManager();
|
||||||
|
```
|
||||||
|
|
||||||
|
### IRenderContext
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class IRenderContext {
|
||||||
|
public:
|
||||||
|
virtual ~IRenderContext() = default;
|
||||||
|
virtual void Clear(float r, float g, float b, float a) = 0;
|
||||||
|
virtual void ClearDepth(float depth) = 0;
|
||||||
|
virtual void SetViewport(int x, int y, int w, int h) = 0;
|
||||||
|
virtual uintptr_t CreateShaderProgram() = 0;
|
||||||
|
virtual uintptr_t GetShaderProgram() const = 0;
|
||||||
|
virtual void InitializeGLState() = 0;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### ISpriteRenderer
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class ISpriteRenderer {
|
||||||
|
public:
|
||||||
|
virtual ~ISpriteRenderer() = default;
|
||||||
|
virtual void SetColor(float r, float g, float b, float a) = 0;
|
||||||
|
virtual void SetWindowSize(int w, int h) = 0;
|
||||||
|
virtual void RenderImmidiate(uintptr_t textureId, const float uvVertex[8]) const = 0;
|
||||||
|
virtual bool IsHit(float px, float py) const = 0;
|
||||||
|
virtual void ResetRect(float x, float y, float w, float h) = 0;
|
||||||
|
virtual uintptr_t GetTextureId() const = 0;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 触摸事件映射
|
||||||
|
|
||||||
|
LApp 不依赖任何窗口事件系统,触摸由应用层主动调用:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// 对应 QMouseEvent / SDL_MouseButtonEvent / GLFW 回调
|
||||||
|
LAppDelegate::GetInstance()->GetView()->OnTouchesBegan(x, y); // 按下
|
||||||
|
LAppDelegate::GetInstance()->GetView()->OnTouchesMoved(x, y); // 移动
|
||||||
|
LAppDelegate::GetInstance()->GetView()->OnTouchesEnded(x, y); // 释放
|
||||||
|
|
||||||
|
// 坐标需为窗口内像素坐标,原点在左上角
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
LAppLive2D/
|
||||||
|
├── Inc/
|
||||||
|
│ ├── LAppDelegate.hpp ← 应用入口(单例)
|
||||||
|
│ ├── LAppView.hpp ← 渲染视图管理
|
||||||
|
│ ├── LAppModel.hpp ← 模型实例
|
||||||
|
│ ├── LAppSprite.hpp ← Sprite 绘制(继承 ISpriteRenderer)
|
||||||
|
│ ├── LAppLive2DManager.hpp ← 模型集管理
|
||||||
|
│ ├── LAppTextureManager.hpp ← 纹理管理
|
||||||
|
│ ├── LAppPal.hpp ← 平台抽象(文件IO、时间)
|
||||||
|
│ ├── LAppAllocator.hpp ← 内存分配器
|
||||||
|
│ ├── LAppDefine.hpp ← 配置常量
|
||||||
|
│ ├── LAppWavFileHandler.hpp ← WAV文件解析
|
||||||
|
│ ├── TouchManager.hpp ← 触摸状态管理
|
||||||
|
│ ├── LAppOpenGL.hpp ← OpenGL 头文件 + 后端宏
|
||||||
|
│ │
|
||||||
|
│ ├── IRenderContext.hpp ← 渲染上下文抽象接口 ★
|
||||||
|
│ ├── ISpriteRenderer.hpp ← Sprite渲染抽象接口 ★
|
||||||
|
│ └── GLRenderContext.hpp ← OpenGL IRenderContext 实现 ★
|
||||||
|
│
|
||||||
|
├── Src/
|
||||||
|
│ ├── *.cpp ← 各模块实现
|
||||||
|
│ └── ...
|
||||||
|
│
|
||||||
|
├── CMakeLists.txt ← 子项目构建脚本
|
||||||
|
└── README.md ← 本文件
|
||||||
|
```
|
||||||
+244
-161
@@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include "LAppDelegate.hpp"
|
#include "LAppDelegate.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <GL/glew.h>
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include "LAppView.hpp"
|
#include "LAppView.hpp"
|
||||||
#include "LAppPal.hpp"
|
#include "LAppPal.hpp"
|
||||||
#include "LAppDefine.hpp"
|
#include "LAppDefine.hpp"
|
||||||
@@ -43,77 +41,100 @@ void LAppDelegate::ReleaseInstance()
|
|||||||
s_instance = NULL;
|
s_instance = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LAppDelegate::Initialize(GLCore* window)
|
// bool LAppDelegate::Initialize(GLCore* window)
|
||||||
|
// {
|
||||||
|
// if (DebugLogEnable)
|
||||||
|
// {
|
||||||
|
// LAppPal::PrintLogLn("START");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // GLFWの初期化
|
||||||
|
// if (glfwInit() == GL_FALSE)
|
||||||
|
// {
|
||||||
|
// if (DebugLogEnable)
|
||||||
|
// {
|
||||||
|
// LAppPal::PrintLogLn("Can't initilize GLFW");
|
||||||
|
// }
|
||||||
|
// return GL_FALSE;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Windowの生成_
|
||||||
|
// //_window = glfwCreateWindow(RenderTargetWidth, RenderTargetHeight, "SAMPLE", NULL, NULL);
|
||||||
|
// _window = window; // Misaki 修改
|
||||||
|
// if (_window == nullptr)
|
||||||
|
// {
|
||||||
|
// if (DebugLogEnable)
|
||||||
|
// {
|
||||||
|
// LAppPal::PrintLogLn("Can't create GLFW window.");
|
||||||
|
// }
|
||||||
|
// glfwTerminate();
|
||||||
|
// return GL_FALSE;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Windowのコンテキストをカレントに設定
|
||||||
|
// //glfwMakeContextCurrent(_window);
|
||||||
|
// _window->makeCurrent(); // Misaki 修改
|
||||||
|
// glfwSwapInterval(1);
|
||||||
|
//
|
||||||
|
// if (glewInit() != GLEW_OK) {
|
||||||
|
// if (DebugLogEnable)
|
||||||
|
// {
|
||||||
|
// LAppPal::PrintLogLn("Can't initilize glew.");
|
||||||
|
// }
|
||||||
|
// glfwTerminate();
|
||||||
|
// return GL_FALSE;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //テクスチャサンプリング設定
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
//
|
||||||
|
// //透過設定
|
||||||
|
// glEnable(GL_BLEND);
|
||||||
|
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// // Misaki 修改
|
||||||
|
// //コールバック関数の登録
|
||||||
|
// //glfwSetMouseButtonCallback(_window, EventHandler::OnMouseCallBack);
|
||||||
|
// //glfwSetCursorPosCallback(_window, EventHandler::OnMouseCallBack);
|
||||||
|
//
|
||||||
|
// // ウィンドウサイズ記憶
|
||||||
|
// //int width, height;
|
||||||
|
// //glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
||||||
|
// _windowWidth = _window->width(); // Misaki 修改
|
||||||
|
// _windowHeight = _window->height();
|
||||||
|
//
|
||||||
|
// //AppViewの初期化
|
||||||
|
// _view->Initialize();
|
||||||
|
//
|
||||||
|
// // Cubism SDK の初期化
|
||||||
|
// InitializeCubism();
|
||||||
|
//
|
||||||
|
// return GL_TRUE;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool LAppDelegate::Initialize(GLCore* window) // 原
|
||||||
|
// bool LAppDelegate::Initialize(QWidget* window) // 中间解耦版本
|
||||||
|
bool LAppDelegate::Initialize(int windowWidth, int windowHeight) // 完全解耦Qt
|
||||||
{
|
{
|
||||||
if (DebugLogEnable)
|
if (DebugLogEnable) LAppPal::PrintLogLn("START");
|
||||||
{
|
// _window = window; // 不再持有窗口指针
|
||||||
LAppPal::PrintLogLn("START");
|
// if (!_window) return false;
|
||||||
}
|
_windowWidth = windowWidth;
|
||||||
|
_windowHeight = windowHeight;
|
||||||
|
|
||||||
// GLFWの初期化
|
// OpenGL 初始化(不依赖 glew)
|
||||||
if (glfwInit() == GL_FALSE)
|
// 原代码:原始GL调用,已抽象到IRenderContext
|
||||||
{
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
if (DebugLogEnable)
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
{
|
// glEnable(GL_BLEND);
|
||||||
LAppPal::PrintLogLn("Can't initilize GLFW");
|
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
_renderContext->InitializeGLState();
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Windowの生成_
|
|
||||||
//_window = glfwCreateWindow(RenderTargetWidth, RenderTargetHeight, "SAMPLE", NULL, NULL);
|
|
||||||
_window = window; // Misaki 修改
|
|
||||||
if (_window == nullptr)
|
|
||||||
{
|
|
||||||
if (DebugLogEnable)
|
|
||||||
{
|
|
||||||
LAppPal::PrintLogLn("Can't create GLFW window.");
|
|
||||||
}
|
|
||||||
glfwTerminate();
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Windowのコンテキストをカレントに設定
|
|
||||||
//glfwMakeContextCurrent(_window);
|
|
||||||
_window->makeCurrent(); // Misaki 修改
|
|
||||||
glfwSwapInterval(1);
|
|
||||||
|
|
||||||
if (glewInit() != GLEW_OK) {
|
|
||||||
if (DebugLogEnable)
|
|
||||||
{
|
|
||||||
LAppPal::PrintLogLn("Can't initilize glew.");
|
|
||||||
}
|
|
||||||
glfwTerminate();
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//テクスチャサンプリング設定
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
|
|
||||||
//透過設定
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
|
|
||||||
// Misaki 修改
|
|
||||||
//コールバック関数の登録
|
|
||||||
//glfwSetMouseButtonCallback(_window, EventHandler::OnMouseCallBack);
|
|
||||||
//glfwSetCursorPosCallback(_window, EventHandler::OnMouseCallBack);
|
|
||||||
|
|
||||||
// ウィンドウサイズ記憶
|
|
||||||
//int width, height;
|
|
||||||
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
|
||||||
_windowWidth = _window->width(); // Misaki 修改
|
|
||||||
_windowHeight = _window->height();
|
|
||||||
|
|
||||||
//AppViewの初期化
|
|
||||||
_view->Initialize();
|
_view->Initialize();
|
||||||
|
|
||||||
// Cubism SDK の初期化
|
|
||||||
InitializeCubism();
|
InitializeCubism();
|
||||||
|
return true;
|
||||||
return GL_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAppDelegate::Release()
|
void LAppDelegate::Release()
|
||||||
@@ -121,7 +142,7 @@ void LAppDelegate::Release()
|
|||||||
// Windowの削除
|
// Windowの削除
|
||||||
//glfwDestroyWindow(_window); // Misaki 修改
|
//glfwDestroyWindow(_window); // Misaki 修改
|
||||||
|
|
||||||
glfwTerminate();
|
// glfwTerminate();
|
||||||
|
|
||||||
delete _textureManager;
|
delete _textureManager;
|
||||||
delete _view;
|
delete _view;
|
||||||
@@ -183,41 +204,54 @@ void LAppDelegate::resize(int width, int height)
|
|||||||
{
|
{
|
||||||
if ((_windowWidth != width || _windowHeight != height) && width > 0 && height > 0)
|
if ((_windowWidth != width || _windowHeight != height) && width > 0 && height > 0)
|
||||||
{
|
{
|
||||||
|
// 先更新尺寸再调_view方法,因为_view内部会通过GetWindowWidth/Height获取
|
||||||
|
_windowWidth = width;
|
||||||
|
_windowHeight = height;
|
||||||
//AppViewの初期化
|
//AppViewの初期化
|
||||||
_view->Initialize();
|
_view->Initialize();
|
||||||
// スプライトサイズを再設定
|
// スプライトサイズを再設定
|
||||||
_view->ResizeSprite();
|
_view->ResizeSprite();
|
||||||
// サイズを保存しておく
|
|
||||||
_windowWidth = width;
|
|
||||||
_windowHeight = height;
|
|
||||||
|
|
||||||
// ビューポート変更
|
// ビューポート変更
|
||||||
glViewport(0, 0, width, height);
|
// glViewport(0, 0, width, height); // 原始GL,改用IRenderContext
|
||||||
|
_renderContext->SetViewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glViewport(0, 0, width, height);
|
// glViewport(0, 0, width, height); // 原始GL,改用IRenderContext
|
||||||
|
_renderContext->SetViewport(0, 0, width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void LAppDelegate::update()
|
||||||
|
// {
|
||||||
|
// // 時間更新
|
||||||
|
// LAppPal::UpdateTime();
|
||||||
|
//
|
||||||
|
// // 画面の初期化
|
||||||
|
// //glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
// glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 渲染背景为透明
|
||||||
|
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
// glClearDepth(1.0);
|
||||||
|
//
|
||||||
|
// //描画更新
|
||||||
|
// _view->Render();
|
||||||
|
// }
|
||||||
void LAppDelegate::update()
|
void LAppDelegate::update()
|
||||||
{
|
{
|
||||||
// 時間更新
|
|
||||||
LAppPal::UpdateTime();
|
LAppPal::UpdateTime();
|
||||||
|
// 原代码:原始GL调用,已抽象到IRenderContext
|
||||||
// 画面の初期化
|
// glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
//glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 渲染背景为透明
|
// LAPP_GL_CLEAR_DEPTH(1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
_renderContext->Clear(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
glClearDepth(1.0);
|
_renderContext->ClearDepth(1.0f);
|
||||||
|
|
||||||
//描画更新
|
|
||||||
_view->Render();
|
_view->Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
LAppDelegate::LAppDelegate():
|
LAppDelegate::LAppDelegate():
|
||||||
_cubismOption(),
|
_cubismOption(),
|
||||||
_window(nullptr),
|
// _window(nullptr), // 已解耦,不再持有窗口指针
|
||||||
_captured(false),
|
_captured(false),
|
||||||
_mouseX(0.0f),
|
_mouseX(0.0f),
|
||||||
_mouseY(0.0f),
|
_mouseY(0.0f),
|
||||||
@@ -257,23 +291,139 @@ void LAppDelegate::InitializeCubism()
|
|||||||
_view->InitializeSprite();
|
_view->InitializeSprite();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAppDelegate::OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
|
// void LAppDelegate::OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
|
||||||
|
// {
|
||||||
|
// if (_view == nullptr)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (GLFW_MOUSE_BUTTON_LEFT != button)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (GLFW_PRESS == action)
|
||||||
|
// {
|
||||||
|
// _captured = true;
|
||||||
|
// _view->OnTouchesBegan(_mouseX, _mouseY);
|
||||||
|
// }
|
||||||
|
// else if (GLFW_RELEASE == action)
|
||||||
|
// {
|
||||||
|
// if (_captured)
|
||||||
|
// {
|
||||||
|
// _captured = false;
|
||||||
|
// _view->OnTouchesEnded(_mouseX, _mouseY);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void LAppDelegate::OnMouseCallBack(GLFWwindow* window, double x, double y)
|
||||||
|
// {
|
||||||
|
// _mouseX = static_cast<float>(x);
|
||||||
|
// _mouseY = static_cast<float>(y);
|
||||||
|
//
|
||||||
|
// if (!_captured)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (_view == nullptr)
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// _view->OnTouchesMoved(_mouseX, _mouseY);
|
||||||
|
// }
|
||||||
|
void LAppDelegate::OnMouseCallBack(double x, double y)
|
||||||
{
|
{
|
||||||
if (_view == nullptr)
|
_mouseX = static_cast<float>(x);
|
||||||
{
|
_mouseY = static_cast<float>(y);
|
||||||
return;
|
if (!_captured) return;
|
||||||
}
|
if (_view == nullptr) return;
|
||||||
if (GLFW_MOUSE_BUTTON_LEFT != button)
|
_view->OnTouchesMoved(_mouseX, _mouseY);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GLFW_PRESS == action)
|
// GLuint LAppDelegate::CreateShader()
|
||||||
|
// {
|
||||||
|
// //バーテックスシェーダのコンパイル
|
||||||
|
// GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
// const char* vertexShader =
|
||||||
|
// "#version 120\n"
|
||||||
|
// "attribute vec3 position;"
|
||||||
|
// "attribute vec2 uv;"
|
||||||
|
// "varying vec2 vuv;"
|
||||||
|
// "void main(void){"
|
||||||
|
// " gl_Position = vec4(position, 1.0);"
|
||||||
|
// " vuv = uv;"
|
||||||
|
// "}";
|
||||||
|
// glShaderSource(vertexShaderId, 1, &vertexShader, nullptr);
|
||||||
|
// glCompileShader(vertexShaderId);
|
||||||
|
// if(!CheckShader(vertexShaderId))
|
||||||
|
// {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //フラグメントシェーダのコンパイル
|
||||||
|
// GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
// const char* fragmentShader =
|
||||||
|
// "#version 120\n"
|
||||||
|
// "varying vec2 vuv;"
|
||||||
|
// "uniform sampler2D texture;"
|
||||||
|
// "uniform vec4 baseColor;"
|
||||||
|
// "void main(void){"
|
||||||
|
// " gl_FragColor = texture2D(texture, vuv) * baseColor;"
|
||||||
|
// "}";
|
||||||
|
// glShaderSource(fragmentShaderId, 1, &fragmentShader, nullptr);
|
||||||
|
// glCompileShader(fragmentShaderId);
|
||||||
|
// if (!CheckShader(fragmentShaderId))
|
||||||
|
// {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //プログラムオブジェクトの作成
|
||||||
|
// GLuint programId = glCreateProgram();
|
||||||
|
// glAttachShader(programId, vertexShaderId);
|
||||||
|
// glAttachShader(programId, fragmentShaderId);
|
||||||
|
//
|
||||||
|
// // リンク
|
||||||
|
// glLinkProgram(programId);
|
||||||
|
//
|
||||||
|
// glUseProgram(programId);
|
||||||
|
//
|
||||||
|
// return programId;
|
||||||
|
// }
|
||||||
|
GLuint LAppDelegate::CreateShader()
|
||||||
|
{
|
||||||
|
// Shader编译逻辑已移入GLRenderContext::CompileShader()
|
||||||
|
// 本函数保留兼容签名,内部委托给IRenderContext
|
||||||
|
return static_cast<GLuint>(_renderContext->GetShaderProgram());
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// 原Shader编译代码,已迁移至GLRenderContext::CompileShader()
|
||||||
|
GLuint LAppDelegate::CreateShader()
|
||||||
|
{
|
||||||
|
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES_3) || defined(EMBEDDED_LINUX)
|
||||||
|
// OpenGL ES 2.0/3.0 着色器
|
||||||
|
const char* vertexShader = ...;
|
||||||
|
...
|
||||||
|
#else
|
||||||
|
...
|
||||||
|
#endif
|
||||||
|
...
|
||||||
|
return programId;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 鼠标回调简化(不再依赖 GLFWwindow*)
|
||||||
|
void LAppDelegate::OnMouseCallBack(int button, int action, int mods)
|
||||||
|
{
|
||||||
|
if (_view == nullptr) return;
|
||||||
|
if (button != 0) return; // 只处理左键,0 代表左键(与 Qt 约定一致)
|
||||||
|
if (action == 1) // 按下
|
||||||
{
|
{
|
||||||
_captured = true;
|
_captured = true;
|
||||||
_view->OnTouchesBegan(_mouseX, _mouseY);
|
_view->OnTouchesBegan(_mouseX, _mouseY);
|
||||||
}
|
}
|
||||||
else if (GLFW_RELEASE == action)
|
else if (action == 0) // 释放
|
||||||
{
|
{
|
||||||
if (_captured)
|
if (_captured)
|
||||||
{
|
{
|
||||||
@@ -283,73 +433,6 @@ void LAppDelegate::OnMouseCallBack(GLFWwindow* window, int button, int action, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAppDelegate::OnMouseCallBack(GLFWwindow* window, double x, double y)
|
|
||||||
{
|
|
||||||
_mouseX = static_cast<float>(x);
|
|
||||||
_mouseY = static_cast<float>(y);
|
|
||||||
|
|
||||||
if (!_captured)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_view == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_view->OnTouchesMoved(_mouseX, _mouseY);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint LAppDelegate::CreateShader()
|
|
||||||
{
|
|
||||||
//バーテックスシェーダのコンパイル
|
|
||||||
GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
const char* vertexShader =
|
|
||||||
"#version 120\n"
|
|
||||||
"attribute vec3 position;"
|
|
||||||
"attribute vec2 uv;"
|
|
||||||
"varying vec2 vuv;"
|
|
||||||
"void main(void){"
|
|
||||||
" gl_Position = vec4(position, 1.0);"
|
|
||||||
" vuv = uv;"
|
|
||||||
"}";
|
|
||||||
glShaderSource(vertexShaderId, 1, &vertexShader, nullptr);
|
|
||||||
glCompileShader(vertexShaderId);
|
|
||||||
if(!CheckShader(vertexShaderId))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//フラグメントシェーダのコンパイル
|
|
||||||
GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
const char* fragmentShader =
|
|
||||||
"#version 120\n"
|
|
||||||
"varying vec2 vuv;"
|
|
||||||
"uniform sampler2D texture;"
|
|
||||||
"uniform vec4 baseColor;"
|
|
||||||
"void main(void){"
|
|
||||||
" gl_FragColor = texture2D(texture, vuv) * baseColor;"
|
|
||||||
"}";
|
|
||||||
glShaderSource(fragmentShaderId, 1, &fragmentShader, nullptr);
|
|
||||||
glCompileShader(fragmentShaderId);
|
|
||||||
if (!CheckShader(fragmentShaderId))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//プログラムオブジェクトの作成
|
|
||||||
GLuint programId = glCreateProgram();
|
|
||||||
glAttachShader(programId, vertexShaderId);
|
|
||||||
glAttachShader(programId, fragmentShaderId);
|
|
||||||
|
|
||||||
// リンク
|
|
||||||
glLinkProgram(programId);
|
|
||||||
|
|
||||||
glUseProgram(programId);
|
|
||||||
|
|
||||||
return programId;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LAppDelegate::CheckShader(GLuint shaderId)
|
bool LAppDelegate::CheckShader(GLuint shaderId)
|
||||||
{
|
{
|
||||||
GLint status;
|
GLint status;
|
||||||
|
|||||||
+17
-19
@@ -15,8 +15,7 @@
|
|||||||
#include <filesystem> // Linux / macOS 用 std::filesystem
|
#include <filesystem> // Linux / macOS 用 std::filesystem
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#endif
|
#endif
|
||||||
#include <GL/glew.h>
|
#include "LAppOpenGL.hpp"
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <Rendering/CubismRenderer.hpp>
|
#include <Rendering/CubismRenderer.hpp>
|
||||||
#include "LAppPal.hpp"
|
#include "LAppPal.hpp"
|
||||||
#include "LAppDefine.hpp"
|
#include "LAppDefine.hpp"
|
||||||
@@ -222,8 +221,8 @@ void LAppLive2DManager::OnUpdate() const
|
|||||||
{
|
{
|
||||||
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
||||||
|
|
||||||
int width = LAppDelegate::GetInstance()->GetWindow()->width();
|
int width = LAppDelegate::GetInstance()->GetWindowWidth();
|
||||||
int height = LAppDelegate::GetInstance()->GetWindow()->height();
|
int height = LAppDelegate::GetInstance()->GetWindowHeight();
|
||||||
|
|
||||||
csmUint32 modelCount = _models.GetSize();
|
csmUint32 modelCount = _models.GetSize();
|
||||||
for (csmUint32 i = 0; i < modelCount; ++i)
|
for (csmUint32 i = 0; i < modelCount; ++i)
|
||||||
@@ -264,17 +263,16 @@ void LAppLive2DManager::OnUpdate() const
|
|||||||
LAppDelegate::GetInstance()->GetView()->PostModelDraw(*model);
|
LAppDelegate::GetInstance()->GetView()->PostModelDraw(*model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#include <AppContext.h>
|
// #include <AppContext.h> // 解耦,改用LAppDelegate回调
|
||||||
void LAppLive2DManager::ModelSizeChange(const int Sacle = 15)
|
void LAppLive2DManager::ModelSizeChange(const int Sacle = 15)
|
||||||
{
|
{
|
||||||
// 加载完后根据模型大小来重新设置当前窗口大小
|
|
||||||
const int width = static_cast<int>(_models[0]->GetModel()->GetCanvasWidthPixel() / Sacle);
|
const int width = static_cast<int>(_models[0]->GetModel()->GetCanvasWidthPixel() / Sacle);
|
||||||
const int height = static_cast<int>(_models[0]->GetModel()->GetCanvasHeightPixel() / Sacle);
|
const int height = static_cast<int>(_models[0]->GetModel()->GetCanvasHeightPixel() / Sacle);
|
||||||
|
|
||||||
// 确保在主线程调用 UI 相关操作
|
// if(AppContext::GetGLCore()) { // 原
|
||||||
if(AppContext::GetGLCore()) {
|
// AppContext::GetGLCore()->setWindowSize(width, height);
|
||||||
AppContext::GetGLCore()->setWindowSize(width, height);
|
// }
|
||||||
}
|
LAppDelegate::GetInstance()->NotifyWindowResize(width, height); // 通过回调通知应用层
|
||||||
LAppPal::PrintLogLn("[APP]窗口尺寸重新设置为: W: %d H: %d", width, height);
|
LAppPal::PrintLogLn("[APP]窗口尺寸重新设置为: W: %d H: %d", width, height);
|
||||||
}
|
}
|
||||||
void LAppLive2DManager::LoadModelFromPath(const std::string& modelPath, const std::string& fileName)
|
void LAppLive2DManager::LoadModelFromPath(const std::string& modelPath, const std::string& fileName)
|
||||||
@@ -289,7 +287,8 @@ void LAppLive2DManager::LoadModelFromPath(const std::string& modelPath, const st
|
|||||||
// 加载完后根据模型大小来重新设置当前窗口大小
|
// 加载完后根据模型大小来重新设置当前窗口大小
|
||||||
const int width = static_cast<int>(_models[0]->GetModel()->GetCanvasWidthPixel() / 15.0);
|
const int width = static_cast<int>(_models[0]->GetModel()->GetCanvasWidthPixel() / 15.0);
|
||||||
const int height = static_cast<int>(_models[0]->GetModel()->GetCanvasHeightPixel() / 15.0);
|
const int height = static_cast<int>(_models[0]->GetModel()->GetCanvasHeightPixel() / 15.0);
|
||||||
AppContext::GetGLCore()->setWindowSize(width, height); // 获取GLCore上下文
|
// AppContext::GetGLCore()->setWindowSize(width, height); // 原
|
||||||
|
LAppDelegate::GetInstance()->NotifyWindowResize(width, height); // 通过回调通知应用层
|
||||||
LAppPal::PrintLogLn("[APP]窗口尺寸重新设置为: W: %d H: %d", width, height);
|
LAppPal::PrintLogLn("[APP]窗口尺寸重新设置为: W: %d H: %d", width, height);
|
||||||
/*
|
/*
|
||||||
* 提供一个半透明表示模型的示例。
|
* 提供一个半透明表示模型的示例。
|
||||||
@@ -352,14 +351,13 @@ void LAppLive2DManager::MountLoadedModel(LAppModel* model)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 加载完后根据模型大小来重新设置当前窗口大小
|
// 加载完后根据模型大小来重新设置当前窗口大小
|
||||||
const int width = static_cast<int>(_models[0]->GetModel()->GetCanvasWidthPixel() / 15.0);
|
// 原代码直接调AppContext,改为统一使用ModelSizeChange
|
||||||
const int height = static_cast<int>(_models[0]->GetModel()->GetCanvasHeightPixel() / 15.0);
|
// const int width = static_cast<int>(_models[0]->GetModel()->GetCanvasWidthPixel() / 15.0);
|
||||||
|
// const int height = static_cast<int>(_models[0]->GetModel()->GetCanvasHeightPixel() / 15.0);
|
||||||
// 确保在主线程调用 UI 相关操作
|
// if(AppContext::GetGLCore()) {
|
||||||
if(AppContext::GetGLCore()) {
|
// AppContext::GetGLCore()->setWindowSize(width, height);
|
||||||
AppContext::GetGLCore()->setWindowSize(width, height);
|
// }
|
||||||
}
|
ModelSizeChange(15); // 统一入口,回调通知应用层
|
||||||
LAppPal::PrintLogLn("[APP]窗口尺寸重新设置为: W: %d H: %d", width, height);
|
|
||||||
|
|
||||||
// 设置渲染目标等
|
// 设置渲染目标等
|
||||||
{
|
{
|
||||||
|
|||||||
+12
-6
@@ -789,7 +789,8 @@ void LAppModel::DoDraw()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->DrawModel();
|
// GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->DrawModel();
|
||||||
|
GetRenderer<CUBISM_RENDERER_TYPE>()->DrawModel(); // 适配不同渲染器
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAppModel::Draw(CubismMatrix44& matrix)
|
void LAppModel::Draw(CubismMatrix44& matrix)
|
||||||
@@ -801,8 +802,10 @@ void LAppModel::Draw(CubismMatrix44& matrix)
|
|||||||
|
|
||||||
matrix.MultiplyByMatrix(_modelMatrix);
|
matrix.MultiplyByMatrix(_modelMatrix);
|
||||||
|
|
||||||
GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->SetMvpMatrix(&matrix);
|
// 設定MVP行列
|
||||||
|
// GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->SetMvpMatrix(&matrix);
|
||||||
|
GetRenderer<CUBISM_RENDERER_TYPE>()->SetMvpMatrix(&matrix); // 适配不同渲染器
|
||||||
|
// 描画
|
||||||
DoDraw();
|
DoDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,13 +895,16 @@ void LAppModel::SetupTextures()
|
|||||||
const csmInt32 glTextueNumber = texture->id;
|
const csmInt32 glTextueNumber = texture->id;
|
||||||
|
|
||||||
//OpenGL
|
//OpenGL
|
||||||
GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->BindTexture(modelTextureNumber, glTextueNumber);
|
// GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->BindTexture(modelTextureNumber, glTextueNumber);
|
||||||
|
GetRenderer<CUBISM_RENDERER_TYPE>()->BindTexture(modelTextureNumber, glTextueNumber); // 适配不同渲染器
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PREMULTIPLIED_ALPHA_ENABLE
|
#ifdef PREMULTIPLIED_ALPHA_ENABLE
|
||||||
GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->IsPremultipliedAlpha(true);
|
// GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->IsPremultipliedAlpha(true);
|
||||||
|
GetRenderer<CUBISM_RENDERER_TYPE>()->IsPremultipliedAlpha(true);
|
||||||
#else
|
#else
|
||||||
GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->IsPremultipliedAlpha(false);
|
// GetRenderer<Rendering::CubismRenderer_OpenGLES2>()->IsPremultipliedAlpha(false);
|
||||||
|
GetRenderer<CUBISM_RENDERER_TYPE>()->IsPremultipliedAlpha(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-5
@@ -6,13 +6,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "LAppPal.hpp"
|
#include "LAppPal.hpp"
|
||||||
|
#include "LAppDefine.hpp"
|
||||||
|
#include <chrono>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <GL/glew.h>
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <Model/CubismMoc.hpp>
|
#include <Model/CubismMoc.hpp>
|
||||||
#include "LAppDefine.hpp"
|
#include "LAppDefine.hpp"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -93,11 +93,24 @@ csmFloat32 LAppPal::GetDeltaTime()
|
|||||||
return static_cast<csmFloat32>(s_deltaTime);
|
return static_cast<csmFloat32>(s_deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::chrono::steady_clock::time_point s_lastTime;
|
||||||
|
static double s_deltaTime = 0.0;
|
||||||
void LAppPal::UpdateTime()
|
void LAppPal::UpdateTime()
|
||||||
{
|
{
|
||||||
s_currentFrame = glfwGetTime();
|
// s_currentFrame = glfwGetTime();
|
||||||
s_deltaTime = s_currentFrame - s_lastFrame;
|
// s_deltaTime = s_currentFrame - s_lastFrame;
|
||||||
s_lastFrame = s_currentFrame;
|
// s_lastFrame = s_currentFrame;
|
||||||
|
static bool initialized = false;
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
s_lastTime = std::chrono::steady_clock::now();
|
||||||
|
initialized = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
std::chrono::duration<double> diff = now - s_lastTime;
|
||||||
|
s_deltaTime = diff.count();
|
||||||
|
s_lastTime = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAppPal::PrintLog(const csmChar* format, ...)
|
void LAppPal::PrintLog(const csmChar* format, ...)
|
||||||
|
|||||||
+17
-9
@@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
#include "LAppSprite.hpp"
|
#include "LAppSprite.hpp"
|
||||||
|
|
||||||
LAppSprite::LAppSprite(float x, float y, float width, float height, GLuint textureId, GLuint programId)
|
// LAppSprite::LAppSprite(float x, float y, float width, float height, GLuint textureId, GLuint programId) // 原
|
||||||
|
LAppSprite::LAppSprite(float x, float y, float width, float height, uintptr_t textureId, uintptr_t programId) // 抽象类型
|
||||||
: _rect()
|
: _rect()
|
||||||
{
|
{
|
||||||
_rect.left = (x - width * 0.5f);
|
_rect.left = (x - width * 0.5f);
|
||||||
@@ -16,11 +17,15 @@ LAppSprite::LAppSprite(float x, float y, float width, float height, GLuint textu
|
|||||||
_rect.down = (y - height * 0.5f);
|
_rect.down = (y - height * 0.5f);
|
||||||
_textureId = textureId;
|
_textureId = textureId;
|
||||||
|
|
||||||
// 何番目のattribute変数か
|
// 原代码:直接传GLuint,改用static_cast适配抽象类型uintptr_t
|
||||||
_positionLocation = glGetAttribLocation(programId, "position");
|
// _positionLocation = glGetAttribLocation(programId, "position");
|
||||||
_uvLocation = glGetAttribLocation(programId, "uv");
|
// _uvLocation = glGetAttribLocation(programId, "uv");
|
||||||
_textureLocation = glGetUniformLocation(programId, "texture");
|
// _textureLocation = glGetUniformLocation(programId, "texture");
|
||||||
_colorLocation = glGetUniformLocation(programId, "baseColor");
|
// _colorLocation = glGetUniformLocation(programId, "baseColor");
|
||||||
|
_positionLocation = glGetAttribLocation(static_cast<GLuint>(programId), "position");
|
||||||
|
_uvLocation = glGetAttribLocation(static_cast<GLuint>(programId), "uv");
|
||||||
|
_textureLocation = glGetUniformLocation(static_cast<GLuint>(programId), "texture");
|
||||||
|
_colorLocation = glGetUniformLocation(static_cast<GLuint>(programId), "baseColor");
|
||||||
|
|
||||||
_spriteColor[0] = 1.0f;
|
_spriteColor[0] = 1.0f;
|
||||||
_spriteColor[1] = 1.0f;
|
_spriteColor[1] = 1.0f;
|
||||||
@@ -72,11 +77,13 @@ void LAppSprite::Render() const
|
|||||||
|
|
||||||
|
|
||||||
// モデルの描画
|
// モデルの描画
|
||||||
glBindTexture(GL_TEXTURE_2D, _textureId);
|
// glBindTexture(GL_TEXTURE_2D, _textureId); // 原
|
||||||
|
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(_textureId)); // 抽象类型转换
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAppSprite::RenderImmidiate(GLuint textureId, const GLfloat uvVertex[8]) const
|
// void LAppSprite::RenderImmidiate(GLuint textureId, const GLfloat uvVertex[8]) const // 原
|
||||||
|
void LAppSprite::RenderImmidiate(uintptr_t textureId, const float uvVertex[8]) const // 抽象类型
|
||||||
{
|
{
|
||||||
if (_maxWidth == 0 || _maxHeight == 0)
|
if (_maxWidth == 0 || _maxHeight == 0)
|
||||||
{
|
{
|
||||||
@@ -106,7 +113,8 @@ void LAppSprite::RenderImmidiate(GLuint textureId, const GLfloat uvVertex[8]) co
|
|||||||
glUniform4f(_colorLocation, _spriteColor[0], _spriteColor[1], _spriteColor[2], _spriteColor[3]);
|
glUniform4f(_colorLocation, _spriteColor[0], _spriteColor[1], _spriteColor[2], _spriteColor[3]);
|
||||||
|
|
||||||
// モデルの描画
|
// モデルの描画
|
||||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
// glBindTexture(GL_TEXTURE_2D, textureId); // 原
|
||||||
|
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(textureId)); // 抽象类型转换
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-13
@@ -60,8 +60,8 @@ void LAppView::Initialize()
|
|||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
||||||
width = LAppDelegate::GetInstance()->GetWindow()->width();
|
width = LAppDelegate::GetInstance()->GetWindowWidth();
|
||||||
height = LAppDelegate::GetInstance()->GetWindow()->height();
|
height = LAppDelegate::GetInstance()->GetWindowHeight();
|
||||||
|
|
||||||
if(width==0 || height==0)
|
if(width==0 || height==0)
|
||||||
{
|
{
|
||||||
@@ -109,8 +109,8 @@ void LAppView::Render()
|
|||||||
// 画面サイズを取得する
|
// 画面サイズを取得する
|
||||||
int maxWidth, maxHeight;
|
int maxWidth, maxHeight;
|
||||||
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &maxWidth, &maxHeight);
|
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &maxWidth, &maxHeight);
|
||||||
maxWidth = LAppDelegate::GetInstance()->GetWindow()->width();
|
maxWidth = LAppDelegate::GetInstance()->GetWindowWidth();
|
||||||
maxHeight = LAppDelegate::GetInstance()->GetWindow()->height();
|
maxHeight = LAppDelegate::GetInstance()->GetWindowHeight();
|
||||||
|
|
||||||
//_back->SetWindowSize(maxWidth, maxHeight);
|
//_back->SetWindowSize(maxWidth, maxHeight);
|
||||||
//_gear->SetWindowSize(maxWidth, maxHeight);
|
//_gear->SetWindowSize(maxWidth, maxHeight);
|
||||||
@@ -155,12 +155,13 @@ void LAppView::Render()
|
|||||||
|
|
||||||
void LAppView::InitializeSprite()
|
void LAppView::InitializeSprite()
|
||||||
{
|
{
|
||||||
_programId = LAppDelegate::GetInstance()->CreateShader();
|
// _programId = LAppDelegate::GetInstance()->CreateShader();
|
||||||
|
_programId = LAppDelegate::GetInstance()->GetRenderContext()->CreateShaderProgram();
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
||||||
width = LAppDelegate::GetInstance()->GetWindow()->width();
|
width = LAppDelegate::GetInstance()->GetWindowWidth();
|
||||||
height = LAppDelegate::GetInstance()->GetWindow()->height();
|
height = LAppDelegate::GetInstance()->GetWindowHeight();
|
||||||
|
|
||||||
LAppTextureManager* textureManager = LAppDelegate::GetInstance()->GetTextureManager();
|
LAppTextureManager* textureManager = LAppDelegate::GetInstance()->GetTextureManager();
|
||||||
const string resourcesPath = ResourcesPath;
|
const string resourcesPath = ResourcesPath;
|
||||||
@@ -196,6 +197,13 @@ void LAppView::InitializeSprite()
|
|||||||
// x = width * 0.5f;
|
// x = width * 0.5f;
|
||||||
// y = height * 0.5f;
|
// y = height * 0.5f;
|
||||||
// _renderSprite = new LAppSprite(x, y, static_cast<float>(width), static_cast<float>(height), 0, _programId);
|
// _renderSprite = new LAppSprite(x, y, static_cast<float>(width), static_cast<float>(height), 0, _programId);
|
||||||
|
// _programId 类型由GLuint改为uintptr_t,构造参数匹配
|
||||||
|
// _renderSprite = new LAppSprite(x, y, static_cast<float>(width),
|
||||||
|
// static_cast<float>(height), 0,
|
||||||
|
// static_cast<GLuint>(_programId));
|
||||||
|
float x = width * 0.5f;
|
||||||
|
float y = height * 0.5f;
|
||||||
|
_renderSprite = new LAppSprite(x, y, static_cast<float>(width), static_cast<float>(height), 0, static_cast<uintptr_t>(_programId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAppView::OnTouchesBegan(float px, float py) const
|
void LAppView::OnTouchesBegan(float px, float py) const
|
||||||
@@ -303,8 +311,8 @@ void LAppView::PreModelDraw(LAppModel& refModel)
|
|||||||
{// 描画ターゲット内部未作成の場合はここで作成
|
{// 描画ターゲット内部未作成の場合はここで作成
|
||||||
int width, height;
|
int width, height;
|
||||||
/*glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);*/
|
/*glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);*/
|
||||||
width = LAppDelegate::GetInstance()->GetWindow()->width();
|
width = LAppDelegate::GetInstance()->GetWindowWidth();
|
||||||
height = LAppDelegate::GetInstance()->GetWindow()->height();
|
height = LAppDelegate::GetInstance()->GetWindowHeight();
|
||||||
|
|
||||||
if (width != 0 && height != 0)
|
if (width != 0 && height != 0)
|
||||||
{
|
{
|
||||||
@@ -350,8 +358,8 @@ void LAppView::PostModelDraw(LAppModel& refModel)
|
|||||||
int maxWidth, maxHeight;
|
int maxWidth, maxHeight;
|
||||||
/*glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &maxWidth, &maxHeight);*/
|
/*glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &maxWidth, &maxHeight);*/
|
||||||
|
|
||||||
maxWidth = LAppDelegate::GetInstance()->GetWindow()->width(); // Misaki 修改
|
maxWidth = LAppDelegate::GetInstance()->GetWindowWidth(); // Misaki 修改
|
||||||
maxHeight = LAppDelegate::GetInstance()->GetWindow()->height();
|
maxHeight = LAppDelegate::GetInstance()->GetWindowHeight();
|
||||||
|
|
||||||
_renderSprite->SetWindowSize(maxWidth, maxHeight);
|
_renderSprite->SetWindowSize(maxWidth, maxHeight);
|
||||||
|
|
||||||
@@ -400,8 +408,8 @@ void LAppView::ResizeSprite()
|
|||||||
// 描画領域サイズ
|
// 描画領域サイズ
|
||||||
int width, height;
|
int width, height;
|
||||||
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
//glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
|
||||||
width = LAppDelegate::GetInstance()->GetWindow()->width();
|
width = LAppDelegate::GetInstance()->GetWindowWidth();
|
||||||
height = LAppDelegate::GetInstance()->GetWindow()->height();
|
height = LAppDelegate::GetInstance()->GetWindowHeight();
|
||||||
|
|
||||||
float x = 0.0f;
|
float x = 0.0f;
|
||||||
float y = 0.0f;
|
float y = 0.0f;
|
||||||
|
|||||||
+170
-121
@@ -6,7 +6,51 @@ set(CMAKE_AUTOMOC ON)
|
|||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
set(CMAKE_PREFIX_PATH "/home/misaki/Qt/6.6.3/gcc_64") # 设置Qt6安装路径(此处请根据你的Qt6安装位置填写)
|
# 平台与架构检测
|
||||||
|
if(DEFINED TARGET_ARCH AND TARGET_ARCH STREQUAL "arm64")
|
||||||
|
set(PLAT "linux_arm")
|
||||||
|
set(ARCH "arm64")
|
||||||
|
set(CMAKE_PREFIX_PATH "/home/misaki/MisakiCodes/rk3566-sdk/3rd/Qt6.6.3")
|
||||||
|
add_definitions(-DCSM_TARGET_HARMONYOS_ES3) # OpenGL ES 3.0 渲染宏
|
||||||
|
add_definitions(-DEMBEDDED_LINUX) # 嵌入式Linux专用宏
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64")
|
||||||
|
set(PLAT "linux_arm")
|
||||||
|
set(ARCH "arm64")
|
||||||
|
set(CMAKE_PREFIX_PATH "/home/misaki/MisakiCodes/rk3566-sdk/3rd/Qt6.6.3")
|
||||||
|
add_definitions(-DCSM_TARGET_HARMONYOS_ES3)
|
||||||
|
add_definitions(-DEMBEDDED_LINUX)
|
||||||
|
elseif(WIN32)
|
||||||
|
set(PLAT "windows")
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
set(ARCH "x86_64")
|
||||||
|
else()
|
||||||
|
set(ARCH "x86")
|
||||||
|
endif()
|
||||||
|
set(CMAKE_PREFIX_PATH "Qt/6.6.3/gcc_64") ## 按照自己电脑上qt6.6.3的位置来替换
|
||||||
|
add_definitions(-DCSM_TARGET_WIN_GL)
|
||||||
|
elseif(APPLE)
|
||||||
|
set(PLAT "macos")
|
||||||
|
set(ARCH "x86_64") # 或通用二进制,可根据需要调整
|
||||||
|
set(CMAKE_PREFIX_PATH "/home/misaki/Qt/6.6.3/gcc_64")
|
||||||
|
add_definitions(-DCSM_TARGET_MAC_GL)
|
||||||
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
set(PLAT "linux_64")
|
||||||
|
set(ARCH "x86_64")
|
||||||
|
set(CMAKE_PREFIX_PATH "/home/misaki/Qt6.3/6.6.3/gcc_64")
|
||||||
|
add_definitions(-DCSM_TARGET_LINUX_GL)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported platform")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 渲染后端选择
|
||||||
|
if(PLAT STREQUAL "linux_arm")
|
||||||
|
add_definitions(-DRENDER_BACKEND_GLES2)
|
||||||
|
else()
|
||||||
|
add_definitions(-DRENDER_BACKEND_OPENGL)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS " 当前Qt路径: ${CMAKE_PREFIX_PATH}")
|
||||||
|
message(STATUS " 当前平台: ${PLAT}, 架构: ${ARCH}")
|
||||||
|
|
||||||
# 设置是否为debug模式 默认为Debug
|
# 设置是否为debug模式 默认为Debug
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
@@ -16,11 +60,7 @@ endif()
|
|||||||
# 设置渲染方式,选择为OpenGL,不然默认是Cocos2d,编译会报错的,CMake也会给你警告的
|
# 设置渲染方式,选择为OpenGL,不然默认是Cocos2d,编译会报错的,CMake也会给你警告的
|
||||||
set(FRAMEWORK_SOURCE OpenGL)
|
set(FRAMEWORK_SOURCE OpenGL)
|
||||||
|
|
||||||
# 查找一些必要的src文件
|
# 查找一些必要的src源文件
|
||||||
file(GLOB_RECURSE LAppLive2D
|
|
||||||
CONFIGURE_DEPENDS # CMake 3.12+:检测到新增文件自动重新生成
|
|
||||||
"3rdparty/Live2D/Src/LAppLive2D/Src/*.cpp"
|
|
||||||
)
|
|
||||||
file(GLOB_RECURSE YosugaSrc
|
file(GLOB_RECURSE YosugaSrc
|
||||||
CONFIGURE_DEPENDS
|
CONFIGURE_DEPENDS
|
||||||
"src/Handle/AudioHandle/Src/*.cpp"
|
"src/Handle/AudioHandle/Src/*.cpp"
|
||||||
@@ -29,12 +69,8 @@ file(GLOB_RECURSE YosugaSrc
|
|||||||
"src/Handle/NetWorkHandle/Inc/*.h"
|
"src/Handle/NetWorkHandle/Inc/*.h"
|
||||||
"src/Handle/DataObjectHandle/Src/*.cpp"
|
"src/Handle/DataObjectHandle/Src/*.cpp"
|
||||||
"src/Handle/DataObjectHandle/Inc/*.h"
|
"src/Handle/DataObjectHandle/Inc/*.h"
|
||||||
"src/UI/Menu/Src/*.cpp"
|
|
||||||
"src/UI/Menu/Inc/*.h"
|
|
||||||
"src/DAO/Inc/*.h"
|
"src/DAO/Inc/*.h"
|
||||||
"src/DAO/Src/*.cpp"
|
"src/DAO/Src/*.cpp"
|
||||||
"src/UI/Setting/Src/*.cpp"
|
|
||||||
"src/UI/Setting/Inc/*.h"
|
|
||||||
"src/UI/Render/TextRender/Src/*.cpp"
|
"src/UI/Render/TextRender/Src/*.cpp"
|
||||||
"src/UI/Render/TextRender/Inc/*.h"
|
"src/UI/Render/TextRender/Inc/*.h"
|
||||||
"src/Core/Src/*.cpp"
|
"src/Core/Src/*.cpp"
|
||||||
@@ -44,6 +80,18 @@ file(GLOB_RECURSE YosugaSrc
|
|||||||
"src/Utils/Src/*.cpp"
|
"src/Utils/Src/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 如果是桌面平台,再额外添加 UI 相关目录
|
||||||
|
if(NOT PLAT STREQUAL "linux_arm")
|
||||||
|
file(GLOB_RECURSE DesktopUI_Src
|
||||||
|
"src/UI/Menu/Src/*.cpp"
|
||||||
|
"src/UI/Menu/Inc/*.h"
|
||||||
|
"src/UI/Setting/Src/*.cpp"
|
||||||
|
"src/UI/Setting/Inc/*.h"
|
||||||
|
)
|
||||||
|
message(STATUS " 被主机平台额外包含的库: ${YosugaSrc}")
|
||||||
|
list(APPEND YosugaSrc ${DesktopUI_Src})
|
||||||
|
endif()
|
||||||
|
|
||||||
# 查找Qt6模块以及其他必须模块
|
# 查找Qt6模块以及其他必须模块
|
||||||
find_package(Qt6 COMPONENTS
|
find_package(Qt6 COMPONENTS
|
||||||
Core
|
Core
|
||||||
@@ -57,83 +105,105 @@ find_package(Qt6 COMPONENTS
|
|||||||
OpenGLWidgets
|
OpenGLWidgets
|
||||||
Concurrent
|
Concurrent
|
||||||
REQUIRED)
|
REQUIRED)
|
||||||
find_package(OpenGL REQUIRED)
|
|
||||||
|
|
||||||
|
# 仅在非 ARM 平台查找桌面 OpenGL
|
||||||
|
if(NOT PLAT STREQUAL "linux_arm")
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
else ()
|
||||||
|
# 若为arm平台,对于C++采用静态链接标准库,避免环境复杂出现问题
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "-static-libstdc++ -static-libgcc")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# 添加第三方子项目
|
||||||
|
if(NOT PLAT STREQUAL "linux_arm")
|
||||||
|
### 部分第三方子项目与嵌入式Linux不兼容(嵌入式Linux环境复杂,有的没有桌面环境,因此不一定支持窗口)
|
||||||
add_subdirectory(3rdparty/ElaWidgetTools) # 添加ElaWidgetTools UI库
|
add_subdirectory(3rdparty/ElaWidgetTools) # 添加ElaWidgetTools UI库
|
||||||
add_subdirectory(3rdparty/autogui-cpp) # 添加autogui-cpp GUI自动化库
|
add_subdirectory(3rdparty/autogui-cpp) # 添加autogui-cpp GUI自动化库
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} main.cpp ${LAppLive2D} ${YosugaSrc})
|
|
||||||
|
|
||||||
# 区分平台
|
|
||||||
if(WIN32)
|
|
||||||
set(PLAT "windows")
|
|
||||||
add_definitions(-DCSM_TARGET_WIN_GL) # 告诉 Live2D 框架,当前平台使用 OpenGL
|
|
||||||
elseif(APPLE)
|
|
||||||
set(PLAT "macos")
|
|
||||||
add_definitions(-DCSM_TARGET_MAC_GL)
|
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
||||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64")
|
|
||||||
set(PLAT "linux_arm")
|
|
||||||
add_definitions(-DCSM_TARGET_LINUX_GL)
|
|
||||||
else()
|
else()
|
||||||
set(PLAT "linux_64")
|
message(STATUS "ARM platform: skipping ElaWidgetTools and autogui-cpp (cross‑compile them separately)")
|
||||||
add_definitions(-DCSM_TARGET_LINUX_GL)
|
|
||||||
endif()
|
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
|
|
||||||
set(PLAT "macos") # 统一按 macos 处理,后面再细分 x86_64 / arm64
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# 架构文件夹名(Windows 分 x86 / x86_64,Linux 分 x86_64 / arm64,macOS 通用二进制)
|
#### 主可执行文件
|
||||||
if(WIN32)
|
add_executable(${PROJECT_NAME} main.cpp ${YosugaSrc})
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(ARCH "x86_64")
|
#### 库导入路径配置
|
||||||
|
# Framework 静态库
|
||||||
|
if(PLAT STREQUAL "linux_arm")
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
### 注意此处需要根据你的framework的放置目录进行调整
|
||||||
|
set(FRAMEWORK_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Live2D/Lib/Debug/linux_arm/framework/misaki_rk3566/libFramework.a")
|
||||||
else()
|
else()
|
||||||
set(ARCH "x86")
|
set(FRAMEWORK_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Live2D/Lib/Release/linux_arm/framework/misaki_rk3566/libFramework.a")
|
||||||
endif()
|
endif()
|
||||||
elseif(PLAT STREQUAL "linux_arm")
|
|
||||||
set(ARCH "arm64")
|
|
||||||
else()
|
else()
|
||||||
set(ARCH "x86_64")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#### 以下为链接相关的内容
|
|
||||||
|
|
||||||
# 根据平台 + 架构生成“库搜索路径”和“库文件名”
|
|
||||||
set(LIB_BASE "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Live2D/Lib")
|
|
||||||
# 根据当前构建类型直接确定子目录(Debug 或 Release)
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
set(LIB_CONFIG "Debug")
|
set(LIB_CONFIG "Debug")
|
||||||
else()
|
else()
|
||||||
set(LIB_CONFIG "Release")
|
set(LIB_CONFIG "Release")
|
||||||
endif()
|
endif()
|
||||||
|
set(LIB_BASE "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Live2D/Lib")
|
||||||
message(STATUS "当前平台与编译方式: ${PLAT} : ${ARCH} : ${LIB_CONFIG}" )
|
|
||||||
|
|
||||||
# 拼接完整库目录
|
|
||||||
set(LIB_CONFIG_DIR "${LIB_BASE}/${LIB_CONFIG}/${PLAT}")
|
set(LIB_CONFIG_DIR "${LIB_BASE}/${LIB_CONFIG}/${PLAT}")
|
||||||
# 需要链接的库列表
|
set(FRAMEWORK_LIB_PATH "${LIB_CONFIG_DIR}/framework/libFramework.a")
|
||||||
# Framework(只有 .a,且 Debug/Release 同名)
|
endif()
|
||||||
add_library(Framework STATIC IMPORTED GLOBAL)
|
|
||||||
set_target_properties(Framework PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${LIB_CONFIG_DIR}/framework/libFramework.a")
|
|
||||||
message(STATUS "当前Framework库: libFramework.a")
|
|
||||||
|
|
||||||
|
add_library(Framework STATIC IMPORTED GLOBAL)
|
||||||
|
set_target_properties(Framework PROPERTIES IMPORTED_LOCATION "${FRAMEWORK_LIB_PATH}")
|
||||||
|
message(STATUS "Framework 库: ${FRAMEWORK_LIB_PATH}")
|
||||||
|
|
||||||
|
# Core 静态库 该库由官方自行编译提供,理论上是平台无关的,但是可能和glibc版本有关,太老的glibc版本不一定能使用
|
||||||
|
# 因为Core没有开源,也因此才叫Live2D SDK,而不是Live2D Lib。个人觉得不如开源出来,像Qt那样就挺好。
|
||||||
|
if(PLAT STREQUAL "linux_arm")
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set(CORE_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Live2D/Lib/Debug/linux_arm/live2d/static_lib/arm64/libLive2DCubismCore.a")
|
||||||
|
else()
|
||||||
|
set(CORE_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Live2D/Lib/Release/linux_arm/live2d/static_lib/arm64/libLive2DCubismCore.a")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(PLAT STREQUAL "windows")
|
||||||
|
set(CORE_LIB_PATH "${LIB_CONFIG_DIR}/live2d/static_lib/x86_64/Live2DCubismCore.lib")
|
||||||
|
else()
|
||||||
|
set(CORE_LIB_PATH "${LIB_CONFIG_DIR}/live2d/static_lib/x86_64/libLive2DCubismCore.a")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(Live2DCubismCore STATIC IMPORTED GLOBAL)
|
||||||
|
set_target_properties(Live2DCubismCore PROPERTIES IMPORTED_LOCATION "${CORE_LIB_PATH}")
|
||||||
|
message(STATUS "Live2D Core 库: ${CORE_LIB_PATH}")
|
||||||
|
|
||||||
|
# 导入 LAppLive2D 子项目 Live2D 应用层,静态库
|
||||||
|
# 依赖顺序:lapp_live2d -> Framework -> Live2DCubismCore
|
||||||
|
add_subdirectory(3rdparty/Live2D/Src/LAppLive2D)
|
||||||
|
|
||||||
|
# LAppOpenGL.hpp 根据平台选择 GL / GLES2 头文件,为 lapp_live2d 补充对应路径
|
||||||
|
if(NOT PLAT STREQUAL "linux_arm")
|
||||||
|
target_include_directories(lapp_live2d PUBLIC
|
||||||
|
3rdparty/Live2D/Src/glew/include
|
||||||
|
3rdparty/Live2D/Src/glew/include/GL
|
||||||
|
3rdparty/Live2D/Src/glfw/include
|
||||||
|
3rdparty/Live2D/Src/glfw/include/GLFW
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
target_include_directories(lapp_live2d PUBLIC
|
||||||
|
/home/misaki/MisakiCodes/rk3566-sdk/host/aarch64-buildroot-linux-gnu/sysroot/usr/include
|
||||||
|
/home/misaki/MisakiCodes/rk3566-sdk/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/GLES2
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# GLFW 和 GLEW(仅桌面平台需要)
|
||||||
|
if(NOT PLAT STREQUAL "linux_arm")
|
||||||
# glfw
|
# glfw
|
||||||
add_library(glfw3 STATIC IMPORTED GLOBAL)
|
add_library(glfw3 STATIC IMPORTED GLOBAL)
|
||||||
set_target_properties(glfw3 PROPERTIES
|
set_target_properties(glfw3 PROPERTIES IMPORTED_LOCATION "${LIB_CONFIG_DIR}/glfw/libglfw3.a")
|
||||||
IMPORTED_LOCATION "${LIB_CONFIG_DIR}/glfw/libglfw3.a")
|
message(STATUS "GLFW 库: libglfw3.a")
|
||||||
message(STATUS "当前GLEW库: libglfw3.a")
|
|
||||||
|
|
||||||
# glew Debug/Release 同名,Debug 同时提供了 .so,此处用 .a
|
# glew
|
||||||
# Debug 带 'd' 后缀,Release 不带
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
# GLEW Unix与Windows生成行为不一致
|
|
||||||
if(PLAT STREQUAL "windows")
|
if(PLAT STREQUAL "windows")
|
||||||
set(GLEW_LIB_NAME "libglew32d.dll.a")
|
set(GLEW_LIB_NAME "libglew32d.dll.a")
|
||||||
else () # 其他平台
|
else()
|
||||||
set(GLEW_LIB_NAME "libGLEWd.a")
|
set(GLEW_LIB_NAME "libGLEWd.a")
|
||||||
endif()
|
endif()
|
||||||
elseif (CMAKE_BUILD_TYPE STREQUAL "Release")
|
else()
|
||||||
if(PLAT STREQUAL "windows")
|
if(PLAT STREQUAL "windows")
|
||||||
set(GLEW_LIB_NAME "libglew32.dll.a")
|
set(GLEW_LIB_NAME "libglew32.dll.a")
|
||||||
else()
|
else()
|
||||||
@@ -141,69 +211,56 @@ elseif (CMAKE_BUILD_TYPE STREQUAL "Release")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
add_library(GLEW STATIC IMPORTED GLOBAL)
|
add_library(GLEW STATIC IMPORTED GLOBAL)
|
||||||
set_target_properties(GLEW PROPERTIES
|
set_target_properties(GLEW PROPERTIES IMPORTED_LOCATION "${LIB_CONFIG_DIR}/glfw/${GLEW_LIB_NAME}")
|
||||||
IMPORTED_LOCATION "${LIB_CONFIG_DIR}/glfw/${GLEW_LIB_NAME}")
|
message(STATUS "GLEW 库: ${GLEW_LIB_NAME}")
|
||||||
message(STATUS "当前GLEW库: ${GLEW_LIB_NAME}")
|
|
||||||
|
|
||||||
# Live2D Cubism Core 静态
|
|
||||||
add_library(Live2DCubismCore STATIC IMPORTED GLOBAL)
|
|
||||||
if (PLAT STREQUAL "windows")
|
|
||||||
set_target_properties(Live2DCubismCore PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${LIB_CONFIG_DIR}/live2d/static_lib/x86_64/Live2DCubismCore.lib")
|
|
||||||
message(STATUS "当前Live2D库: Live2DCubismCore.lib")
|
|
||||||
else ()
|
|
||||||
set_target_properties(Live2DCubismCore PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${LIB_CONFIG_DIR}/live2d/static_lib/x86_64/libLive2DCubismCore.a")
|
|
||||||
message(STATUS "当前Live2D库: libLive2DCubismCore.a")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
#### 以下为链接相关的内容
|
||||||
PRIVATE
|
if(PLAT STREQUAL "linux_arm") ## 针对嵌入式Linux的配置,部分条目需要根据你的soc以及sysroot进行修改
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
|
lapp_live2d
|
||||||
|
Framework
|
||||||
|
Live2DCubismCore
|
||||||
|
# Mali GPU 驱动完整链接(EGLFS 必需)
|
||||||
|
-lmali-hook # 注意此处,你的soc不一定是该GPU,可能需要修改
|
||||||
|
-Wl,--whole-archive -lmali-hook-injector -Wl,--no-whole-archive
|
||||||
|
-lmali
|
||||||
|
-ldrm
|
||||||
|
-lEGL
|
||||||
|
-lGLESv2
|
||||||
|
# Qt 模块(从交叉编译的 Qt)
|
||||||
|
Qt::Core Qt::Gui Qt::Widgets Qt::Network Qt::Svg Qt::SerialPort
|
||||||
|
Qt::WebSockets Qt::Multimedia Qt::OpenGLWidgets Qt::Concurrent
|
||||||
|
#
|
||||||
|
# ElaWidgetTools autogui-cpp
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
# 桌面平台
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
|
lapp_live2d
|
||||||
Framework
|
Framework
|
||||||
glfw3
|
glfw3
|
||||||
GLEW
|
GLEW
|
||||||
Live2DCubismCore
|
Live2DCubismCore
|
||||||
$<$<BOOL:${WIN32}>:opengl32> # WIN32 为真时才链接
|
$<$<BOOL:${WIN32}>:opengl32>
|
||||||
$<$<BOOL:${WIN32}>:glu32> # WIN32 为真时才链接
|
$<$<BOOL:${WIN32}>:glu32>
|
||||||
)
|
|
||||||
# 不论平台统一需要链接的库
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
|
||||||
PRIVATE
|
|
||||||
ElaWidgetTools
|
ElaWidgetTools
|
||||||
autogui-cpp
|
autogui-cpp
|
||||||
Qt::Core
|
Qt::Core Qt::Gui Qt::Widgets Qt::Network Qt::Svg Qt::SerialPort
|
||||||
Qt::Gui
|
Qt::WebSockets Qt::Multimedia Qt::OpenGLWidgets Qt::Concurrent
|
||||||
Qt::Widgets
|
|
||||||
Qt::Network
|
|
||||||
Qt::Svg
|
|
||||||
Qt::SerialPort
|
|
||||||
Qt::WebSockets
|
|
||||||
Qt::Multimedia
|
|
||||||
Qt::OpenGLWidgets
|
|
||||||
Qt::Concurrent
|
|
||||||
)
|
)
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT PLAT STREQUAL "linux_arm")
|
||||||
# 全局热键 (PTT) 所需平台库
|
find_package(X11 REQUIRED)
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE X11::X11)
|
||||||
|
endif()
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
find_library(COREGRAPHICS_LIB CoreGraphics REQUIRED)
|
find_library(COREGRAPHICS_LIB CoreGraphics REQUIRED)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${COREGRAPHICS_LIB})
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${COREGRAPHICS_LIB})
|
||||||
endif()
|
endif()
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
||||||
find_package(X11 REQUIRED)
|
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE X11::X11)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# 添加头文件
|
# 头文件路径
|
||||||
target_include_directories(${PROJECT_NAME}
|
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||||
PRIVATE
|
|
||||||
3rdparty/Live2D/Src/Framework/src
|
|
||||||
3rdparty/Live2D/Src/glew/include
|
|
||||||
3rdparty/Live2D/Src/glew/include/GL
|
|
||||||
3rdparty/Live2D/Src/glfw/include
|
|
||||||
3rdparty/Live2D/Src/glfw/include/GLFW
|
|
||||||
3rdparty/Live2D/Src/Core/include
|
|
||||||
3rdparty/Live2D/Src/stb
|
|
||||||
3rdparty/Live2D/Src/LAppLive2D/Inc
|
|
||||||
3rdparty/autogui-cpp/src
|
3rdparty/autogui-cpp/src
|
||||||
src/Handle/AudioHandle/Inc
|
src/Handle/AudioHandle/Inc
|
||||||
src/Handle/NetWorkHandle/Inc
|
src/Handle/NetWorkHandle/Inc
|
||||||
@@ -216,19 +273,13 @@ target_include_directories(${PROJECT_NAME}
|
|||||||
src/Utils/Inc
|
src/Utils/Inc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 资源复制(所有平台)
|
||||||
|
|
||||||
#### 构建时额外复制一些必要的文件与运行库
|
|
||||||
|
|
||||||
# 将资源文件夹 'other' 复制到构建目录
|
|
||||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/other/Resources"
|
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/other/Resources"
|
||||||
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
# 复制 Live2D 渲染所需的 Shader 文件
|
|
||||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/other/FrameworkShaders"
|
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/other/FrameworkShaders"
|
||||||
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
||||||
|
# Windows 特有的 DLL 复制
|
||||||
# 对于windows,复制一些必要的dll库
|
|
||||||
if(PLAT STREQUAL "windows")
|
if(PLAT STREQUAL "windows")
|
||||||
# 自动复制Ela的DLL
|
# 自动复制Ela的DLL
|
||||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||||
@@ -301,6 +352,4 @@ if(PLAT STREQUAL "windows")
|
|||||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Live2D/Lib/Debug/windows/live2d/static_lib/x86_64/Live2DCubismCore.dll"
|
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/Live2D/Lib/Debug/windows/live2d/static_lib/x86_64/Live2DCubismCore.dll"
|
||||||
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
endif ()
|
endif ()
|
||||||
elseif () # 其他平台
|
|
||||||
set()
|
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -2,7 +2,13 @@
|
|||||||
|
|
||||||
#include <QtWidgets/QWidget>
|
#include <QtWidgets/QWidget>
|
||||||
#include <QOpenGLWidget>
|
#include <QOpenGLWidget>
|
||||||
|
#if !defined(EMBEDDED_LINUX)
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#endif
|
||||||
|
#ifdef EMBEDDED_LINUX
|
||||||
|
#include <QPushButton>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -79,7 +85,13 @@ private:
|
|||||||
double frameRate = 60.0; /// 帧率
|
double frameRate = 60.0; /// 帧率
|
||||||
static QMap<QString, double> frameRateMap; /// 帧率映射表
|
static QMap<QString, double> frameRateMap; /// 帧率映射表
|
||||||
QTimer* frameTimer; /// 帧控制定时器
|
QTimer* frameTimer; /// 帧控制定时器
|
||||||
|
#if !defined(EMBEDDED_LINUX)
|
||||||
Menu *contextMenu; /// 使用 Menu 类
|
Menu *contextMenu; /// 使用 Menu 类
|
||||||
|
#endif
|
||||||
|
#ifdef EMBEDDED_LINUX
|
||||||
|
QPushButton *pttButton; /// 嵌入式平台PTT按钮
|
||||||
|
#endif
|
||||||
|
|
||||||
bool isLeftPressed; /// 鼠标左键是否按下
|
bool isLeftPressed; /// 鼠标左键是否按下
|
||||||
bool isRightPressed; /// 鼠标右键是否按下
|
bool isRightPressed; /// 鼠标右键是否按下
|
||||||
QPoint currentPos; /// 当前鼠标位置
|
QPoint currentPos; /// 当前鼠标位置
|
||||||
|
|||||||
+61
-2
@@ -14,8 +14,12 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "TextRenderer.h"
|
#include "TextRenderer.h"
|
||||||
// #include "AudioOutput.h"
|
|
||||||
#include "AppContext.h"
|
#include "AppContext.h"
|
||||||
|
#include "GLRenderContext.hpp" // 渲染后端抽象
|
||||||
|
#ifdef EMBEDDED_LINUX
|
||||||
|
#include "AppCore.h"
|
||||||
|
#include <QIcon>
|
||||||
|
#endif
|
||||||
QMap<QString, double> GLCore::frameRateMap = {
|
QMap<QString, double> GLCore::frameRateMap = {
|
||||||
{"30", 30.0},
|
{"30", 30.0},
|
||||||
{"60", 60.0},
|
{"60", 60.0},
|
||||||
@@ -49,7 +53,9 @@ GLCore::GLCore(const int width, const int height, QWidget *parent)
|
|||||||
QApplication::setFont(QFont("Microsoft YaHei", 13));
|
QApplication::setFont(QFont("Microsoft YaHei", 13));
|
||||||
|
|
||||||
// new一些必要的对象
|
// new一些必要的对象
|
||||||
|
#if !defined(EMBEDDED_LINUX)
|
||||||
contextMenu = new Menu(this);
|
contextMenu = new Menu(this);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 设置窗口大小
|
// 设置窗口大小
|
||||||
setFixedSize(width, height);
|
setFixedSize(width, height);
|
||||||
@@ -81,7 +87,38 @@ GLCore::GLCore(const int width, const int height, QWidget *parent)
|
|||||||
this->setMouseTracking(true);
|
this->setMouseTracking(true);
|
||||||
|
|
||||||
// 连接一些必要的信号与槽
|
// 连接一些必要的信号与槽
|
||||||
|
#ifndef EMBEDDED_LINUX // 如果不是嵌入式Linux系统(注意如果你的嵌入式Linux平台启用了桌面系统,那么可能需要去掉这个条件宏)
|
||||||
connect(contextMenu, &Menu::closeMainWindow, this, &GLCore::closeGL); // 关闭窗口信号
|
connect(contextMenu, &Menu::closeMainWindow, this, &GLCore::closeGL); // 关闭窗口信号
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EMBEDDED_LINUX
|
||||||
|
AppCore::getInstance();
|
||||||
|
|
||||||
|
pttButton = new QPushButton(this);
|
||||||
|
pttButton->setFixedSize(64, 64);
|
||||||
|
pttButton->move(width - 80, height - 80);
|
||||||
|
pttButton->setIcon(QIcon("Resources/Pic/Others/voice.png"));
|
||||||
|
pttButton->setIconSize(QSize(56, 56));
|
||||||
|
pttButton->setStyleSheet(
|
||||||
|
"QPushButton {"
|
||||||
|
" background-color: rgba(255, 255, 255, 60);"
|
||||||
|
" border-radius: 32px;"
|
||||||
|
" border: none;"
|
||||||
|
"}"
|
||||||
|
"QPushButton:pressed {"
|
||||||
|
" background-color: rgba(250, 80, 80, 150);"
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
pttButton->raise();
|
||||||
|
pttButton->show();
|
||||||
|
|
||||||
|
connect(pttButton, &QPushButton::pressed, this, []() {
|
||||||
|
AppCore::getInstance()->startPttRecording();
|
||||||
|
});
|
||||||
|
connect(pttButton, &QPushButton::released, this, []() {
|
||||||
|
AppCore::getInstance()->stopPttRecording();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
// 注册当前实例到中介类
|
// 注册当前实例到中介类
|
||||||
AppContext::RegisterGLCore(this);
|
AppContext::RegisterGLCore(this);
|
||||||
@@ -191,10 +228,12 @@ void GLCore::mouseMoveEvent(QMouseEvent* event)
|
|||||||
const float y = static_cast<float>(event->position().y());
|
const float y = static_cast<float>(event->position().y());
|
||||||
LAppDelegate::GetInstance()->GetView()->OnTouchesMoved(x, y); // 将当前鼠标位置传递给LAppDelegate
|
LAppDelegate::GetInstance()->GetView()->OnTouchesMoved(x, y); // 将当前鼠标位置传递给LAppDelegate
|
||||||
|
|
||||||
|
#if !defined(EMBEDDED_LINUX)
|
||||||
if (isLeftPressed) { // 鼠标左键按下
|
if (isLeftPressed) { // 鼠标左键按下
|
||||||
const QPoint newPos = event->globalPos() - currentPos;
|
const QPoint newPos = event->globalPos() - currentPos;
|
||||||
this->move(newPos);
|
this->move(newPos);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCore::mousePressEvent(QMouseEvent* event)
|
void GLCore::mousePressEvent(QMouseEvent* event)
|
||||||
@@ -249,7 +288,9 @@ void GLCore::mousePressEvent(QMouseEvent* event)
|
|||||||
if (event->button() == Qt::RightButton) {
|
if (event->button() == Qt::RightButton) {
|
||||||
// 在鼠标右键点击的位置创建菜单,显示自定义右键菜单
|
// 在鼠标右键点击的位置创建菜单,显示自定义右键菜单
|
||||||
if (onModel) {
|
if (onModel) {
|
||||||
|
#if !defined(EMBEDDED_LINUX)
|
||||||
contextMenu->showMenu(event->globalPos());
|
contextMenu->showMenu(event->globalPos());
|
||||||
|
#endif
|
||||||
this->isRightPressed = true;
|
this->isRightPressed = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -297,7 +338,25 @@ void GLCore::mouseReleaseEvent(QMouseEvent* event)
|
|||||||
|
|
||||||
void GLCore::initializeGL()
|
void GLCore::initializeGL()
|
||||||
{
|
{
|
||||||
LAppDelegate::GetInstance()->Initialize(this);
|
// 注入渲染后端抽象层,由GLCore(OpenGL)创建GLRenderContext并交给LAppDelegate管理
|
||||||
|
if (!LAppDelegate::GetInstance()->GetRenderContext()) {
|
||||||
|
LAppDelegate::GetInstance()->SetRenderContext(new GLRenderContext());
|
||||||
|
}
|
||||||
|
// 初始化GLEW 必须在任何Live2D渲染操作之前调用
|
||||||
|
// Live2D预编译的libFramework.a使用GLEW函数指针(如glGenFramebuffers等),
|
||||||
|
// 未调用glewInit()会导致空指针解引用SIGSEGV
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
if (glewInit() != GLEW_OK) {
|
||||||
|
qFatal("Failed to initialize GLEW");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册窗口大小变更回调 模型加载后通过此回调通知GLCore调整窗口
|
||||||
|
LAppDelegate::GetInstance()->SetWindowResizeCallback([this](int w, int h) {
|
||||||
|
setWindowSize(w, h);
|
||||||
|
});
|
||||||
|
// LAppDelegate::GetInstance()->Initialize(this); // 原(QWidget*)
|
||||||
|
LAppDelegate::GetInstance()->Initialize(this->width(), this->height()); // 解耦
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCore::paintGL()
|
void GLCore::paintGL()
|
||||||
|
|||||||
Reference in New Issue
Block a user