1. 完全解耦了Live2D的LApp部分,使其可以接入任何GUI库

2. 初步尝试合并嵌入式Linux平台支持的相关代码,预计在下一次提交完整支持。
This commit is contained in:
Misaki
2026-06-24 01:05:26 +08:00
parent 5141e524dd
commit f7be85fbf6
24 changed files with 1590 additions and 421 deletions
+102
View File
@@ -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;
}
};
+17
View File
@@ -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;
};
+19
View File
@@ -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
View File
@@ -7,10 +7,10 @@
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "LAppOpenGL.hpp"
#include "LAppAllocator.hpp"
#include "GLCore.h"
#include "IRenderContext.hpp"
#include <functional>
class LAppView;
class LAppTextureManager;
@@ -37,17 +37,29 @@ public:
static void ReleaseInstance();
// 新增
// resize 由应用层(GLCore::resizeGL)调用,通知LApp窗口尺寸变更
void resize(int width, int height);
// 新增
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に必要なものを初期化する。
* @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 解放する。
@@ -67,7 +79,8 @@ public:
* @param[in] action 実行結果
* @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用関数。
@@ -76,7 +89,8 @@ public:
* @param[in] x 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 シェーダーを登録する。
@@ -84,9 +98,12 @@ public:
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情報を取得する。
@@ -126,10 +143,13 @@ private:
*/
bool CheckShader(GLuint shaderId);
IRenderContext* _renderContext = nullptr;
WindowResizeFunc _onResizeWindow; ///< 窗口大小回调
LAppAllocator _cubismAllocator; ///< Cubism SDK Allocator
Csm::CubismFramework::Option _cubismOption; ///< Cubism SDK Option
//GLFWwindow* _window; ///< OpenGL ウィンドウ
GLCore* _window; ///< Misaki 修改
// GLCore* _window; ///< Misaki 修改
// QWidget* _window; ///< 使用QWidget基类,解耦GLCore
LAppView* _view; ///< View情報
bool _captured; ///< クリックしているか
float _mouseX; ///< マウスX座標
@@ -141,23 +161,23 @@ private:
int _windowHeight; ///< Initialize関数で設定したウィンドウ高さ
};
class EventHandler
{
public:
/**
* @brief glfwSetMouseButtonCallback用コールバック関数。
*/
static void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
{
LAppDelegate::GetInstance()->OnMouseCallBack(window, button, action, modify);
}
/**
* @brief glfwSetCursorPosCallback用コールバック関数。
*/
static void OnMouseCallBack(GLFWwindow* window, double x, double y)
{
LAppDelegate::GetInstance()->OnMouseCallBack(window, x, y);
}
};
// class EventHandler
// {
// public:
// /**
// * @brief glfwSetMouseButtonCallback用コールバック関数。
// */
// static void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
// {
// LAppDelegate::GetInstance()->OnMouseCallBack(window, button, action, modify);
// }
//
// /**
// * @brief glfwSetCursorPosCallback用コールバック関数。
// */
// static void OnMouseCallBack(GLFWwindow* window, double x, double y)
// {
// LAppDelegate::GetInstance()->OnMouseCallBack(window, x, y);
// }
//
// };
+3 -1
View File
@@ -17,6 +17,7 @@
#include <map>
#include <vector>
#include <string>
#include "LAppOpenGL.hpp"
/**
* @brief ユーザーが実際に使用するモデルの実装クラス<br>
* モデル生成、機能コンポーネント生成、更新処理とレンダリングの呼び出しを行う。
@@ -286,5 +287,6 @@ private:
Live2D::Cubism::Framework::csmFloat32 alpha = 0.8f; // 滤波系数,范围在0到1之间,值越小,平滑效果越强
Live2D::Cubism::Framework::csmFloat32 filteredValue = 0.0f; // 滤波后的值
Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
// Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
CUBISM_OFFSCREEN_TYPE _renderBuffer;
};
+46
View File
@@ -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
View File
@@ -7,8 +7,8 @@
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "LAppOpenGL.hpp"
#include "ISpriteRenderer.hpp" // 渲染后端抽象
/**
* @brief スプライトを実装するクラス。
@@ -16,7 +16,8 @@
* テクスチャID、Rectの管理。
*
*/
class LAppSprite
// class LAppSprite // 原
class LAppSprite : public ISpriteRenderer // 继承渲染抽象接口
{
public:
/**
@@ -41,7 +42,8 @@ public:
* @param[in] textureId テクスチャ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 デストラクタ
@@ -52,7 +54,8 @@ public:
* @brief Getter テクスチャID
* @return テクスチャIDを返す
*/
GLuint GetTextureId() { return _textureId; }
// GLuint GetTextureId() { return _textureId; } // 原
uintptr_t GetTextureId() const override { return _textureId; } // 抽象类型
/**
* @brief 描画する
@@ -64,7 +67,8 @@ public:
* @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 コンストラクタ
@@ -72,7 +76,8 @@ public:
* @param[in] pointX x座標
* @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 色設定
@@ -82,7 +87,8 @@ public:
* @param[in] b (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 サイズ再設定
@@ -92,7 +98,8 @@ public:
* @param[in] width 横幅
* @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 ウインドウサイズ設定
@@ -100,10 +107,12 @@ public:
* @param[in] width 横幅
* @param[in] height 高さ
*/
void SetWindowSize(int width, int height);
// void SetWindowSize(int width, int height); // 原
void SetWindowSize(int width, int height) override; // 接口实现
private:
GLuint _textureId; ///< テクスチャID
// GLuint _textureId; ///< テクスチャID
uintptr_t _textureId; ///< テクスチャID 抽象类型
Rect _rect; ///< 矩形
int _positionLocation; ///< 位置アトリビュート
int _uvLocation; ///< UVアトリビュート
+3 -3
View File
@@ -8,8 +8,7 @@
#pragma once
#include <string>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "LAppOpenGL.hpp"
#include <Type/csmVector.hpp>
/**
@@ -26,7 +25,8 @@ public:
*/
struct TextureInfo
{
GLuint id; ///< テクスチャID
// GLuint id; ///< テクスチャID
uintptr_t id;
int width; ///< 横幅
int height; ///< 高さ
std::string fileName; ///< ファイル名
+8 -5
View File
@@ -7,12 +7,12 @@
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "LAppOpenGL.hpp"
#include <Math/CubismMatrix44.hpp>
#include <Math/CubismViewMatrix.hpp>
#include "CubismFramework.hpp"
#include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
#include "ISpriteRenderer.hpp" // 绘制接口抽象
class TouchManager;
class LAppSprite;
@@ -158,14 +158,17 @@ private:
TouchManager* _touchManager; ///< タッチマネージャー
Csm::CubismMatrix44* _deviceToScreen; ///< デバイスからスクリーンへの行列
Csm::CubismViewMatrix* _viewMatrix; ///< viewMatrix
GLuint _programId; ///< シェーダID
// GLuint _programId; ///< シェーダID
uintptr_t _programId; ///< 顶点着色器ID
//LAppSprite* _back; ///< 背景画像
//LAppSprite* _gear; ///< ギア画像
//LAppSprite* _power; ///< 電源画像
// レンダリング先を別ターゲットにする方式の場合に使用
LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< モードによってはCubismモデル結果をこっちにレンダリング
// LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
ISpriteRenderer* _renderSprite; ///< 绘制接口抽象
// Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< モードによってはCubismモデル結果をこっちにレンダリング
CUBISM_OFFSCREEN_TYPE _renderBuffer;
SelectTarget _renderTarget; ///< レンダリング先の選択肢
float _clearColor[4]; ///< レンダリングターゲットのクリアカラー
};