This commit is contained in:
Misaki
2025-12-04 19:11:29 +08:00
commit bb600bbbc4
2741 changed files with 364700 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <CubismFramework.hpp>
#include <ICubismAllocator.hpp>
/**
* @brief メモリアロケーションを実装するクラス。
*
* メモリ確保・解放処理のインターフェースの実装。
* フレームワークから呼び出される。
*
*/
class LAppAllocator : public Csm::ICubismAllocator
{
/**
* @brief メモリ領域を割り当てる。
*
* @param[in] size 割り当てたいサイズ。
* @return 指定したメモリ領域
*/
void* Allocate(const Csm::csmSizeType size);
/**
* @brief メモリ領域を解放する
*
* @param[in] memory 解放するメモリ。
*/
void Deallocate(void* memory);
/**
* @brief
*
* @param[in] size 割り当てたいサイズ。
* @param[in] alignment 割り当てたいサイズ。
* @return alignedAddress
*/
void* AllocateAligned(const Csm::csmSizeType size, const Csm::csmUint32 alignment);
/**
* @brief
*
* @param[in] alignedMemory 解放するメモリ。
*/
void DeallocateAligned(void* alignedMemory);
};
+65
View File
@@ -0,0 +1,65 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <CubismFramework.hpp>
/**
* @brief Sample Appで使用する定数
*
*/
namespace LAppDefine {
using namespace Csm;
extern const csmFloat32 ViewScale; ///< 拡大縮小率
extern const csmFloat32 ViewMaxScale; ///< 拡大縮小率の最大値
extern const csmFloat32 ViewMinScale; ///< 拡大縮小率の最小値
extern const csmFloat32 ViewLogicalLeft; ///< 論理的なビュー座標系の左端の値
extern const csmFloat32 ViewLogicalRight; ///< 論理的なビュー座標系の右端の値
extern const csmFloat32 ViewLogicalBottom; ///< 論理的なビュー座標系の下端の値
extern const csmFloat32 ViewLogicalTop; ///< 論理的なビュー座標系の上端の値
extern const csmFloat32 ViewLogicalMaxLeft; ///< 論理的なビュー座標系の左端の最大値
extern const csmFloat32 ViewLogicalMaxRight; ///< 論理的なビュー座標系の右端の最大値
extern const csmFloat32 ViewLogicalMaxBottom; ///< 論理的なビュー座標系の下端の最大値
extern const csmFloat32 ViewLogicalMaxTop; ///< 論理的なビュー座標系の上端の最大値
extern const csmChar* ResourcesPath; ///< 素材パス
extern const csmChar* BackImageName; ///< 背景画像ファイル
extern const csmChar* GearImageName; ///< 歯車画像ファイル
extern const csmChar* PowerImageName; ///< 終了ボタン画像ファイル
// モデル定義--------------------------------------------
// 外部定義ファイル(json)と合わせる
extern const csmChar* MotionGroupIdle; ///< アイドリング時に再生するモーションのリスト
extern const csmChar* MotionGroupTapBody; ///< 体をタップした時に再生するモーションのリスト
// 外部定義ファイル(json)と合わせる
extern const csmChar* HitAreaNameHead; ///< 当たり判定の[Head]タグ
extern const csmChar* HitAreaNameBody; ///< 当たり判定の[Body]タグ
// モーションの優先度定数
extern const csmInt32 PriorityNone; ///< モーションの優先度定数: 0
extern const csmInt32 PriorityIdle; ///< モーションの優先度定数: 1
extern const csmInt32 PriorityNormal; ///< モーションの優先度定数: 2
extern const csmInt32 PriorityForce; ///< モーションの優先度定数: 3
extern const csmBool MocConsistencyValidationEnable; ///< MOC3の整合性検証機能の有効・無効
// デバッグ用ログの表示
extern const csmBool DebugLogEnable; ///< デバッグ用ログ表示の有効・無効
extern const csmBool DebugTouchLogEnable; ///< タッチ処理のデバッグ用ログ表示の有効・無効
// Frameworkから出力するログのレベル設定
extern const CubismFramework::Option::LogLevel CubismLoggingLevel;
// デフォルトのレンダーターゲットサイズ
extern const csmInt32 RenderTargetWidth;
extern const csmInt32 RenderTargetHeight;
}
+163
View File
@@ -0,0 +1,163 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "LAppAllocator.hpp"
#include "GLCore.h"
class LAppView;
class LAppTextureManager;
/**
* @brief アプリケーションクラス。
* Cubism SDK の管理を行う。
*/
class LAppDelegate
{
public:
/**
* @brief クラスのインスタンス(シングルトン)を返す。<br>
* インスタンスが生成されていない場合は内部でインスタンを生成する。
*
* @return クラスのインスタンス
*/
static LAppDelegate* GetInstance();
/**
* @brief クラスのインスタンス(シングルトン)を解放する。
*
*/
static void ReleaseInstance();
// 新增
void resize(int width, int height);
// 新增
void update();
/**
* @brief APPに必要なものを初期化する。
*/
//bool Initialize();
bool Initialize(GLCore* window);
/**
* @brief 解放する。
*/
void Release();
/**
* @brief 実行処理。
*/
//void Run(); // Misaki 修改
/**
* @brief OpenGL用 glfwSetMouseButtonCallback用関数。
*
* @param[in] window コールバックを呼んだWindow情報
* @param[in] button ボタン種類
* @param[in] action 実行結果
* @param[in] modify
*/
void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify);
/**
* @brief OpenGL用 glfwSetCursorPosCallback用関数。
*
* @param[in] window コールバックを呼んだWindow情報
* @param[in] x x座標
* @param[in] y x座標
*/
void OnMouseCallBack(GLFWwindow* window, double x, double y);
/**
* @brief シェーダーを登録する。
*/
GLuint CreateShader();
/**
* @brief Window情報を取得する。
*/
GLCore* GetWindow() { return _window; } // Misaki 修改
/**
* @brief View情報を取得する。
*/
LAppView* GetView() { return _view; }
/**
* @brief アプリケーションを終了するかどうか。
*/
bool GetIsEnd() { return _isEnd; }
/**
* @brief アプリケーションを終了する。
*/
void AppEnd() { _isEnd = true; }
LAppTextureManager* GetTextureManager() { return _textureManager; }
private:
/**
* @brief コンストラクタ
*/
LAppDelegate();
/**
* @brief デストラクタ
*/
~LAppDelegate();
/**
* @brief Cubism SDK の初期化
*/
void InitializeCubism();
/**
* @brief CreateShader内部関数 エラーチェック
*/
bool CheckShader(GLuint shaderId);
LAppAllocator _cubismAllocator; ///< Cubism SDK Allocator
Csm::CubismFramework::Option _cubismOption; ///< Cubism SDK Option
//GLFWwindow* _window; ///< OpenGL ウィンドウ
GLCore* _window; ///< Misaki 修改
LAppView* _view; ///< View情報
bool _captured; ///< クリックしているか
float _mouseX; ///< マウスX座標
float _mouseY; ///< マウスY座標
bool _isEnd; ///< APP終了しているか
LAppTextureManager* _textureManager; ///< テクスチャマネージャー
int _windowWidth; ///< Initialize関数で設定したウィンドウ幅
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);
}
};
+170
View File
@@ -0,0 +1,170 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <CubismFramework.hpp>
#include <Math/CubismMatrix44.hpp>
#include <Type/csmVector.hpp>
#include <string>
class LAppModel;
/**
* @brief サンプルアプリケーションにおいてCubismModelを管理するクラス<br>
* モデル生成と破棄、タップイベントの処理、モデル切り替えを行う。
*
*/
class LAppLive2DManager
{
public:
/**
* @brief クラスのインスタンス(シングルトン)を返す。<br>
* インスタンスが生成されていない場合は内部でインスタンを生成する。
*
* @return クラスのインスタンス
*/
static LAppLive2DManager* GetInstance();
/**
* @brief クラスのインスタンス(シングルトン)を解放する。
*
*/
static void ReleaseInstance();
/**
* @brief Resources フォルダにあるモデルフォルダ名をセットする
*
*
* 无需多言,这个也宣布弃用了,这个函数功能是自动扫描路径下所有模型
*/
void SetUpModel();
/**
* @brief Resources フォルダにあるモデルフォルダ名を取得する
*
*/
Csm::csmVector<Csm::csmString> GetModelDir() const;
/**
* @brief Resources フォルダにあるモデルフォルダのサイズを取得する
*
*/
Csm::csmInt32 GetModelDirSize() const;
/**
* @brief 現在のシーンで保持しているモデルを返す
*
* @param[in] no モデルリストのインデックス値
* @return モデルのインスタンスを返す。インデックス値が範囲外の場合はNULLを返す。
*/
LAppModel* GetModel(Csm::csmUint32 no) const;
/**
* @brief 現在のシーンで保持しているすべてのモデルを解放する
*
*/
void ReleaseAllModel();
/**
* @brief 画面をドラッグしたときの処理
*
* @param[in] x 画面のX座標
* @param[in] y 画面のY座標
*/
void OnDrag(Csm::csmFloat32 x, Csm::csmFloat32 y) const;
/**
* @brief 画面をタップしたときの処理
*
* @param[in] x 画面のX座標
* @param[in] y 画面のY座標
*/
void OnTap(Csm::csmFloat32 x, Csm::csmFloat32 y);
/**
* @brief 画面を更新するときの処理
* モデルの更新処理および描画処理を行う
*/
void OnUpdate() const;
/**
* @brief 从指定路径加载模型
*
* @param[in] modelPath 模型文件的路径
* @param[in] fileName 模型文件的名称
*
* Misaki 增设于2024.12.17 <br>
*
* 举个例子:<br>
* LoadModelFromPath("Resources/Haru/", "Haru.model3.json");<br>
*
* 至于为什么要这样拆分,只是为了适应底层的模型加载函数<br>
* 你可以选择再上层封装,将传入的路径拆分为路径和文件名,然后调用本函数即可<br>
*/
void LoadModelFromPath(const std::string& modelPath, const std::string& fileName);
/**
* @brief 次のシーンに切り替える<br>
* サンプルアプリケーションではモデルセットの切り替えを行う。
*/
void NextScene();
/**
* @brief シーンを切り替える<br>
* サンプルアプリケーションではモデルセットの切り替えを行う。
*
* 如果你看到了这段文字,就代表你用的是被Misaki修改后的版本
* 那么现在告诉你,这个函数已经弃用,请使用LoadModelFromPath来进行导入模型文件
* 以及自行设计模型选择器
* 至于为什么修改,原生的SDK是自动查找指定目录的模型文件,自动加载的
* 但这样就与实际使用的需求大不相同,我们需要能够手动选择
*/
void ChangeScene(Csm::csmInt32 index);
/**
* @brief 启动当前活动模型的唇形同步并播放指定的 WAV 文件
* @param wavFilePath WAV 文件的路径
*/
void StartLipSync(const Csm::csmString& wavFilePath);
/**
* @brief 启动指定模型的唇形同步并播放指定的 WAV 文件
* @param modelIndex 模型索引
* @param wavFilePath WAV 文件的路径
*/
void StartLipSync(Live2D::Cubism::Framework::csmUint32 modelIndex, const Csm::csmString& wavFilePath);
/**
* @brief モデル個数を得る
* @return 所持モデル個数
*/
Csm::csmUint32 GetModelNum() const;
/**
* @brief viewMatrixをセットする
*/
void SetViewMatrix(Live2D::Cubism::Framework::CubismMatrix44* m);
private:
/**
* @brief コンストラクタ
*/
LAppLive2DManager();
/**
* @brief デストラクタ
*/
virtual ~LAppLive2DManager();
Csm::CubismMatrix44* _viewMatrix; ///< モデル描画に用いるView行列
Csm::csmVector<LAppModel*> _models; ///< モデルインスタンスのコンテナ
Csm::csmInt32 _sceneIndex; ///< 表示するシーンのインデックス値
Csm::csmVector<Csm::csmString> _modelDir; ///< モデルディレクトリ名のコンテナ
};
+231
View File
@@ -0,0 +1,231 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <CubismFramework.hpp>
#include <Model/CubismUserModel.hpp>
#include <ICubismModelSetting.hpp>
#include <Type/csmRectF.hpp>
#include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
#include "LAppWavFileHandler.hpp"
/**
* @brief ユーザーが実際に使用するモデルの実装クラス<br>
* モデル生成、機能コンポーネント生成、更新処理とレンダリングの呼び出しを行う。
*
*/
class LAppModel : public Csm::CubismUserModel
{
public:
/**
* @brief コンストラクタ
*/
LAppModel();
/**
* @brief デストラクタ
*
*/
virtual ~LAppModel();
/**
* @brief 获得Idle动画总数量
* @author Misaki
* @return int
*/
int getIdleMotionCount();
/**
* @brief 获得TapBody动画总数量
* @author Misaki
* @return int
*/
int getTapBodyMotionCount();
/**
* @brief 启动唇形同步并播放指定的 WAV 文件
* @param filePath WAV 文件的路径(csmString 类型)
* @author Misaki
*/
void StartLipSync(const Csm::csmString& filePath);
/**
* @brief 停止唇形同步并停止播放指定的 WAV 文件
* @author Misaki
*/
void StopLipSync();
/**
* @brief model3.jsonが置かれたディレクトリとファイルパスからモデルを生成する
*
*/
void LoadAssets(const Csm::csmChar* dir, const Csm::csmChar* fileName);
/**
* @brief レンダラを再構築する
*
*/
void ReloadRenderer();
/**
* @brief モデルの更新処理。モデルのパラメータから描画状態を決定する。
*
*/
void Update();
/**
* @brief モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
*
* @param[in] matrix View-Projection行列
*/
void Draw(Csm::CubismMatrix44& matrix);
/**
* @brief 引数で指定したモーションの再生を開始する。
*
* @param[in] group モーショングループ名
* @param[in] no グループ内の番号
* @param[in] priority 優先度
* @param[in] onFinishedMotionHandler モーション再生終了時に呼び出されるコールバック関数。NULLの場合、呼び出されない。
* @return 開始したモーションの識別番号を返す。個別のモーションが終了したか否かを判定するIsFinished()の引数で使用する。開始できない時は「-1」
*/
Csm::CubismMotionQueueEntryHandle StartMotion(const Csm::csmChar* group, Csm::csmInt32 no, Csm::csmInt32 priority, Csm::ACubismMotion::FinishedMotionCallback onFinishedMotionHandler = NULL);
/**
* @brief 开始播放随机选择的动画。
*
* @param[in] group 动画组名称
* @param[in] priority 优先级
* @param[in] onFinishedMotionHandler 动画播放结束时被调用的回调函数。如果为NULL,则不被调用。
* @return 返回开始播放的动画的标识编号。用于作为判断特定动画是否结束的IsFinished()函数的参数。如果无法开始播放,则返回「-1」
*/
Csm::CubismMotionQueueEntryHandle StartRandomMotion(const Csm::csmChar* group, Csm::csmInt32 priority, Csm::ACubismMotion::FinishedMotionCallback onFinishedMotionHandler = NULL);
/**
* @brief 引数で指定した表情モーションをセットする
*
* @param expressionID 表情モーションのID
*/
void SetExpression(const Csm::csmChar* expressionID);
/**
* @brief ランダムに選ばれた表情モーションをセットする
*
*/
void SetRandomExpression();
/**
* @brief イベントの発火を受け取る
*
*/
virtual void MotionEventFired(const Live2D::Cubism::Framework::csmString& eventValue);
/**
* @brief 当たり判定テスト。<br>
* 指定IDの頂点リストから矩形を計算し、座標が矩形範囲内か判定する。
*
* @param[in] hitAreaName 当たり判定をテストする対象のID
* @param[in] x 判定を行うX座標
* @param[in] y 判定を行うY座標
*/
virtual Csm::csmBool HitTest(const Csm::csmChar* hitAreaName, Csm::csmFloat32 x, Csm::csmFloat32 y);
/**
* @brief 別ターゲットに描画する際に使用するバッファの取得
*/
Csm::Rendering::CubismOffscreenSurface_OpenGLES2& GetRenderBuffer();
/**
* @brief .moc3ファイルの整合性をチェックする
*
* @param[in] mocName MOC3ファイル名
* @return MOC3に整合性があれば'true'、そうでなければ'false'。
*/
Csm::csmBool HasMocConsistencyFromFile(const Csm::csmChar* mocFileName);
protected:
/**
* @brief モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
*
*/
void DoDraw();
private:
/**
* @brief model3.jsonからモデルを生成する。<br>
* model3.jsonの記述に従ってモデル生成、モーション、物理演算などのコンポーネント生成を行う。
*
* @param[in] setting ICubismModelSettingのインスタンス
*
*/
void SetupModel(Csm::ICubismModelSetting* setting);
/**
* @brief OpenGLのテクスチャユニットにテクスチャをロードする
*
*/
void SetupTextures();
/**
* @brief モーションデータをグループ名から一括でロードする。<br>
* モーションデータの名前は内部でModelSettingから取得する。
*
* @param[in] group モーションデータのグループ名
*/
void PreloadMotionGroup(const Csm::csmChar* group);
/**
* @brief モーションデータをグループ名から一括で解放する。<br>
* モーションデータの名前は内部でModelSettingから取得する。
*
* @param[in] group モーションデータのグループ名
*/
void ReleaseMotionGroup(const Csm::csmChar* group) const;
/**
* @brief すべてのモーションデータの解放
*
* すべてのモーションデータを解放する。
*/
void ReleaseMotions();
/**
* @brief すべての表情データの解放
*
* すべての表情データを解放する。
*/
void ReleaseExpressions();
Csm::ICubismModelSetting* _modelSetting; ///< モデルセッティング情報
Csm::csmString _modelHomeDir; ///< モデルセッティングが置かれたディレクトリ
Csm::csmFloat32 _userTimeSeconds; ///< デルタ時間の積算値[秒]
Csm::csmVector<Csm::CubismIdHandle> _eyeBlinkIds; ///< モデルに設定されたまばたき機能用パラメータID
Csm::csmVector<Csm::CubismIdHandle> _lipSyncIds; ///< モデルに設定されたリップシンク機能用パラメータID
Csm::csmMap<Csm::csmString, Csm::ACubismMotion*> _motions; ///< 読み込まれているモーションのリスト
Csm::csmMap<Csm::csmString, Csm::ACubismMotion*> _expressions; ///< 読み込まれている表情のリスト
Csm::csmVector<Csm::csmRectF> _hitArea;
Csm::csmVector<Csm::csmRectF> _userArea;
const Csm::CubismId* _idParamAngleX; ///< パラメータID: ParamAngleX
const Csm::CubismId* _idParamAngleY; ///< パラメータID: ParamAngleX
const Csm::CubismId* _idParamAngleZ; ///< パラメータID: ParamAngleX
const Csm::CubismId* _idParamBodyAngleX; ///< パラメータID: ParamBodyAngleX
const Csm::CubismId* _idParamEyeBallX; ///< パラメータID: ParamEyeBallX
const Csm::CubismId* _idParamEyeBallY; ///< パラメータID: ParamEyeBallXY
LAppWavFileHandler _wavFileHandler; ///< wavファイルハンドラ WAV文件处理器
// 低通滤波器参数
Live2D::Cubism::Framework::csmFloat32 alpha = 0.8f; // 滤波系数,范围在0到1之间,值越小,平滑效果越强
Live2D::Cubism::Framework::csmFloat32 filteredValue = 0.0f; // 滤波后的值
Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
};
+100
View File
@@ -0,0 +1,100 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <CubismFramework.hpp>
#include <string>
/**
* @brief プラットフォーム依存機能を抽象化する Cubism Platform Abstraction Layer.
*
* ファイル読み込みや時刻取得等のプラットフォームに依存する関数をまとめる
*
*/
class LAppPal
{
public:
/**
* @brief ファイルをバイトデータとして読み込む
*
* ファイルをバイトデータとして読み込む
*
* @param[in] filePath 読み込み対象ファイルのパス
* @param[out] outSize ファイルサイズ
* @return バイトデータ
*/
static Csm::csmByte* LoadFileAsBytes(const std::string filePath, Csm::csmSizeInt* outSize);
/**
* @brief バイトデータを解放する
*
* バイトデータを解放する
*
* @param[in] byteData 解放したいバイトデータ
*/
static void ReleaseBytes(Csm::csmByte* byteData);
/**
* @biref デルタ時間(前回フレームとの差分)を取得する
*
* @return デルタ時間[ms]
*
*/
static Csm::csmFloat32 GetDeltaTime();
static void UpdateTime();
/**
* @brief ログを出力する
*
* ログを出力する
*
* @param[in] format 書式付文字列
* @param[in] ... (可変長引数)文字列
*
*/
static void PrintLog(const Csm::csmChar* format, ...);
/**
* @brief ログを出力し最後に改行する
*
* ログを出力し最後に改行する
*
* @param[in] format 書式付文字列
* @param[in] ... (可変長引数)文字列
*
*/
static void PrintLogLn(const Csm::csmChar* format, ...);
/**
* @brief メッセージを出力する
*
* メッセージを出力する
*
* @param[in] message 文字列
*
*/
static void PrintMessage(const Csm::csmChar* message);
/**
* @brief メッセージを出力し最後に改行する
*
* メッセージを出力し最後に改行する
*
* @param[in] message 文字列
*
*/
static void PrintMessageLn(const Csm::csmChar* message);
private:
static double s_currentFrame;
static double s_lastFrame;
static double s_deltaTime;
};
+117
View File
@@ -0,0 +1,117 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
/**
* @brief スプライトを実装するクラス。
*
* テクスチャID、Rectの管理。
*
*/
class LAppSprite
{
public:
/**
* @brief Rect 構造体。
*/
struct Rect
{
public:
float left; ///< 左辺
float right; ///< 右辺
float up; ///< 上辺
float down; ///< 下辺
};
/**
* @brief コンストラクタ
*
* @param[in] x x座標
* @param[in] y y座標
* @param[in] width 横幅
* @param[in] height 高さ
* @param[in] textureId テクスチャID
* @param[in] programId シェーダID
*/
LAppSprite(float x, float y, float width, float height, GLuint textureId, GLuint programId);
/**
* @brief デストラクタ
*/
~LAppSprite();
/**
* @brief Getter テクスチャID
* @return テクスチャIDを返す
*/
GLuint GetTextureId() { return _textureId; }
/**
* @brief 描画する
*
*/
void Render() const;
/**
* @brief テクスチャIDを指定して描画する
*
*/
void RenderImmidiate(GLuint textureId, const GLfloat uvVertex[8]) const;
/**
* @brief コンストラクタ
*
* @param[in] pointX x座標
* @param[in] pointY y座標
*/
bool IsHit(float pointX, float pointY) const;
/**
* @brief 色設定
*
* @param[in] r (0.0~1.0)
* @param[in] g (0.0~1.0)
* @param[in] b (0.0~1.0)
* @param[in] a (0.0~1.0)
*/
void SetColor(float r, float g, float b, float a);
/**
* @brief サイズ再設定
*
* @param[in] x x座標
* @param[in] y y座標
* @param[in] width 横幅
* @param[in] height 高さ
*/
void ResetRect(float x, float y, float width, float height);
/**
* @brief ウインドウサイズ設定
*
* @param[in] width 横幅
* @param[in] height 高さ
*/
void SetWindowSize(int width, int height);
private:
GLuint _textureId; ///< テクスチャID
Rect _rect; ///< 矩形
int _positionLocation; ///< 位置アトリビュート
int _uvLocation; ///< UVアトリビュート
int _textureLocation; ///< テクスチャアトリビュート
int _colorLocation; ///< カラーアトリビュート
float _spriteColor[4]; ///< 表示カラー
int _maxWidth; ///< ウインドウ幅
int _maxHeight; ///< ウインドウ高さ
};
@@ -0,0 +1,108 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <string>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <Type/csmVector.hpp>
/**
* @brief テクスチャ管理クラス
*
* 画像読み込み、管理を行うクラス。
*/
class LAppTextureManager
{
public:
/**
* @brief 画像情報構造体
*/
struct TextureInfo
{
GLuint id; ///< テクスチャID
int width; ///< 横幅
int height; ///< 高さ
std::string fileName; ///< ファイル名
};
/**
* @brief コンストラクタ
*/
LAppTextureManager();
/**
* @brief デストラクタ
*
*/
~LAppTextureManager();
/**
* @brief プリマルチプライ処理
*
* @param[in] red 画像のRed値
* @param[in] green 画像のGreen値
* @param[in] blue 画像のBlue値
* @param[in] alpha 画像のAlpha値
*
* @return プリマルチプライ処理後のカラー値
*/
inline unsigned int Premultiply(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
{
return static_cast<unsigned>(\
(red * (alpha + 1) >> 8) | \
((green * (alpha + 1) >> 8) << 8) | \
((blue * (alpha + 1) >> 8) << 16) | \
(((alpha)) << 24) \
);
}
/**
* @brief 画像読み込み
*
* @param[in] fileName 読み込む画像ファイルパス名
* @return 画像情報。読み込み失敗時はNULLを返す
*/
TextureInfo* CreateTextureFromPngFile(std::string fileName);
/**
* @brief 画像の解放
*
* 配列に存在する画像全てを解放する
*/
void ReleaseTextures();
/**
* @brief 画像の解放
*
* 指定したテクスチャIDの画像を解放する
* @param[in] textureId 解放するテクスチャID
**/
void ReleaseTexture(Csm::csmUint32 textureId);
/**
* @brief 画像の解放
*
* 指定した名前の画像を解放する
* @param[in] fileName 解放する画像ファイルパス名
**/
void ReleaseTexture(std::string fileName);
/**
* @brief テクスチャIDからテクスチャ情報を得る
*
* @param textureId[in] 取得したいテクスチャID
* @return テクスチャが存在していればTextureInfoが返る
*/
TextureInfo* GetTextureInfoById(GLuint textureId) const;
private:
Csm::csmVector<TextureInfo*> _textures;
};
+163
View File
@@ -0,0 +1,163 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <Math/CubismMatrix44.hpp>
#include <Math/CubismViewMatrix.hpp>
#include "CubismFramework.hpp"
#include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
class TouchManager;
class LAppSprite;
class LAppModel;
/**
* @brief 描画クラス
*/
class LAppView
{
public:
/**
* @brief LAppModelのレンダリング先
*/
enum SelectTarget
{
SelectTarget_None, ///< デフォルトのフレームバッファにレンダリング
SelectTarget_ModelFrameBuffer, ///< LAppModelが各自持つフレームバッファにレンダリング
SelectTarget_ViewFrameBuffer, ///< LAppViewの持つフレームバッファにレンダリング
};
/**
* @brief コンストラクタ
*/
LAppView();
/**
* @brief デストラクタ
*/
~LAppView();
/**
* @brief 初期化する。
*/
void Initialize();
/**
* @brief 描画する。
*/
void Render();
/**
* @brief 画像の初期化を行う。
*/
void InitializeSprite();
/**
* @brief スプライト系のサイズ再設定
*/
void ResizeSprite();
/**
* @brief タッチされたときに呼ばれる。
*
* @param[in] pointX スクリーンX座標
* @param[in] pointY スクリーンY座標
*/
void OnTouchesBegan(float pointX, float pointY) const;
/**
* @brief タッチしているときにポインタが動いたら呼ばれる。
*
* @param[in] pointX スクリーンX座標
* @param[in] pointY スクリーンY座標
*/
void OnTouchesMoved(float pointX, float pointY) const;
/**
* @brief タッチが終了したら呼ばれる。
*
* @param[in] pointX スクリーンX座標
* @param[in] pointY スクリーンY座標
*/
void OnTouchesEnded(float pointX, float pointY) const;
/**
* @brief X座標をView座標に変換する。
*
* @param[in] deviceX デバイスX座標
*/
float TransformViewX(float deviceX) const;
/**
* @brief Y座標をView座標に変換する。
*
* @param[in] deviceY デバイスY座標
*/
float TransformViewY(float deviceY) const;
/**
* @brief X座標をScreen座標に変換する。
*
* @param[in] deviceX デバイスX座標
*/
float TransformScreenX(float deviceX) const;
/**
* @brief Y座標をScreen座標に変換する。
*
* @param[in] deviceY デバイスY座標
*/
float TransformScreenY(float deviceY) const;
/**
* @brief モデル1体を描画する直前にコールされる
*/
void PreModelDraw(LAppModel& refModel);
/**
* @brief モデル1体を描画した直後にコールされる
*/
void PostModelDraw(LAppModel& refModel);
/**
* @brief 別レンダリングターゲットにモデルを描画するサンプルで
* 描画時のαを決定する
*/
float GetSpriteAlpha(int assign) const;
/**
* @brief レンダリング先を切り替える
*/
void SwitchRenderingTarget(SelectTarget targetType);
/**
* @brief レンダリング先をデフォルト以外に切り替えた際の背景クリア色設定
* @param[in] r 赤(0.0~1.0)
* @param[in] g 緑(0.0~1.0)
* @param[in] b 青(0.0~1.0)
*/
void SetRenderTargetClearColor(float r, float g, float b);
private:
TouchManager* _touchManager; ///< タッチマネージャー
Csm::CubismMatrix44* _deviceToScreen; ///< デバイスからスクリーンへの行列
Csm::CubismViewMatrix* _viewMatrix; ///< viewMatrix
GLuint _programId; ///< シェーダID
//LAppSprite* _back; ///< 背景画像
//LAppSprite* _gear; ///< ギア画像
//LAppSprite* _power; ///< 電源画像
// レンダリング先を別ターゲットにする方式の場合に使用
LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< モードによってはCubismモデル結果をこっちにレンダリング
SelectTarget _renderTarget; ///< レンダリング先の選択肢
float _clearColor[4]; ///< レンダリングターゲットのクリアカラー
};
@@ -0,0 +1,234 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
#include <CubismFramework.hpp>
#include <Type/csmVector.hpp>
/**
* @brief wavファイルハンドラ
* @attention 16bit wav ファイル読み込みのみ実装済み
*/
class LAppWavFileHandler
{
public:
/**
* @brief 読み込んだwavfileの情報
*/
struct WavFileInfo
{
/**
* @brief コンストラクタ
*/
WavFileInfo() : _fileName(""), _numberOfChannels(0),
_bitsPerSample(0), _samplingRate(0), _samplesPerChannel(0),
_avgBytesPerSec(0), _blockAlign(0)
{ }
Csm::csmString _fileName; ///< ファイル名
Csm::csmUint32 _numberOfChannels; ///< チャンネル数
Csm::csmUint32 _bitsPerSample; ///< サンプルあたりビット数
Csm::csmUint32 _samplingRate; ///< サンプリングレート
Csm::csmUint32 _samplesPerChannel; ///< 1チャンネルあたり総サンプル数
Csm::csmUint32 _avgBytesPerSec; ///< 平均データ速度
Csm::csmUint32 _blockAlign; ///< ブロックサイズ
} _wavFileInfo;
/**
* @brief コンストラクタ
*/
LAppWavFileHandler();
/**
* @brief デストラクタ
*/
~LAppWavFileHandler();
/**
* @brief wavファイルハンドラの内部状態更新
*
* @param[in] deltaTimeSeconds デルタ時間[秒]
* @retval true 更新されている
* @retval false 更新されていない
*/
Csm::csmBool Update(Csm::csmFloat32 deltaTimeSeconds);
/**
* @brief 引数で指定したwavファイルの読み込みを開始する
*
* @param[in] filePath wavファイルのパス
*/
void Start(const Csm::csmString& filePath);
/**
* @brief 現在のRMS値取得
*
* @retval csmFloat32 RMS値
*/
Csm::csmFloat32 GetRms() const;
/**
* @brief ファイル情報を取得
*
* @retval ファイル情報
*/
const WavFileInfo& GetWavFileInfo() const;
/**
* @brief 正規化前のデータを取得
*
* @retval 正規化前のデータ
*/
const Csm::csmByte* GetRawData() const;
/**
* @brief 正規化前のデータの大きさを取得
*
* @retval 正規化前のデータの大きさ
*/
Csm::csmUint64 GetRawDataSize() const;
/**
* @brief 正規化データを取得する
*
* @retval 正規化データ
*/
Csm::csmVector<Csm::csmFloat32> GetPcmData() const;
/**
* @brief 引数で指定したチャンネルの正規化データを取得する
*
* @param[in] dst 格納先
* @param[in] useChannel 使用するチャンネル
*/
void GetPcmDataChannel(Csm::csmFloat32* dst, Csm::csmUint32 useChannel) const;
/**
* @brief -11の範囲の1サンプル取得
*
* @param[in] bitsPerSample ビット深度
* @param[in] data 正規化したいデータ
* @param[in] dataSize 正規化したいデータの大きさ
*
* @retval csmFloat32 正規化されたサンプル
*/
static Csm::csmFloat32 NormalizePcmSample(Csm::csmUint32 bitsPerSample, Csm::csmByte* data, Csm::csmUint32 dataSize);
private:
/**
* @brief wavファイルのロード
*
* @param[in] filePath wavファイルのパス
* @retval true 読み込み成功
* @retval false 読み込み失敗
*/
Csm::csmBool LoadWavFile(const Csm::csmString& filePath);
/**
* @brief PCMデータの解放
*/
void ReleasePcmData();
/**
* @brief -11の範囲の1サンプル取得
* @retval csmFloat32 正規化されたサンプル
*/
Csm::csmFloat32 GetPcmSample();
/**
* @brief バイトリーダ
*/
struct ByteReader {
/**
* @brief コンストラクタ
*/
ByteReader() : _fileByte(NULL), _fileSize(0), _readOffset(0)
{ }
/**
* @brief 8ビット読み込み
* @return Csm::csmUint8 読み取った8ビット値
*/
Csm::csmUint8 Get8()
{
const Csm::csmUint8 ret = _fileByte[_readOffset];
_readOffset++;
return ret;
}
/**
* @brief 16ビット読み込み(リトルエンディアン)
* @return Csm::csmUint16 読み取った16ビット値
*/
Csm::csmUint16 Get16LittleEndian()
{
const Csm::csmUint16 ret = (_fileByte[_readOffset + 1] << 8) | _fileByte[_readOffset];
_readOffset += 2;
return ret;
}
/**
* @brief 24ビット読み込み(リトルエンディアン)
* @return Csm::csmUint32 読み取った24ビット値(下位24ビットに設定)
*/
Csm::csmUint32 Get24LittleEndian()
{
const Csm::csmUint32 ret =
(_fileByte[_readOffset + 2] << 16) | (_fileByte[_readOffset + 1] << 8)
| _fileByte[_readOffset];
_readOffset += 3;
return ret;
}
/**
* @brief 32ビット読み込み(リトルエンディアン)
* @return Csm::csmUint32 読み取った32ビット値
*/
Csm::csmUint32 Get32LittleEndian()
{
const Csm::csmUint32 ret =
(_fileByte[_readOffset + 3] << 24) | (_fileByte[_readOffset + 2] << 16)
| (_fileByte[_readOffset + 1] << 8) | _fileByte[_readOffset];
_readOffset += 4;
return ret;
}
/**
* @brief シグネチャの取得と参照文字列との一致チェック
* @param[in] reference 検査対象のシグネチャ文字列
* @retval true 一致している
* @retval false 一致していない
*/
Csm::csmBool GetCheckSignature(const Csm::csmString& reference)
{
Csm::csmChar getSignature[4] = { 0, 0, 0, 0 };
const Csm::csmChar* referenceString = reference.GetRawString();
if (reference.GetLength() != 4)
{
return false;
}
for (Csm::csmUint32 signatureOffset = 0; signatureOffset < 4; signatureOffset++)
{
getSignature[signatureOffset] = static_cast<Csm::csmChar>(Get8());
}
return (getSignature[0] == referenceString[0]) && (getSignature[1] == referenceString[1])
&& (getSignature[2] == referenceString[2]) && (getSignature[3] == referenceString[3]);
}
Csm::csmByte* _fileByte; ///< ロードしたファイルのバイト列
Csm::csmSizeInt _fileSize; ///< ファイルサイズ
Csm::csmUint32 _readOffset; ///< ファイル参照位置
} _byteReader;
Csm::csmByte* _rawData; ///< 正規化される前のバイト列
Csm::csmUint64 _rawDataSize; ///< 正規化される前のバイト列の大きさ
Csm::csmFloat32** _pcmData; ///< -1から1の範囲で表現された音声データ配列
Csm::csmUint32 _sampleOffset; ///< サンプル参照位置
Csm::csmFloat32 _lastRms; ///< 最後に計測したRMS値
Csm::csmFloat32 _userTimeSeconds; ///< デルタ時間の積算値[秒]
};
+104
View File
@@ -0,0 +1,104 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#pragma once
class TouchManager
{
public:
TouchManager();
float GetCenterX() const { return _lastX; }
float GetCenterY() const { return _lastY; }
float GetDeltaX() const { return _deltaX; }
float GetDeltaY() const{ return _deltaY; }
float GetStartX() const{ return _startX; }
float GetStartY() const{ return _startY; }
float GetScale() const { return _scale; }
float GetX() const{ return _lastX; }
float GetY() const{ return _lastY; }
float GetX1() const{ return _lastX1; }
float GetY1() const{ return _lastY1; }
float GetX2() const{ return _lastX2; }
float GetY2() const{ return _lastY2; }
bool IsSingleTouch() const { return _touchSingle; }
bool IsFlickAvailable() const { return _flipAvailable; }
void DisableFlick() { _flipAvailable = false; }
/*
* @brief タッチ開始時イベント
*
* @param[in] deviceY タッチした画面のyの値
* @param[in] deviceX タッチした画面のxの値
*/
void TouchesBegan(float deviceX, float deviceY);
/*
* @brief ドラッグ時のイベント
*
* @param[in] deviceX タッチした画面のyの値
* @param[in] deviceY タッチした画面のxの値
*/
void TouchesMoved(float deviceX, float deviceY);
/*
* @brief ドラッグ時のイベント
*
* @param[in] deviceX1 1つめのタッチした画面のxの値
* @param[in] deviceY1 1つめのタッチした画面のyの値
* @param[in] deviceX2 2つめのタッチした画面のxの値
* @param[in] deviceY2 2つめのタッチした画面のyの値
*/
void TouchesMoved(float deviceX1, float deviceY1, float deviceX2, float deviceY2);
/*
* @brief フリックの距離測定
*
* @return フリック距離
*/
float GetFlickDistance() const;
private:
/*
* @brief 点1から点2への距離を求める
*
* @param[in] x1 1つめのタッチした画面のxの値
* @param[in] y1 1つめのタッチした画面のyの値
* @param[in] x2 2つめのタッチした画面のxの値
* @param[in] y2 2つめのタッチした画面のyの値
* @return 2点の距離
*/
float CalculateDistance(float x1, float y1, float x2, float y2) const;
/*
* 二つの値から、移動量を求める。
* 違う方向の場合は移動量0。同じ方向の場合は、絶対値が小さい方の値を参照する
*
* @param[in] v1 1つめの移動量
* @param[in] v2 2つめの移動量
*
* @return 小さい方の移動量
*/
float CalculateMovingAmount(float v1, float v2);
float _startY; // タッチを開始した時のxの値
float _startX; // タッチを開始した時のyの値
float _lastX; // シングルタッチ時のxの値
float _lastY; // シングルタッチ時のyの値
float _lastX1; // ダブルタッチ時の一つ目のxの値
float _lastY1; // ダブルタッチ時の一つ目のyの値
float _lastX2; // ダブルタッチ時の二つ目のxの値
float _lastY2; // ダブルタッチ時の二つ目のyの値
float _lastTouchDistance; // 2本以上でタッチしたときの指の距離
float _deltaX; // 前回の値から今回の値へのxの移動距離。
float _deltaY; // 前回の値から今回の値へのyの移動距離。
float _scale; // このフレームで掛け合わせる拡大率。拡大操作中以外は1。
bool _touchSingle; // シングルタッチ時はtrue
bool _flipAvailable; // フリップが有効かどうか
};