diff --git a/CHANGELOG.md b/CHANGELOG.md index 5712225..47ed01b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,39 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [5-r.1] - 2024-03-26 + +### Added + +* Add function `ModF()` to compute floating-point remainder in `CubismMath` class. + +### Changed + +* Change the `Reset()` function of `CubismPose` class to public. +* Change some processes in the renderer to be handled as functions. +* Change to output log if the argument `MotionQueueEntry` is `NULL` in the `UpdateFadeWeight()` function of the `ACubismMotion` class. + +### Deprecated + +* Deprecate the `_fadeWeight` variable and the `GetFadeWeight()` function of the `CubismExpressionMotion` class. + * The `_fadeWeight` variable of the `CubismExpressionMotion` class can cause problems. + * Please use the `GetFadeWeight()` function of the `CubismExpressionMotionManager` class with one argument from now on. +* The `StartMotion()` function of the `CubismMotionQueueManager` class with the unnecessary third argument `userTimeSeconds` is deprecated. + * Please use the `StartMotion()` function with two arguments from now on. + +### Fixed + +* Fix a typo in `SetParameterValue()`. +* Fix an issue that the override keyword is not specified for some functions of classes inheriting from `CubismRenderer`. +* Fix operator overloading in the `CubismId` class from being private to public. +* Fix a bug that caused incorrect weight values when expression motions were shared by multiple models. + * Change the way fadeWeight is managed for expression motions. +* Fix shader build error when running nmake in Vulkan. + +### Removed + +* Remove `CubismSetupMaskedShaderUniforms`, `CubismNormalShaderUniforms`, `CubismMaskedShaderUniforms` and `CubismFragMaskedShaderUniforms` from Metal and merged them into `CubismMaskedShaderUniforms`. + ## [5-r.1-beta.4] - 2024-01-25 @@ -338,6 +371,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Fix invalid expressions of `CubismCdiJson`. +[5-r.1]: https://github.com/Live2D/CubismNativeFramework/compare/5-r.1-beta.4...5-r.1 [5-r.1-beta.4]: https://github.com/Live2D/CubismNativeFramework/compare/5-r.1-beta.3...5-r.1-beta.4 [5-r.1-beta.3]: https://github.com/Live2D/CubismNativeFramework/compare/5-r.1-beta.2...5-r.1-beta.3 [5-r.1-beta.2]: https://github.com/Live2D/CubismNativeFramework/compare/5-r.1-beta.1...5-r.1-beta.2 diff --git a/README.ja.md b/README.ja.md index 31953ca..d184b83 100644 --- a/README.ja.md +++ b/README.ja.md @@ -91,7 +91,7 @@ JSON パーサーやログ出力などのユーティリティ機能を提供し ### フォークとプルリクエスト -修正、改善、さらには新機能をもたらすかどうかにかかわらず、プルリクエストに感謝します。ただし、ラッパーは可能な限り軽量で浅くなるように設計されているため、バグ修正とメモリ/パフォーマンスの改善のみを行う必要があることに注意してください。メインリポジトリを可能な限りクリーンに保つために、必要に応じて個人用フォークと機能ブランチを作成してください。 +修正、改善、さらには新機能をもたらすかどうかにかかわらず、プルリクエストに感謝します。メインリポジトリを可能な限りクリーンに保つために、必要に応じて個人用フォークと機能ブランチを作成してください。 ### バグ diff --git a/README.md b/README.md index 36ae1a4..aeafb70 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ There are many ways to contribute to the project: logging bugs, submitting pull ### Forking And Pull Requests -We very much appreciate your pull requests, whether they bring fixes, improvements, or even new features. Note, however, that the wrapper is designed to be as lightweight and shallow as possible and should therefore only be subject to bug fixes and memory/performance improvements. To keep the main repository as clean as possible, create a personal fork and feature branches there as needed. +We very much appreciate your pull requests, whether they bring fixes, improvements, or even new features. To keep the main repository as clean as possible, create a personal fork and feature branches there as needed. ### Bugs diff --git a/src/Effect/CubismPose.hpp b/src/Effect/CubismPose.hpp index 71d5c9a..3df93fa 100644 --- a/src/Effect/CubismPose.hpp +++ b/src/Effect/CubismPose.hpp @@ -99,6 +99,17 @@ class CubismPose */ void UpdateParameters(CubismModel* model, csmFloat32 deltaTimeSeconds); + /** + * @brief 表示を初期化 + * + * 表示を初期化する。 + * + * @param[in] model 対象のモデル + * + * @note 不透明度の初期値が0でないパラメータは、不透明度を1に設定する。 + */ + void Reset(CubismModel* model); + private: /** * @brief コンストラクタ @@ -114,17 +125,6 @@ class CubismPose */ virtual ~CubismPose(); - /** - * @brief 表示を初期化 - * - * 表示を初期化する。 - * - * @param[in] model 対象のモデル - * - * @note 不透明度の初期値が0でないパラメータは、不透明度を1に設定する。 - */ - void Reset(CubismModel* model); - /** * @brief パーツの不透明度をコピー * diff --git a/src/Id/CubismId.hpp b/src/Id/CubismId.hpp index ca406f3..b16acd3 100644 --- a/src/Id/CubismId.hpp +++ b/src/Id/CubismId.hpp @@ -29,6 +29,11 @@ struct CubismId */ const csmString& GetString() const; + CubismId& operator=(const CubismId& c); + + csmBool operator==(const CubismId& c) const; + csmBool operator!=(const CubismId& c) const; + private: /** * @brief コンストラクタ @@ -54,10 +59,6 @@ struct CubismId ~CubismId(); CubismId(const CubismId& c); - CubismId& operator=(const CubismId& c); - - csmBool operator==(const CubismId& c) const; - csmBool operator!=(const CubismId& c) const; csmString _id; ///< ID名 }; diff --git a/src/Math/CubismMath.cpp b/src/Math/CubismMath.cpp index 1a59dde..31d31a6 100644 --- a/src/Math/CubismMath.cpp +++ b/src/Math/CubismMath.cpp @@ -6,6 +6,7 @@ */ #include "CubismMath.hpp" +#include "Utils/CubismDebug.hpp" namespace Live2D {namespace Cubism {namespace Framework { @@ -189,4 +190,27 @@ csmFloat32 CubismMath::CardanoAlgorithmForBezier(csmFloat32 a, csmFloat32 b, csm return RangeF(root1, 0.0f, 1.0f); } +csmFloat32 CubismMath::ModF(csmFloat32 dividend, csmFloat32 divisor) +{ + if ( + !isfinite(dividend) || + divisor == 0 || + isnan(dividend) || + isnan(divisor) + ) { + CubismLogWarning("dividend: %f, divisor: %f ModF() returns 'NaN'.", dividend, divisor); + return NAN; + } + + // 絶対値に変換する。 + const csmFloat32 absDividend = CubismMath::AbsF(dividend); + const csmFloat32 absDivisor = CubismMath::AbsF(divisor); + + // 絶対値で割り算する。 + csmFloat32 result = absDividend - floorf(absDividend / absDivisor) * absDivisor; + + // 符号を被除数のものに指定する。 + return copysign(result, dividend); +} + }}} diff --git a/src/Math/CubismMath.hpp b/src/Math/CubismMath.hpp index 8ab3dba..a04ebf9 100644 --- a/src/Math/CubismMath.hpp +++ b/src/Math/CubismMath.hpp @@ -209,6 +209,15 @@ class CubismMath */ static csmFloat32 CardanoAlgorithmForBezier(csmFloat32 a, csmFloat32 b, csmFloat32 c, csmFloat32 d); + /** + * @brief 浮動小数点の余りを求める。 + * + * @param dividend 被除数(割られる値) + * @param divisor 除数(割る値) + * @returns 余り + */ + static csmFloat32 ModF(csmFloat32 dividend, csmFloat32 divisor); + private: /** *@brief privateコンストラクタ diff --git a/src/Model/CubismModel.cpp b/src/Model/CubismModel.cpp index 5f36526..5cca76e 100644 --- a/src/Model/CubismModel.cpp +++ b/src/Model/CubismModel.cpp @@ -41,9 +41,9 @@ csmFloat32 CubismModel::GetParameterValue(CubismIdHandle parameterId) return GetParameterValue(parameterIndex); } -void CubismModel::SetParameterValue(CubismIdHandle parameteId, csmFloat32 value, csmFloat32 weight) +void CubismModel::SetParameterValue(CubismIdHandle parameterId, csmFloat32 value, csmFloat32 weight) { - const csmInt32 index = GetParameterIndex(parameteId); + const csmInt32 index = GetParameterIndex(parameterId); SetParameterValue(index, value, weight); } diff --git a/src/Motion/ACubismMotion.cpp b/src/Motion/ACubismMotion.cpp index 7fae366..4668446 100644 --- a/src/Motion/ACubismMotion.cpp +++ b/src/Motion/ACubismMotion.cpp @@ -39,21 +39,7 @@ void ACubismMotion::UpdateParameters(CubismModel* model, CubismMotionQueueEntry* return; } - if (!motionQueueEntry->IsStarted()) - { - motionQueueEntry->IsStarted(true); - motionQueueEntry->SetStartTime(userTimeSeconds - _offsetSeconds); //モーションの開始時刻を記録 - motionQueueEntry->SetFadeInStartTime(userTimeSeconds); //フェードインの開始時刻 - - const csmFloat32 duration = GetDuration(); - - if (motionQueueEntry->GetEndTime() < 0) - { - //開始していないうちに終了設定している場合がある。 - motionQueueEntry->SetEndTime( (duration <= 0) ? -1 : motionQueueEntry->GetStartTime() + duration ); - //duration == -1 の場合はループする - } - } + SetupMotionQueueEntry(motionQueueEntry, userTimeSeconds); csmFloat32 fadeWeight = UpdateFadeWeight(motionQueueEntry, userTimeSeconds); @@ -68,8 +54,37 @@ void ACubismMotion::UpdateParameters(CubismModel* model, CubismMotionQueueEntry* } } +void ACubismMotion::SetupMotionQueueEntry(CubismMotionQueueEntry* motionQueueEntry, csmFloat32 userTimeSeconds) +{ + if (!motionQueueEntry->IsAvailable() || motionQueueEntry->IsFinished()) { + return; + } + + if (motionQueueEntry->IsStarted()) { + return; + } + + motionQueueEntry->IsStarted(true); + motionQueueEntry->SetStartTime(userTimeSeconds - _offsetSeconds); //モーションの開始時刻を記録 + motionQueueEntry->SetFadeInStartTime(userTimeSeconds); //フェードインの開始時刻 + + const csmFloat32 duration = GetDuration(); + + if (motionQueueEntry->GetEndTime() < 0) + { + //開始していないうちに終了設定している場合がある。 + motionQueueEntry->SetEndTime((duration <= 0) ? -1 : motionQueueEntry->GetStartTime() + duration); + //duration == -1 の場合はループする + } +} + csmFloat32 ACubismMotion::UpdateFadeWeight(CubismMotionQueueEntry* motionQueueEntry, csmFloat32 userTimeSeconds) { + if (motionQueueEntry == NULL) + { + CubismLogError("motionQueueEntry is null."); + } + csmFloat32 fadeWeight = _weight; //現在の値と掛け合わせる割合 //---- フェードイン・アウトの処理 ---- diff --git a/src/Motion/ACubismMotion.hpp b/src/Motion/ACubismMotion.hpp index 3a2c0c6..fea58e7 100644 --- a/src/Motion/ACubismMotion.hpp +++ b/src/Motion/ACubismMotion.hpp @@ -54,6 +54,14 @@ class ACubismMotion */ void UpdateParameters(CubismModel* model, CubismMotionQueueEntry* motionQueueEntry, csmFloat32 userTimeSeconds); + /** + * モーションの再生を開始するためのセットアップを行う。 + * + * @param motionQueueEntry CubismMotionQueueManagerによって管理されるモーション + * @param userTimeSeconds 総再生時間(秒) + */ + void SetupMotionQueueEntry(CubismMotionQueueEntry* motionQueueEntry, csmFloat32 userTimeSeconds); + /** * @brief フェードイン * @@ -235,19 +243,6 @@ class ACubismMotion */ virtual CubismIdHandle GetModelOpacityId(csmInt32 index); -protected: - /** - * - * @brief 指定時間の透明度の値を返す - * - * @param[in] motionTimeSeconds 現在の再生時間[秒] - * - * @return success:モーションの当該時間におけるOpacityの値 - * - * @note 更新後の値を取るにはUpdateParameters() の後に呼び出す。 - */ - virtual csmFloat32 GetModelOpacityValue() const; - /** * @brief モデルのウェイト更新 * @@ -271,6 +266,18 @@ class ACubismMotion */ virtual ~ACubismMotion(); + /** + * + * @brief 指定時間の透明度の値を返す + * + * @param[in] motionTimeSeconds 現在の再生時間[秒] + * + * @return success:モーションの当該時間におけるOpacityの値 + * + * @note 更新後の値を取るにはUpdateParameters() の後に呼び出す。 + */ + virtual csmFloat32 GetModelOpacityValue() const; + /** * @brief モデルのパラメータの更新の実行 * diff --git a/src/Motion/CubismExpressionMotion.cpp b/src/Motion/CubismExpressionMotion.cpp index 38aa758..081bf48 100644 --- a/src/Motion/CubismExpressionMotion.cpp +++ b/src/Motion/CubismExpressionMotion.cpp @@ -31,7 +31,6 @@ const csmFloat32 DefaultFadeTime = 1.0f; CubismExpressionMotion::CubismExpressionMotion() - : _fadeWeight(0.0f) { } CubismExpressionMotion::~CubismExpressionMotion() @@ -72,29 +71,20 @@ void CubismExpressionMotion::DoUpdateParameters(CubismModel* model, csmFloat32 u } void CubismExpressionMotion::CalculateExpressionParameters(CubismModel* model, csmFloat32 userTimeSeconds, CubismMotionQueueEntry* motionQueueEntry, - csmVector* expressionParameterValues, csmInt32 expressionIndex) + csmVector* expressionParameterValues, csmInt32 expressionIndex, csmFloat32 fadeWeight) { - if (!motionQueueEntry->IsAvailable() || motionQueueEntry->IsFinished()) + if (motionQueueEntry == NULL || expressionParameterValues == NULL) { return; } - if (!motionQueueEntry->IsStarted()) + if (!motionQueueEntry->IsAvailable()) { - motionQueueEntry->IsStarted(true); - motionQueueEntry->SetStartTime(userTimeSeconds - _offsetSeconds); //モーションの開始時刻を記録 - motionQueueEntry->SetFadeInStartTime(userTimeSeconds); //フェードインの開始時刻 - - const csmFloat32 duration = GetDuration(); - - if (motionQueueEntry->GetEndTime() < 0.0f) - { - //開始していないうちに終了設定している場合がある。 - motionQueueEntry->SetEndTime((duration <= 0.0f) ? -1 : motionQueueEntry->GetStartTime() + duration); - //duration == -1 の場合はループする - } + return; } + // CubismExpressionMotion._fadeWeight は廃止予定です。 + // 互換性のために処理は残りますが、実際には使用しておりません。 _fadeWeight = UpdateFadeWeight(motionQueueEntry, userTimeSeconds); // モデルに適用する値を計算 @@ -138,13 +128,13 @@ void CubismExpressionMotion::CalculateExpressionParameters(CubismModel* model, c else { expressionParameterValues->At(i).AdditiveValue = - CalculateValue(expressionParameterValue.AdditiveValue, DefaultAdditiveValue); + CalculateValue(expressionParameterValue.AdditiveValue, DefaultAdditiveValue, fadeWeight); expressionParameterValues->At(i).MultiplyValue = - CalculateValue(expressionParameterValue.MultiplyValue, DefaultMultiplyValue); + CalculateValue(expressionParameterValue.MultiplyValue, DefaultMultiplyValue, fadeWeight); expressionParameterValues->At(i).OverwriteValue = - CalculateValue(expressionParameterValue.OverwriteValue, currentParameterValue); + CalculateValue(expressionParameterValue.OverwriteValue, currentParameterValue, fadeWeight); } continue; } @@ -178,9 +168,9 @@ void CubismExpressionMotion::CalculateExpressionParameters(CubismModel* model, c expressionParameterValues->At(i).OverwriteValue = newSetValue; } else { - expressionParameterValues->At(i).AdditiveValue = (expressionParameterValue.AdditiveValue * (1.0f - _fadeWeight)) + newAdditiveValue * _fadeWeight; - expressionParameterValues->At(i).MultiplyValue = (expressionParameterValue.MultiplyValue * (1.0f - _fadeWeight)) + newMultiplyValue * _fadeWeight; - expressionParameterValues->At(i).OverwriteValue = (expressionParameterValue.OverwriteValue * (1.0f - _fadeWeight)) + newSetValue * _fadeWeight; + expressionParameterValues->At(i).AdditiveValue = (expressionParameterValue.AdditiveValue * (1.0f - fadeWeight)) + newAdditiveValue * fadeWeight; + expressionParameterValues->At(i).MultiplyValue = (expressionParameterValue.MultiplyValue * (1.0f - fadeWeight)) + newMultiplyValue * fadeWeight; + expressionParameterValues->At(i).OverwriteValue = (expressionParameterValue.OverwriteValue * (1.0f - fadeWeight)) + newSetValue * fadeWeight; } } } @@ -192,6 +182,10 @@ csmVector CubismExpressionMotion::G csmFloat32 CubismExpressionMotion::GetFadeWeight() { +#if _DEBUG + CubismLogWarning("GetFadeWeight() is a deprecated function. Please use CubismExpressionMotionManager.GetFadeWeight(int index)."); +#endif // _DEBUG + return _fadeWeight; } @@ -252,9 +246,9 @@ void CubismExpressionMotion::Parse(const csmByte* buffer, csmSizeInt size) Utils::CubismJson::Delete(json);// JSONデータは不要になったら削除する } -csmFloat32 CubismExpressionMotion::CalculateValue(csmFloat32 source, csmFloat32 destination) +csmFloat32 CubismExpressionMotion::CalculateValue(csmFloat32 source, csmFloat32 destination, csmFloat32 fadeWeight) { - return (source * (1.0f - _fadeWeight)) + (destination * _fadeWeight); + return (source * (1.0f - fadeWeight)) + (destination * fadeWeight); } diff --git a/src/Motion/CubismExpressionMotion.hpp b/src/Motion/CubismExpressionMotion.hpp index 6f7e459..b877981 100644 --- a/src/Motion/CubismExpressionMotion.hpp +++ b/src/Motion/CubismExpressionMotion.hpp @@ -80,7 +80,7 @@ class CubismExpressionMotion : public ACubismMotion * @param[in] expressionIndex 表情のインデックス */ void CalculateExpressionParameters(CubismModel* model, csmFloat32 userTimeSeconds, CubismMotionQueueEntry* motionQueueEntry, - csmVector* expressionParameterValues, csmInt32 expressionIndex); + csmVector* expressionParameterValues, csmInt32 expressionIndex, csmFloat32 fadeWeight); /** * @brief 表情が参照しているパラメータを取得 @@ -93,6 +93,13 @@ class CubismExpressionMotion : public ACubismMotion * @brief 表情のフェードの値を取得 * * 現在の表情のフェードのウェイト値を取得する。 + * + * @return 表情のフェードのウェイト値 + * + * @deprecated CubismExpressionMotion._fadeWeightが削除予定のため非推奨 + * CubismExpressionMotionManager.getFadeWeight(int index) を使用してください。 + * + * @see CubismExpressionMotionManager#GetFadeWeight(int index) */ csmFloat32 GetFadeWeight(); @@ -136,9 +143,15 @@ class CubismExpressionMotion : public ACubismMotion * @param[in] source 現在の値 * @param[in] destination 適用する値 */ - csmFloat32 CalculateValue(csmFloat32 source, csmFloat32 destination); + csmFloat32 CalculateValue(csmFloat32 source, csmFloat32 destination, csmFloat32 fadeWeight); + - csmFloat32 _fadeWeight; ///< 表情の現在のウェイト + /** + * 表情の現在のウェイト + * + * @deprecated 不具合を引き起こす要因となるため非推奨。 + */ + csmFloat32 _fadeWeight; }; }}} diff --git a/src/Motion/CubismExpressionMotionManager.cpp b/src/Motion/CubismExpressionMotionManager.cpp index ee85fc9..d0d5616 100644 --- a/src/Motion/CubismExpressionMotionManager.cpp +++ b/src/Motion/CubismExpressionMotionManager.cpp @@ -27,6 +27,8 @@ CubismExpressionMotionManager::~CubismExpressionMotionManager() _expressionParameterValues = NULL; } + + _fadeWeights.Clear(); } csmInt32 CubismExpressionMotionManager::GetCurrentPriority() const @@ -52,7 +54,9 @@ CubismMotionQueueEntryHandle CubismExpressionMotionManager::StartMotionPriority( } _currentPriority = priority; // 再生中モーションの優先度を設定 - return CubismMotionQueueManager::StartMotion(motion, autoDelete, _userTimeSeconds); + _fadeWeights.PushBack(0.0f); + + return CubismMotionQueueManager::StartMotion(motion, autoDelete); } csmBool CubismExpressionMotionManager::UpdateMotion(CubismModel* model, csmFloat32 deltaTimeSeconds) @@ -125,8 +129,10 @@ csmBool CubismExpressionMotionManager::UpdateMotion(CubismModel* model, csmFloat } // ------ 値を計算する ------ + expressionMotion->SetupMotionQueueEntry(motionQueueEntry, _userTimeSeconds); + _fadeWeights[expressionIndex] = expressionMotion->UpdateFadeWeight(motionQueueEntry, _userTimeSeconds); expressionMotion->CalculateExpressionParameters(model, _userTimeSeconds, motionQueueEntry, - _expressionParameterValues, expressionIndex); + _expressionParameterValues, expressionIndex, _fadeWeights[expressionIndex]); expressionWeight += expressionMotion->GetFadeInTime() == 0.0f ? 1.0f @@ -149,7 +155,9 @@ csmBool CubismExpressionMotionManager::UpdateMotion(CubismModel* model, csmFloat { CubismExpressionMotion* expressionMotion = (CubismExpressionMotion*)(motions->At(motions->GetSize() - 1))->GetCubismMotion(); - if (expressionMotion->GetFadeWeight() >= 1.0f) + + csmFloat32 latestFadeWeight = _fadeWeights[_fadeWeights.GetSize() - 1]; + if (latestFadeWeight >= 1.0f) { // 配列の最後の要素は削除しない for (csmInt32 i = motions->GetSize()-2; i >= 0; i--) @@ -157,6 +165,7 @@ csmBool CubismExpressionMotionManager::UpdateMotion(CubismModel* model, csmFloat CubismMotionQueueEntry* motionQueueEntry = motions->At(i); CSM_DELETE(motionQueueEntry); motions->Remove(i); + _fadeWeights.Remove(i); } } } @@ -180,4 +189,9 @@ csmBool CubismExpressionMotionManager::UpdateMotion(CubismModel* model, csmFloat return updated; } +csmFloat32 CubismExpressionMotionManager::GetFadeWeight(csmInt32 index) +{ + return _fadeWeights[index]; +} + }}} diff --git a/src/Motion/CubismExpressionMotionManager.hpp b/src/Motion/CubismExpressionMotionManager.hpp index de6dfd8..209d66f 100644 --- a/src/Motion/CubismExpressionMotionManager.hpp +++ b/src/Motion/CubismExpressionMotionManager.hpp @@ -97,11 +97,23 @@ class CubismExpressionMotionManager : public CubismMotionQueueManager */ csmBool UpdateMotion(CubismModel* model, csmFloat32 deltaTimeSeconds); + /** + * 現在の表情のフェードのウェイト値を取得する。 + * + * @param index 取得する表情モーションのインデックス + * + * @return 表情のフェードのウェイト値 + */ + csmFloat32 GetFadeWeight(csmInt32 index); + private: // モデルに適用する各パラメータの値 csmVector* _expressionParameterValues; + // 再生中の表情のウェイト + csmVector _fadeWeights; + csmInt32 _currentPriority; ///< 現在再生中のモーションの優先度 csmInt32 _reservePriority; ///< 再生予定のモーションの優先度。再生中は0になる。モーションファイルを別スレッドで読み込むときの機能。 }; diff --git a/src/Motion/CubismMotionManager.cpp b/src/Motion/CubismMotionManager.cpp index 0fabbfb..983dc2c 100644 --- a/src/Motion/CubismMotionManager.cpp +++ b/src/Motion/CubismMotionManager.cpp @@ -41,7 +41,7 @@ CubismMotionQueueEntryHandle CubismMotionManager::StartMotionPriority(ACubismMot _currentPriority = priority; // 再生中モーションの優先度を設定 - return CubismMotionQueueManager::StartMotion(motion, autoDelete, _userTimeSeconds); + return CubismMotionQueueManager::StartMotion(motion, autoDelete); } csmBool CubismMotionManager::UpdateMotion(CubismModel* model, csmFloat32 deltaTimeSeconds) diff --git a/src/Motion/CubismMotionQueueManager.cpp b/src/Motion/CubismMotionQueueManager.cpp index 780dc2f..3db6cf0 100644 --- a/src/Motion/CubismMotionQueueManager.cpp +++ b/src/Motion/CubismMotionQueueManager.cpp @@ -31,8 +31,42 @@ CubismMotionQueueManager::~CubismMotionQueueManager() } } +CubismMotionQueueEntryHandle CubismMotionQueueManager::StartMotion(ACubismMotion* motion, csmBool autoDelete) +{ + if (motion == NULL) + { + return InvalidMotionQueueEntryHandleValue; + } + + CubismMotionQueueEntry* motionQueueEntry = NULL; + + // 既にモーションがあれば終了フラグを立てる + for (csmUint32 i = 0; i < _motions.GetSize(); ++i) + { + motionQueueEntry = _motions.At(i); + if (motionQueueEntry == NULL) + { + continue; + } + + motionQueueEntry->SetFadeout(motionQueueEntry->_motion->GetFadeOutTime()); + } + + motionQueueEntry = CSM_NEW CubismMotionQueueEntry(); // 終了時に破棄する + motionQueueEntry->_autoDelete = autoDelete; + motionQueueEntry->_motion = motion; + + _motions.PushBack(motionQueueEntry, false); + + return motionQueueEntry->_motionQueueEntryHandle; +} + CubismMotionQueueEntryHandle CubismMotionQueueManager::StartMotion(ACubismMotion* motion, csmBool autoDelete, csmFloat32 userTimeSeconds) { +#if _DEBUG + CubismLogWarning("StartMotion(ACubismMotion* motion, csmBool autoDelete, csmFloat32 userTimeSeconds) is a deprecated function. Please use StartMotion(ACubismMotion* motion, csmBool autoDelete)."); +#endif + if (motion == NULL) { return InvalidMotionQueueEntryHandleValue; diff --git a/src/Motion/CubismMotionQueueManager.hpp b/src/Motion/CubismMotionQueueManager.hpp index 588ced9..bcd65a5 100644 --- a/src/Motion/CubismMotionQueueManager.hpp +++ b/src/Motion/CubismMotionQueueManager.hpp @@ -63,6 +63,18 @@ class CubismMotionQueueManager virtual ~CubismMotionQueueManager(); /** + * @brief 指定したモーションの開始 + * + * 指定したモーションを開始する。同じタイプのモーションが既にある場合は、既存のモーションに終了フラグを立て、フェードアウトを開始させる。 + * + * @param[in] motion 開始するモーション + * @param[in] autoDelete 再生が終了したモーションのインスタンスを削除するなら true + * @return 開始したモーションの識別番号を返す。個別のモーションが終了したか否かを判定するIsFinished()の引数で使用する。開始できない時は「-1」 + */ + CubismMotionQueueEntryHandle StartMotion(ACubismMotion* motion, csmBool autoDelete); + + /** + * @deprecated 第3引数userTimeSecondsを関数内で使用していないため非推奨。StartMotion(ACubismMotion* motion, csmBool autoDelete)を使用してください。 * @brief 指定したモーションの開始 * * 指定したモーションを開始する。同じタイプのモーションが既にある場合は、既存のモーションに終了フラグを立て、フェードアウトを開始させる。 diff --git a/src/Rendering/Cocos2d/CubismRenderer_Cocos2dx.hpp b/src/Rendering/Cocos2d/CubismRenderer_Cocos2dx.hpp index 4f07d8e..0e50156 100644 --- a/src/Rendering/Cocos2d/CubismRenderer_Cocos2dx.hpp +++ b/src/Rendering/Cocos2d/CubismRenderer_Cocos2dx.hpp @@ -162,9 +162,9 @@ class CubismRenderer_Cocos2dx : public CubismRenderer * * @param[in] model -> モデルのインスタンス */ - void Initialize(Framework::CubismModel* model); + void Initialize(Framework::CubismModel* model) override; - void Initialize(Framework::CubismModel* model, csmInt32 maskBufferCount); + void Initialize(Framework::CubismModel* model, csmInt32 maskBufferCount) override; /** * @brief OpenGLテクスチャのバインド処理
@@ -238,7 +238,7 @@ class CubismRenderer_Cocos2dx : public CubismRenderer * @brief モデルを描画する実際の処理 * */ - void DoDrawModel(); + void DoDrawModel() override; /** * @brief 描画オブジェクト(アートメッシュ)を描画する。
@@ -296,12 +296,12 @@ class CubismRenderer_Cocos2dx : public CubismRenderer /** * @brief モデル描画直前のCocos2dxのステートを保持する */ - virtual void SaveProfile(); + void SaveProfile() override; /** * @brief モデル描画直前のCocos2dxのステートを保持する */ - virtual void RestoreProfile(); + void RestoreProfile() override; /** * @brief マスクテクスチャに描画するクリッピングコンテキストをセットする。 diff --git a/src/Rendering/Cocos2d/CubismShader_Cocos2dx.cpp b/src/Rendering/Cocos2d/CubismShader_Cocos2dx.cpp index 9cb4141..e7fe15e 100644 --- a/src/Rendering/Cocos2d/CubismShader_Cocos2dx.cpp +++ b/src/Rendering/Cocos2d/CubismShader_Cocos2dx.cpp @@ -770,62 +770,42 @@ void CubismShader_Cocos2dx::SetupShaderProgramForMask(CubismCommandBuffer_Cocos2 GenerateShaders(); } + CubismShaderSet* shaderSet = _shaderSets[ShaderNames_SetupMask]; + cocos2d::backend::BlendDescriptor* blendDescriptor = drawCommand->GetBlendDescriptor(); - cocos2d::PipelineDescriptor* pipelineDescriptor = drawCommand->GetPipelineDescriptor(); + blendDescriptor->sourceRGBBlendFactor = cocos2d::backend::BlendFactor::ZERO; + blendDescriptor->destinationRGBBlendFactor = cocos2d::backend::BlendFactor::ONE_MINUS_SRC_COLOR; + blendDescriptor->sourceAlphaBlendFactor = cocos2d::backend::BlendFactor::ZERO; + blendDescriptor->destinationAlphaBlendFactor = cocos2d::backend::BlendFactor::ONE_MINUS_SRC_ALPHA; + cocos2d::PipelineDescriptor* pipelineDescriptor = drawCommand->GetPipelineDescriptor(); cocos2d::backend::ProgramState* programState = pipelineDescriptor->programState; - - CubismShaderSet* shaderSet = _shaderSets[ShaderNames_SetupMask]; - if (!programState) { programState = new cocos2d::backend::ProgramState(shaderSet->ShaderProgram); } - //テクスチャ設定 - const csmInt32 textureIndex = model.GetDrawableTextureIndex(index); - cocos2d::Texture2D* texture = renderer->GetBindedTexture(textureIndex); - programState->setTexture(shaderSet->SamplerTexture0Location, 0, texture->getBackendTexture()); + SetupTexture(renderer, programState, model, index, shaderSet); - // 頂点配列の設定 - programState->getVertexLayout()->setAttribute("a_position", shaderSet->AttributePositionLocation, cocos2d::backend::VertexFormat::FLOAT2, 0, false); - // テクスチャ頂点の設定 - programState->getVertexLayout()->setAttribute("a_texCoord", shaderSet->AttributeTexCoordLocation, cocos2d::backend::VertexFormat::FLOAT2, sizeof(csmFloat32) * 2, false); + // 頂点属性の設定 + SetVertexAttributes(programState, shaderSet); - // チャンネル - const csmInt32 channelIndex = renderer->GetClippingContextBufferForMask()->_layoutChannelIndex; - CubismRenderer::CubismTextureColor* colorChannel = renderer->GetClippingContextBufferForMask()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - csmFloat32 colorFlag[4] = { colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A }; - programState->setUniform(shaderSet->UnifromChannelFlagLocation, colorFlag, sizeof(float) * 4); + // カラーチャンネル + CubismClippingContext_Cocos2dx* contextBuffer = renderer->GetClippingContextBufferForMask(); + SetColorChannel(renderer, programState, shaderSet, contextBuffer); //マスク用行列 programState->setUniform(shaderSet->UniformClipMatrixLocation, renderer->GetClippingContextBufferForMask()->_matrixForMask.GetArray(), sizeof(float) * 16); - //マスク描画範囲 + // ユニフォーム変数設定 csmRectF* rect = renderer->GetClippingContextBufferForMask()->_layoutBounds; - csmFloat32 base[4] = { rect->X * 2.0f - 1.0f, - rect->Y * 2.0f - 1.0f, - rect->GetRight() * 2.0f - 1.0f, - rect->GetBottom() * 2.0f - 1.0f }; - programState->setUniform(shaderSet->UniformBaseColorLocation, base, sizeof(float) * 4); - - //乗算色 - const CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); - csmFloat32 multiply[4] = { multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A }; - programState->setUniform(shaderSet->UniformMultiplyColorLocation, multiply, sizeof(float) * 4); - - //スクリーン色 - const CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); - csmFloat32 screen[4] = { screenColor.R, screenColor.G, screenColor.B, screenColor.A }; - programState->setUniform(shaderSet->UniformScreenColorLocation, screen, sizeof(float) * 4); - - blendDescriptor->sourceRGBBlendFactor = cocos2d::backend::BlendFactor::ZERO; - blendDescriptor->destinationRGBBlendFactor = cocos2d::backend::BlendFactor::ONE_MINUS_SRC_COLOR; - blendDescriptor->sourceAlphaBlendFactor = cocos2d::backend::BlendFactor::ZERO; - blendDescriptor->destinationAlphaBlendFactor = cocos2d::backend::BlendFactor::ONE_MINUS_SRC_ALPHA; + CubismRenderer::CubismTextureColor baseColor = {rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, rect->GetBottom() * 2.0f - 1.0f}; + CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); + SetColorUniformVariables(programState, shaderSet, baseColor, multiplyColor, screenColor); programState->getVertexLayout()->setLayout(sizeof(csmFloat32) * 4); blendDescriptor->blendEnabled = true; @@ -883,10 +863,11 @@ void CubismShader_Cocos2dx::SetupShaderProgramForDraw(CubismCommandBuffer_Cocos2 programState = new cocos2d::backend::ProgramState(shaderSet->ShaderProgram); } - // 頂点配列の設定 - programState->getVertexLayout()->setAttribute("a_position", shaderSet->AttributePositionLocation, cocos2d::backend::VertexFormat::FLOAT2, 0, false); - // テクスチャ頂点の設定 - programState->getVertexLayout()->setAttribute("a_texCoord", shaderSet->AttributeTexCoordLocation, cocos2d::backend::VertexFormat::FLOAT2, sizeof(csmFloat32) * 2, false); + //テクスチャ設定 + SetupTexture(renderer, programState, model, index, shaderSet); + + // 頂点属性の設定 + SetVertexAttributes(programState, shaderSet); if (masked) { @@ -900,36 +881,20 @@ void CubismShader_Cocos2dx::SetupShaderProgramForDraw(CubismCommandBuffer_Cocos2 renderer->GetClippingContextBufferForDraw()->_matrixForDraw.GetArray(), sizeof(float) * 16); - // 使用するカラーチャンネルを設定 - const csmInt32 channelIndex = renderer->GetClippingContextBufferForDraw()->_layoutChannelIndex; - CubismRenderer::CubismTextureColor* colorChannel = renderer->GetClippingContextBufferForDraw()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - csmFloat32 colorFlag[4] = { colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A }; - programState->setUniform(shaderSet->UnifromChannelFlagLocation, colorFlag, sizeof(float) * 4); + // カラーチャンネル + CubismClippingContext_Cocos2dx* contextBuffer = renderer->GetClippingContextBufferForDraw(); + SetColorChannel(renderer, programState, shaderSet, contextBuffer); } - //テクスチャ設定 - const csmInt32 textureIndex = model.GetDrawableTextureIndex(index); - cocos2d::Texture2D* texture = renderer->GetBindedTexture(textureIndex); - programState->setTexture(shaderSet->SamplerTexture0Location, 0, texture->getBackendTexture()); - //座標変換 CubismMatrix44 matrix4x4 = renderer->GetMvpMatrix(); programState->setUniform(shaderSet->UniformMatrixLocation, matrix4x4.GetArray(), sizeof(float) * 16); - //ベース色 + // ユニフォーム変数設定 CubismRenderer::CubismTextureColor baseColor = renderer->GetModelColorWithOpacity(model.GetDrawableOpacity(index)); - csmFloat32 base[4] = { baseColor.R, baseColor.G, baseColor.B, baseColor.A }; - programState->setUniform(shaderSet->UniformBaseColorLocation, base, sizeof(float) * 4); - - //乗算色 - const CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); - csmFloat32 multiply[4] = { multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A }; - programState->setUniform(shaderSet->UniformMultiplyColorLocation, multiply, sizeof(float) * 4); - - //スクリーン色 - const CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); - csmFloat32 screen[4] = { screenColor.R, screenColor.G, screenColor.B, screenColor.A }; - programState->setUniform(shaderSet->UniformScreenColorLocation, screen, sizeof(float) * 4); + CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); + SetColorUniformVariables(programState, shaderSet, baseColor, multiplyColor, screenColor); programState->getVertexLayout()->setLayout(sizeof(csmFloat32) * 4); blendDescriptor->blendEnabled = true; @@ -943,5 +908,42 @@ cocos2d::backend::Program* CubismShader_Cocos2dx::LoadShaderProgram(const csmCha return cocos2d::backend::Device::getInstance()->newProgram(vertShaderSrc, fragShaderSrc); } +void CubismShader_Cocos2dx::SetVertexAttributes(cocos2d::backend::ProgramState* programState, CubismShaderSet* shaderSet) +{ + // 頂点配列の設定 + programState->getVertexLayout()->setAttribute("a_position", shaderSet->AttributePositionLocation, cocos2d::backend::VertexFormat::FLOAT2, 0, false); + // テクスチャ頂点の設定 + programState->getVertexLayout()->setAttribute("a_texCoord", shaderSet->AttributeTexCoordLocation, cocos2d::backend::VertexFormat::FLOAT2, sizeof(csmFloat32) * 2, false); +} + +void CubismShader_Cocos2dx::SetupTexture(CubismRenderer_Cocos2dx* renderer, cocos2d::backend::ProgramState* programState + , const CubismModel& model, const csmInt32 index, CubismShaderSet* shaderSet) +{ + const csmInt32 textureIndex = model.GetDrawableTextureIndex(index); + cocos2d::Texture2D* texture = renderer->GetBindedTexture(textureIndex); + programState->setTexture(shaderSet->SamplerTexture0Location, 0, texture->getBackendTexture()); +} + +void CubismShader_Cocos2dx::SetColorUniformVariables(cocos2d::backend::ProgramState* programState, CubismShaderSet* shaderSet, CubismRenderer::CubismTextureColor& baseColor, + CubismRenderer::CubismTextureColor& multiplyColor, CubismRenderer::CubismTextureColor& screenColor) +{ + csmFloat32 base[4] = { baseColor.R, baseColor.G, baseColor.B, baseColor.A }; + csmFloat32 multiply[4] = { multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A }; + csmFloat32 screen[4] = { screenColor.R, screenColor.G, screenColor.B, screenColor.A }; + + programState->setUniform(shaderSet->UniformBaseColorLocation, base, sizeof(float) * 4); + programState->setUniform(shaderSet->UniformMultiplyColorLocation, multiply, sizeof(float) * 4); + programState->setUniform(shaderSet->UniformScreenColorLocation, screen, sizeof(float) * 4); +} + +void CubismShader_Cocos2dx::SetColorChannel(CubismRenderer_Cocos2dx* renderer, cocos2d::backend::ProgramState* programState, + CubismShaderSet* shaderSet, CubismClippingContext_Cocos2dx* contextBuffer) +{ + const csmInt32 channelIndex = contextBuffer->_layoutChannelIndex; + CubismRenderer::CubismTextureColor* colorChannel = contextBuffer->GetClippingManager()->GetChannelFlagAsColor(channelIndex); + csmFloat32 colorFlag[4] = { colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A }; + programState->setUniform(shaderSet->UnifromChannelFlagLocation, colorFlag, sizeof(float) * 4); +} + }}}} //------------ LIVE2D NAMESPACE ------------ diff --git a/src/Rendering/Cocos2d/CubismShader_Cocos2dx.hpp b/src/Rendering/Cocos2d/CubismShader_Cocos2dx.hpp index 4e03f80..bb7b963 100644 --- a/src/Rendering/Cocos2d/CubismShader_Cocos2dx.hpp +++ b/src/Rendering/Cocos2d/CubismShader_Cocos2dx.hpp @@ -41,6 +41,7 @@ namespace Live2D { namespace Cubism { namespace Framework { namespace Rendering // 前方宣言 class CubismRenderer_Cocos2dx; +class CubismClippingContext_Cocos2dx; /** * @brief Cocos2dx用のシェーダプログラムを生成・破棄するクラス
@@ -133,6 +134,49 @@ class CubismShader_Cocos2dx */ cocos2d::backend::Program* LoadShaderProgram(const csmChar* vertShaderSrc, const csmChar* fragShaderSrc); + /** + * @brief 必要な頂点属性を設定する + * + * @param[in] programState -> cocos2dプログラムステート + * @param[in] shaderSet -> シェーダープログラムのセット + */ + void SetVertexAttributes(cocos2d::backend::ProgramState* programState, CubismShaderSet* shaderSet); + + /** + * @brief テクスチャの設定を行う + * + * @param[in] renderer -> レンダラー + * @param[in] programState -> cocos2dプログラムステート + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画対象のメッシュのインデックス + * @param[in] shaderSet -> シェーダープログラムのセット + */ + void SetupTexture(CubismRenderer_Cocos2dx* renderer, cocos2d::backend::ProgramState* programState + , const CubismModel& model, const csmInt32 index, CubismShaderSet* shaderSet); + + /** + * @brief 色関連のユニフォーム変数の設定を行う + * + * @param[in] programState -> cocos2dプログラムステート + * @param[in] shaderSet -> シェーダープログラムのセット + * @param[in] baseColor -> ベースカラー + * @param[in] multiplyColor -> 乗算カラー + * @param[in] screenColor -> スクリーンカラー + */ + void SetColorUniformVariables(cocos2d::backend::ProgramState* programState, CubismShaderSet* shaderSet, CubismRenderer::CubismTextureColor& baseColor + , CubismRenderer::CubismTextureColor& multiplyColor, CubismRenderer::CubismTextureColor& screenColor); + + /** + * @brief カラーチャンネル関連のユニフォーム変数の設定を行う + * + * @param[in] renderer -> レンダラー + * @param[in] programState -> cocos2dプログラムステート + * @param[in] shaderSet -> シェーダープログラムのセット + * @param[in] contextBuffer -> 描画コンテキスト + */ + void SetColorChannel(CubismRenderer_Cocos2dx* renderer, cocos2d::backend::ProgramState* programState, + CubismShaderSet* shaderSet, CubismClippingContext_Cocos2dx* contextBuffer); + #ifdef CSM_TARGET_ANDROID_ES2 public: /** diff --git a/src/Rendering/D3D11/CubismRenderer_D3D11.cpp b/src/Rendering/D3D11/CubismRenderer_D3D11.cpp index 8cb2706..c60237a 100644 --- a/src/Rendering/D3D11/CubismRenderer_D3D11.cpp +++ b/src/Rendering/D3D11/CubismRenderer_D3D11.cpp @@ -678,8 +678,9 @@ void CubismRenderer_D3D11::ExecuteDrawForMask(const CubismModel& model, const cs return; } - // テクスチャセット - ID3D11ShaderResourceView* textureView = GetTextureViewWithIndex(model, index); + // テクスチャ+サンプラーセット + SetTextureView(model, index); + SetSamplerAccordingToAnisotropy(); // シェーダーセット s_context->VSSetShader(shaderManager->GetVertexShader(ShaderNames_SetupMask), NULL, 0); @@ -696,51 +697,29 @@ void CubismRenderer_D3D11::ExecuteDrawForMask(const CubismModel& model, const cs CubismConstantBufferD3D11 cb; memset(&cb, 0, sizeof(cb)); - DirectX::XMMATRIX proj = ConvertToD3DX(GetClippingContextBufferForMask()->_matrixForMask); + // 使用するカラーチャンネルを設定 + CubismClippingContext_D3D11* contextBuffer = GetClippingContextBufferForMask(); + SetColorChannel(cb, contextBuffer); + + // 色 csmRectF* rect = GetClippingContextBufferForMask()->_layoutBounds; - const csmInt32 channelIndex = GetClippingContextBufferForMask()->_layoutChannelIndex; - CubismTextureColor* colorChannel = GetClippingContextBufferForMask()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - const CubismTextureColor& multiplyColor = model.GetMultiplyColor(index); - const CubismTextureColor& screenColor = model.GetScreenColor(index); + CubismTextureColor baseColor = {rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, rect->GetBottom() * 2.0f - 1.0f}; + CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismTextureColor screenColor = model.GetScreenColor(index); + SetColorConstantBuffer(cb, model, index, baseColor, multiplyColor, screenColor); - XMStoreFloat4x4(&cb.projectMatrix, DirectX::XMMatrixTranspose(proj)); - XMStoreFloat4(&cb.baseColor, DirectX::XMVectorSet(rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, rect->GetBottom() * 2.0f - 1.0f)); - XMStoreFloat4(&cb.channelFlag, DirectX::XMVectorSet(colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A)); - XMStoreFloat4(&cb.multiplyColor, DirectX::XMVectorSet(multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A)); - XMStoreFloat4(&cb.screenColor, DirectX::XMVectorSet(screenColor.R, screenColor.G, screenColor.B, screenColor.A)); + // プロジェクションMtx + SetProjectionMatrix(cb, GetClippingContextBufferForMask()->_matrixForMask); // Update - ID3D11Buffer* constantBuffer = _constantBuffers[_commandBufferCurrent][index]; - s_context->UpdateSubresource(constantBuffer, 0, NULL, &cb, 0, 0); - - // セットする - s_context->VSSetConstantBuffers(0, 1, &constantBuffer); - s_context->PSSetConstantBuffers(0, 1, &constantBuffer); - } - - // テクスチャ - { - ID3D11ShaderResourceView* const viewArray[2] = { textureView, NULL }; - s_context->PSSetShaderResources(0, 2, viewArray); - - SetSamplerAccordingToAnisotropy(); + UpdateConstantBuffer(cb, index); } // トライアングルリスト s_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // 描画 - { - UINT strides = sizeof(Csm::CubismVertexD3D11); - UINT offsets = 0; - ID3D11Buffer* vertexBuffer = _vertexBuffers[_commandBufferCurrent][index]; - ID3D11Buffer* indexBuffer = _indexBuffers[_commandBufferCurrent][index]; - const csmInt32 indexCount = model.GetDrawableVertexIndexCount(index); - - s_context->IASetVertexBuffers(0, 1, &vertexBuffer, &strides, &offsets); - s_context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); - s_context->DrawIndexed(indexCount, 0, 0); - } + DrawDrawableIndexed(model, index); } void CubismRenderer_D3D11::ExecuteDrawForDraw(const CubismModel& model, const csmInt32 index) @@ -752,8 +731,12 @@ void CubismRenderer_D3D11::ExecuteDrawForDraw(const CubismModel& model, const cs return; } - // テクスチャセット - ID3D11ShaderResourceView* textureView = GetTextureViewWithIndex(model, index); + // テクスチャ+サンプラーセット + SetTextureView(model, index); + SetSamplerAccordingToAnisotropy(); + + // シェーダーセット + SetShader(model, index); // ブレンドステート { @@ -761,72 +744,54 @@ void CubismRenderer_D3D11::ExecuteDrawForDraw(const CubismModel& model, const cs SetBlendState(colorBlendMode); } + // 定数バッファ { - SetShader(model, index); + CubismConstantBufferD3D11 cb; + memset(&cb, 0, sizeof(cb)); const csmBool masked = GetClippingContextBufferForDraw() != NULL; + if (masked) + { + // View座標をClippingContextの座標に変換するための行列を設定 + DirectX::XMMATRIX clip = ConvertToD3DX(GetClippingContextBufferForDraw()->_matrixForDraw); + XMStoreFloat4x4(&cb.clipMatrix, DirectX::XMMatrixTranspose(clip)); - // テクスチャ+サンプラーセット - ID3D11ShaderResourceView* const viewArray[2] = { textureView, - (masked ? _offscreenSurfaces[_commandBufferCurrent][GetClippingContextBufferForDraw()->_bufferIndex].GetTextureView() : NULL)}; - s_context->PSSetShaderResources(0, 2, viewArray); + // 使用するカラーチャンネルを設定 + CubismClippingContext_D3D11* contextBuffer = GetClippingContextBufferForDraw(); + SetColorChannel(cb, contextBuffer); + } - SetSamplerAccordingToAnisotropy(); + // 色 + CubismTextureColor baseColor = GetModelColorWithOpacity(model.GetDrawableOpacity(index)); + CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismTextureColor screenColor = model.GetScreenColor(index); + SetColorConstantBuffer(cb, model, index, baseColor, multiplyColor, screenColor); - // 定数バッファ - { - CubismConstantBufferD3D11 cb; - memset(&cb, 0, sizeof(cb)); + // プロジェクションMtx + SetProjectionMatrix(cb, GetMvpMatrix()); - if (masked) - { - // View座標をClippingContextの座標に変換するための行列を設定 - DirectX::XMMATRIX clip = ConvertToD3DX(GetClippingContextBufferForDraw()->_matrixForDraw); - XMStoreFloat4x4(&cb.clipMatrix, DirectX::XMMatrixTranspose(clip)); - - // 使用するカラーチャンネルを設定 - const csmInt32 channelIndex = GetClippingContextBufferForDraw()->_layoutChannelIndex; - CubismRenderer::CubismTextureColor* colorChannel = GetClippingContextBufferForDraw()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - XMStoreFloat4(&cb.channelFlag, DirectX::XMVectorSet(colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A)); - } + // Update + UpdateConstantBuffer(cb, index); + } - // プロジェクションMtx - CubismMatrix44 mvp = GetMvpMatrix(); - DirectX::XMMATRIX proj = ConvertToD3DX(mvp); - XMStoreFloat4x4(&cb.projectMatrix, DirectX::XMMatrixTranspose(proj)); - - // 色 - CubismTextureColor modelColorRGBA = GetModelColorWithOpacity(model.GetDrawableOpacity(index)); - const CubismTextureColor multiplyColor = model.GetMultiplyColor(index); - const CubismTextureColor screenColor = model.GetScreenColor(index); - XMStoreFloat4(&cb.baseColor, DirectX::XMVectorSet(modelColorRGBA.R, modelColorRGBA.G, modelColorRGBA.B, modelColorRGBA.A)); - XMStoreFloat4(&cb.multiplyColor, DirectX::XMVectorSet(multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A)); - XMStoreFloat4(&cb.screenColor, DirectX::XMVectorSet(screenColor.R, screenColor.G, screenColor.B, screenColor.A)); - - // Update - ID3D11Buffer* constantBuffer = _constantBuffers[_commandBufferCurrent][index]; - s_context->UpdateSubresource(constantBuffer, 0, NULL, &cb, 0, 0); - - s_context->VSSetConstantBuffers(0, 1, &constantBuffer); - s_context->PSSetConstantBuffers(0, 1, &constantBuffer); - } + // トライアングルリスト + s_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - // トライアングルリスト - s_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + // 描画 + DrawDrawableIndexed(model, index); +} - // 描画 - { - UINT strides = sizeof(Csm::CubismVertexD3D11); - UINT offsets = 0; - ID3D11Buffer* vertexBuffer = _vertexBuffers[_commandBufferCurrent][index]; - ID3D11Buffer* indexBuffer = _indexBuffers[_commandBufferCurrent][index]; - const csmInt32 indexCount = model.GetDrawableVertexIndexCount(index); - - s_context->IASetVertexBuffers(0, 1, &vertexBuffer, &strides, &offsets); - s_context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); - s_context->DrawIndexed(indexCount, 0, 0); - } - } +void CubismRenderer_D3D11::DrawDrawableIndexed(const CubismModel& model, const csmInt32 index) +{ + UINT strides = sizeof(Csm::CubismVertexD3D11); + UINT offsets = 0; + ID3D11Buffer* vertexBuffer = _vertexBuffers[_commandBufferCurrent][index]; + ID3D11Buffer* indexBuffer = _indexBuffers[_commandBufferCurrent][index]; + const csmInt32 indexCount = model.GetDrawableVertexIndexCount(index); + + s_context->IASetVertexBuffers(0, 1, &vertexBuffer, &strides, &offsets); + s_context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); + s_context->DrawIndexed(indexCount, 0, 0); } void CubismRenderer_D3D11::DrawMeshDX11(const CubismModel& model, const csmInt32 index) @@ -1125,16 +1090,57 @@ void CubismRenderer_D3D11::SetShader(const CubismModel& model, const csmInt32 in s_context->PSSetShader(shaderManager->GetPixelShader(pixelShaderNames), NULL, 0); } +void CubismRenderer_D3D11::SetTextureView(const CubismModel& model, const csmInt32 index) +{ + const csmBool masked = GetClippingContextBufferForDraw() != NULL; + const csmBool drawing = !IsGeneratingMask(); + + ID3D11ShaderResourceView* textureView = GetTextureViewWithIndex(model, index); + ID3D11ShaderResourceView* maskView = (masked && drawing ? _offscreenSurfaces[_commandBufferCurrent][GetClippingContextBufferForDraw()->_bufferIndex].GetTextureView() : NULL); + ID3D11ShaderResourceView* const viewArray[2] = { textureView, maskView }; + s_context->PSSetShaderResources(0, 2, viewArray); +} + +void CubismRenderer_D3D11::SetColorConstantBuffer(CubismConstantBufferD3D11& cb, const CubismModel& model, const csmInt32 index, + CubismTextureColor& baseColor, CubismTextureColor& multiplyColor, CubismTextureColor& screenColor) +{ + XMStoreFloat4(&cb.baseColor, DirectX::XMVectorSet(baseColor.R, baseColor.G, baseColor.B, baseColor.A)); + XMStoreFloat4(&cb.multiplyColor, DirectX::XMVectorSet(multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A)); + XMStoreFloat4(&cb.screenColor, DirectX::XMVectorSet(screenColor.R, screenColor.G, screenColor.B, screenColor.A)); +} + +void CubismRenderer_D3D11::SetColorChannel(CubismConstantBufferD3D11& cb, CubismClippingContext_D3D11* contextBuffer) +{ + const csmInt32 channelIndex = contextBuffer->_layoutChannelIndex; + CubismRenderer::CubismTextureColor* colorChannel = contextBuffer->GetClippingManager()->GetChannelFlagAsColor(channelIndex); + XMStoreFloat4(&cb.channelFlag, DirectX::XMVectorSet(colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A)); +} + +void CubismRenderer_D3D11::SetProjectionMatrix(CubismConstantBufferD3D11& cb, CubismMatrix44 matrix) +{ + DirectX::XMMATRIX proj = ConvertToD3DX(matrix); + XMStoreFloat4x4(&cb.projectMatrix, DirectX::XMMatrixTranspose(proj)); +} + +void CubismRenderer_D3D11::UpdateConstantBuffer(CubismConstantBufferD3D11& cb, csmInt32 index) +{ + ID3D11Buffer* constantBuffer = _constantBuffers[_commandBufferCurrent][index]; + s_context->UpdateSubresource(constantBuffer, 0, NULL, &cb, 0, 0); + + s_context->VSSetConstantBuffers(0, 1, &constantBuffer); + s_context->PSSetConstantBuffers(0, 1, &constantBuffer); +} + void CubismRenderer_D3D11::SetSamplerAccordingToAnisotropy() { if (GetAnisotropy() > 0.0) - { - GetRenderStateManager()->SetSampler(s_context, CubismRenderState_D3D11::Sampler_Anisotropy, GetAnisotropy()); - } - else - { - GetRenderStateManager()->SetSampler(s_context, CubismRenderState_D3D11::Sampler_Normal); - } + { + GetRenderStateManager()->SetSampler(s_context, CubismRenderState_D3D11::Sampler_Anisotropy, GetAnisotropy()); + } + else + { + GetRenderStateManager()->SetSampler(s_context, CubismRenderState_D3D11::Sampler_Normal); + } } const csmBool inline CubismRenderer_D3D11::IsGeneratingMask() const diff --git a/src/Rendering/D3D11/CubismRenderer_D3D11.hpp b/src/Rendering/D3D11/CubismRenderer_D3D11.hpp index 062e61a..a13a866 100644 --- a/src/Rendering/D3D11/CubismRenderer_D3D11.hpp +++ b/src/Rendering/D3D11/CubismRenderer_D3D11.hpp @@ -12,6 +12,7 @@ #include "../CubismRenderer.hpp" #include "../CubismClippingManager.hpp" #include "CubismFramework.hpp" +#include "CubismType_D3D11.hpp" #include "Type/csmVector.hpp" #include "Type/csmRectF.hpp" #include "Math/CubismVector2.hpp" @@ -268,6 +269,14 @@ class CubismRenderer_D3D11 : public CubismRenderer */ void ExecuteDrawForDraw(const CubismModel& model, const csmInt32 index); + /** + * @brief 指定されたメッシュインデックスに対して描画命令を実行する + * + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画対象のインデックス + */ + void DrawDrawableIndexed(const CubismModel& model, const csmInt32 index); + /** * @brief レンダラが保持する静的なリソースを解放する */ @@ -354,6 +363,51 @@ class CubismRenderer_D3D11 : public CubismRenderer */ void SetShader(const CubismModel& model, const csmInt32 index); + /** + * @brief 描画に使用するテクスチャを設定する。 + * + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画対象のインデックス + */ + void SetTextureView(const CubismModel& model, const csmInt32 index); + + /** + * @brief 色関連の定数バッファを設定する + * + * @param[in] cb -> 設定する定数バッファ + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画対象のインデックス + * @param[in] baseColor -> ベースカラー + * @param[in] multiplyColor -> 乗算カラー + * @param[in] screenColor -> スクリーンカラー + */ + void SetColorConstantBuffer(CubismConstantBufferD3D11& cb, const CubismModel& model, const csmInt32 index, + CubismTextureColor& baseColor, CubismTextureColor& multiplyColor, CubismTextureColor& screenColor); + + /** + * @brief 描画に使用するカラーチャンネルを設定 + * + * @param[in] cb -> 設定する定数バッファ + * @param[in] contextBuffer -> 描画コンテキスト + */ + void SetColorChannel(CubismConstantBufferD3D11& cb, CubismClippingContext_D3D11* contextBuffer); + + /** + * @brief 描画に使用するプロジェクション行列を更新する + * + * @param[in] cb -> 設定する定数バッファ + * @param[in] matrix -> 設定するプロジェクション行列 + */ + void SetProjectionMatrix(CubismConstantBufferD3D11& cb, CubismMatrix44 matrix); + + /** + * @brief 定数バッファを更新する + * + * @param[in] cb -> 書き込む定数バッファ情報 + * @param[in] index -> 描画対象のインデックス + */ + void UpdateConstantBuffer(CubismConstantBufferD3D11& cb, csmInt32 index); + /** * @brief 異方向フィルタリングの値によってサンプラーを設定する。 */ diff --git a/src/Rendering/D3D9/CubismRenderer_D3D9.cpp b/src/Rendering/D3D9/CubismRenderer_D3D9.cpp index 98f20ad..b3b313d 100644 --- a/src/Rendering/D3D9/CubismRenderer_D3D9.cpp +++ b/src/Rendering/D3D9/CubismRenderer_D3D9.cpp @@ -623,16 +623,12 @@ void CubismRenderer_D3D9::ExecuteDrawForDraw(const CubismModel& model, const csm shaderEffect->Begin(&numPass, 0); shaderEffect->BeginPass(0); - // テクスチャセット メイン - LPDIRECT3DTEXTURE9 texture = GetTextureWithIndex(model, index); - shaderEffect->SetTexture("mainTexture", texture); - - // テクスチャセット マスク - const csmBool masked = GetClippingContextBufferForDraw() != NULL; - shaderEffect->SetTexture("maskTexture", (masked ? _offscreenSurfaces[_commandBufferCurrent][GetClippingContextBufferForDraw()->_bufferIndex].GetTexture() : NULL)); + // テスクチャ + SetExecutionTextures(model, index, shaderEffect); // 定数バッファ { + const csmBool masked = GetClippingContextBufferForDraw() != NULL; if (masked) { // View座標をClippingContextの座標に変換するための行列を設定 @@ -641,41 +637,25 @@ void CubismRenderer_D3D9::ExecuteDrawForDraw(const CubismModel& model, const csm shaderEffect->SetMatrix("clipMatrix", &clipM); // 使用するカラーチャンネルを設定 - const csmInt32 channelIndex = GetClippingContextBufferForDraw()->_layoutChannelIndex; - CubismRenderer::CubismTextureColor* colorChannel = GetClippingContextBufferForDraw()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - D3DXVECTOR4 channel(colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); - shaderEffect->SetVector("channelFlag", &channel); + CubismClippingContext_D3D9* contextBuffer = GetClippingContextBufferForDraw(); + SetColorChannel(shaderEffect, contextBuffer); } - CubismMatrix44 mvp = GetMvpMatrix(); - D3DXMATRIX proj = ConvertToD3DX(mvp); - shaderEffect->SetMatrix("projectMatrix", &proj); - - CubismTextureColor modelColorRGBA = (IsGeneratingMask() ? GetModelColor() : GetModelColorWithOpacity(model.GetDrawableOpacity(index))); - D3DXVECTOR4 color(modelColorRGBA.R, modelColorRGBA.G, modelColorRGBA.B, modelColorRGBA.A); - shaderEffect->SetVector("baseColor", &color); - - const CubismTextureColor& multiplyColor = model.GetMultiplyColor(index); - D3DXVECTOR4 shaderMultiplyColor(multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); - shaderEffect->SetVector("multiplyColor", &shaderMultiplyColor); + // プロジェクション行列 + SetProjectionMatrix(shaderEffect, GetMvpMatrix()); - const CubismTextureColor& screenColor = model.GetScreenColor(index); - D3DXVECTOR4 shaderScreenColor(screenColor.R, screenColor.G, screenColor.B, screenColor.A); - shaderEffect->SetVector("screenColor", &shaderScreenColor); + // 色 + CubismTextureColor modelColorRGBA = GetModelColorWithOpacity(model.GetDrawableOpacity(index)); + CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismTextureColor screenColor = model.GetScreenColor(index); + SetColorVectors(shaderEffect, modelColorRGBA, multiplyColor, screenColor); } // パラメータ反映 shaderEffect->CommitChanges(); // 描画 - { - const csmInt32 vertexCount = model.GetDrawableVertexCount(index); - const csmInt32 indexCount = model.GetDrawableVertexIndexCount(index); - const csmInt32 triangleCount = indexCount / 3; - const csmUint16* indexArray = _indexStore[index]; - const CubismVertexD3D9* vertexArray = _vertexStore[index]; - s_useDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, triangleCount, indexArray, D3DFMT_INDEX16, vertexArray, sizeof(CubismVertexD3D9)); - } + DrawIndexedPrimiteveWithSetup(model, index); shaderEffect->EndPass(); shaderEffect->End(); @@ -710,48 +690,29 @@ void CubismRenderer_D3D9::ExecuteDrawForMask(const CubismModel& model, const csm // 定数バッファ { - CubismMatrix44 modelToWorldF = GetClippingContextBufferForMask()->_matrixForMask; - D3DXMATRIX proj = ConvertToD3DX(modelToWorldF); - shaderEffect->SetMatrix("projectMatrix", &proj); + // プロジェクション行列 + SetProjectionMatrix(shaderEffect, GetClippingContextBufferForMask()->_matrixForMask); + // 色 csmRectF* rect = GetClippingContextBufferForMask()->_layoutBounds; - D3DXVECTOR4 color(rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, rect->GetBottom() * 2.0f - 1.0f); - shaderEffect->SetVector("baseColor", &color); - - const CubismTextureColor& multiplyColor = model.GetMultiplyColor(index); - D3DXVECTOR4 shaderMultiplyColor(multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); - shaderEffect->SetVector("multiplyColor", &shaderMultiplyColor); + CubismTextureColor baseColor = {rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, rect->GetBottom() * 2.0f - 1.0f}; + CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismTextureColor screenColor = model.GetScreenColor(index); + SetColorVectors(shaderEffect, baseColor, multiplyColor, screenColor); - const CubismTextureColor& screenColor = model.GetScreenColor(index); - D3DXVECTOR4 shaderScreenColor(screenColor.R, screenColor.G, screenColor.B, screenColor.A); - shaderEffect->SetVector("screenColor", &shaderScreenColor); + // 使用するカラーチャンネルを設定 + CubismClippingContext_D3D9* contextBuffer = GetClippingContextBufferForMask(); + SetColorChannel(shaderEffect, contextBuffer); - // チャンネル - const csmInt32 channelIndex = GetClippingContextBufferForMask()->_layoutChannelIndex; - // チャンネルをRGBAに変換 - CubismTextureColor* colorChannel = GetClippingContextBufferForMask()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - D3DXVECTOR4 channel(colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); - shaderEffect->SetVector("channelFlag", &channel); - - // テクスチャセット - shaderEffect->SetTexture("mainTexture", GetTextureWithIndex(model, index)); - // 使わない場合はNULLを必ず代入 - shaderEffect->SetTexture("maskTexture", NULL); + // テスクチャ + SetExecutionTextures(model, index, shaderEffect); // パラメータ反映 shaderEffect->CommitChanges(); } // 描画 - { - const csmInt32 vertexCount = model.GetDrawableVertexCount(index); - const csmInt32 indexCount = model.GetDrawableVertexIndexCount(index); - const csmInt32 triangleCount = indexCount / 3; - const csmUint16* indexArray = _indexStore[index]; - const CubismVertexD3D9* vertexArray = _vertexStore[index]; - s_useDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, triangleCount, - indexArray, D3DFMT_INDEX16, vertexArray, sizeof(CubismVertexD3D9)); - } + DrawIndexedPrimiteveWithSetup(model, index); shaderEffect->EndPass(); shaderEffect->End(); @@ -1101,6 +1062,52 @@ void CubismRenderer_D3D9::SetTextureFilter() const } } +void CubismRenderer_D3D9::SetColorVectors(ID3DXEffect* shaderEffect, CubismTextureColor& baseColor, CubismTextureColor& multiplyColor, CubismTextureColor& screenColor) +{ + D3DXVECTOR4 shaderBaseColor(baseColor.R, baseColor.G, baseColor.B, baseColor.A); + D3DXVECTOR4 shaderMultiplyColor(multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); + D3DXVECTOR4 shaderScreenColor(screenColor.R, screenColor.G, screenColor.B, screenColor.A); + + shaderEffect->SetVector("baseColor", &shaderBaseColor); + shaderEffect->SetVector("multiplyColor", &shaderMultiplyColor); + shaderEffect->SetVector("screenColor", &shaderScreenColor); +} + +void CubismRenderer_D3D9::SetExecutionTextures(const CubismModel& model, const csmInt32 index, ID3DXEffect* shaderEffect) +{ + const csmBool drawing = !IsGeneratingMask(); + const csmBool masked = GetClippingContextBufferForDraw() != NULL; + LPDIRECT3DTEXTURE9 mainTexture = GetTextureWithIndex(model, index); + LPDIRECT3DTEXTURE9 maskTexture = ((drawing && masked) ? _offscreenSurfaces[_commandBufferCurrent][GetClippingContextBufferForDraw()->_bufferIndex].GetTexture() : NULL); + + shaderEffect->SetTexture("mainTexture", mainTexture); + shaderEffect->SetTexture("maskTexture", maskTexture); +} + +void CubismRenderer_D3D9::SetColorChannel(ID3DXEffect* shaderEffect, CubismClippingContext_D3D9* contextBuffer) +{ + const csmInt32 channelIndex = contextBuffer->_layoutChannelIndex; + CubismRenderer::CubismTextureColor* colorChannel = contextBuffer->GetClippingManager()->GetChannelFlagAsColor(channelIndex); + D3DXVECTOR4 channel(colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); + shaderEffect->SetVector("channelFlag", &channel); +} + +void CubismRenderer_D3D9::SetProjectionMatrix(ID3DXEffect* shaderEffect, CubismMatrix44& matrix) +{ + D3DXMATRIX proj = ConvertToD3DX(matrix); + shaderEffect->SetMatrix("projectMatrix", &proj); +} + +void CubismRenderer_D3D9::DrawIndexedPrimiteveWithSetup(const CubismModel& model, const csmInt32 index) +{ + const csmInt32 vertexCount = model.GetDrawableVertexCount(index); + const csmInt32 indexCount = model.GetDrawableVertexIndexCount(index); + const csmInt32 triangleCount = indexCount / 3; + const csmUint16* indexArray = _indexStore[index]; + const CubismVertexD3D9* vertexArray = _vertexStore[index]; + s_useDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, triangleCount, indexArray, D3DFMT_INDEX16, vertexArray, sizeof(CubismVertexD3D9)); +} + }}}} //------------ LIVE2D NAMESPACE ------------ diff --git a/src/Rendering/D3D9/CubismRenderer_D3D9.hpp b/src/Rendering/D3D9/CubismRenderer_D3D9.hpp index 48f78cb..db44425 100644 --- a/src/Rendering/D3D9/CubismRenderer_D3D9.hpp +++ b/src/Rendering/D3D9/CubismRenderer_D3D9.hpp @@ -367,6 +367,49 @@ class CubismRenderer_D3D9 : public CubismRenderer */ void SetTextureFilter() const; + /** + * @brief 色関連の定数バッファを設定 + * + * @param[in] shaderEffect -> シェーダーエフェクト + * @param[in] baseColor -> ベースカラー + * @param[in] multiplyColor -> 乗算カラー + * @param[in] screenColor -> スクリーンカラー + */ + void SetColorVectors(ID3DXEffect* shaderEffect, CubismTextureColor& baseColor, CubismTextureColor& multiplyColor, CubismTextureColor& screenColor); + + /** + * @brief 描画実行時のテクスチャを設定 + * + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画すべき対象のインデックス + * @param[in] shaderEffect -> シェーダーエフェクト + */ + void SetExecutionTextures(const CubismModel& model, const csmInt32 index, ID3DXEffect* shaderEffect); + + /** + * @brief 描画に使用するカラーチャンネルを設定 + * + * @param[in] shaderEffect -> シェーダーエフェクト + * @param[in] contextBuffer -> 描画コンテキスト + */ + void SetColorChannel(ID3DXEffect* shaderEffect, CubismClippingContext_D3D9* contextBuffer); + + /** + * @brief 描画に使用するプロジェクション行列を更新する + * + * @param[in] shaderEffect -> シェーダーエフェクト + * @param[in] matrix -> 設定するプロジェクション行列 + */ + void SetProjectionMatrix(ID3DXEffect* shaderEffect, CubismMatrix44& matrix); + + /** + * @brief 引数を指定して DrawIndexedPrimitiveUP 描画命令を実行 + * + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画すべき対象のインデックス + */ + void DrawIndexedPrimiteveWithSetup(const CubismModel& model, const csmInt32 index); + csmUint32 _drawableNum; ///< _vertexBuffers, _indexBuffersの確保数 /** diff --git a/src/Rendering/Metal/CubismRenderer_Metal.hpp b/src/Rendering/Metal/CubismRenderer_Metal.hpp index c620793..f5b4135 100644 --- a/src/Rendering/Metal/CubismRenderer_Metal.hpp +++ b/src/Rendering/Metal/CubismRenderer_Metal.hpp @@ -127,9 +127,9 @@ class CubismRenderer_Metal : public CubismRenderer * * @param[in] model -> モデルのインスタンス */ - void Initialize(Framework::CubismModel* model); + void Initialize(Framework::CubismModel* model) override; - void Initialize(Framework::CubismModel* model, csmInt32 maskBufferCount); + void Initialize(Framework::CubismModel* model, csmInt32 maskBufferCount) override; /** * @brief テクスチャのバインド処理
@@ -208,7 +208,7 @@ class CubismRenderer_Metal : public CubismRenderer * @brief モデルを描画する実際の処理 * */ - void DoDrawModel(); + void DoDrawModel() override; /** * @brief 描画オブジェクト(アートメッシュ)を描画する。
@@ -257,12 +257,12 @@ class CubismRenderer_Metal : public CubismRenderer /** * @brief SuperClass対応 */ - virtual void SaveProfile(); + void SaveProfile() override; /** * @brief SuperClass対応 */ - virtual void RestoreProfile(); + void RestoreProfile() override; /** * @brief マスクテクスチャに描画するクリッピングコンテキストをセットする。 diff --git a/src/Rendering/Metal/CubismShader_Metal.hpp b/src/Rendering/Metal/CubismShader_Metal.hpp index 8f929b3..92176f7 100644 --- a/src/Rendering/Metal/CubismShader_Metal.hpp +++ b/src/Rendering/Metal/CubismShader_Metal.hpp @@ -12,6 +12,7 @@ #include "CubismRenderer_Metal.hpp" #include "CubismCommandBuffer_Metal.hpp" #include "Type/csmVector.hpp" +#include "MetalShaderTypes.h" //------------ LIVE2D NAMESPACE ------------ namespace Live2D { namespace Cubism { namespace Framework { namespace Rendering { @@ -97,6 +98,38 @@ class CubismShader_Metal */ void GenerateShaders(CubismRenderer_Metal* renderer); + /** + * @brief CubismMatrix44をsimd::float4x4の形式に変換する + */ + simd::float4x4 ConvertCubismMatrix44IntoSimdFloat4x4(CubismMatrix44& matrix); + + /** + * @brief 使用するカラーチャンネルを設定 + * + * @param[in] shaderUniforms -> シェーダー用ユニフォームバッファ + * @param[in] contextBuffer -> クリッピングマスクのコンテキスト + */ + void SetColorChannel(CubismShaderUniforms& shaderUniforms, CubismClippingContext_Metal* contextBuffer); + + /** + * @brief モデルにバインドされているテクスチャを、フラグメントシェーダーのテクスチャに設定する + * + * @param[in] drawCommandBuffer -> コマンドバッファ + * @param[in] renderEncoder -> MTLRenderCommandEncoder + * @param[in] renderer -> レンダラのインスタンス + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画オブジェクトのインデックス + */ + void SetFragmentModelTexture(CubismCommandBuffer_Metal::DrawCommandBuffer* drawCommandBuffer, id renderEncoder + , CubismRenderer_Metal* renderer, const CubismModel& model, const csmInt32 index); + + /** + * @brief 頂点シェーダーに頂点インデックスと UV 座標を設定する + * + * @param[in] drawCommandBuffer -> コマンドバッファ + */ + void SetVertexBufferForVerticesAndUvs(CubismCommandBuffer_Metal::DrawCommandBuffer* drawCommandBuffer, id renderEncoder); + /** * @brief シェーダプログラムをロードしてアドレス返す。 * diff --git a/src/Rendering/Metal/CubismShader_Metal.mm b/src/Rendering/Metal/CubismShader_Metal.mm index d9e741a..2523f28 100644 --- a/src/Rendering/Metal/CubismShader_Metal.mm +++ b/src/Rendering/Metal/CubismShader_Metal.mm @@ -8,7 +8,6 @@ #include "CubismShader_Metal.hpp" #include "CubismRenderer_Metal.hpp" #include "CubismRenderingInstanceSingleton_Metal.h" -#include "MetalShaderTypes.h" //------------ LIVE2D NAMESPACE ------------ namespace Live2D { namespace Cubism { namespace Framework { namespace Rendering { @@ -220,6 +219,35 @@ _shaderSets[18]->SamplerState = _shaderSets[0]->SamplerState; } +simd::float4x4 CubismShader_Metal::ConvertCubismMatrix44IntoSimdFloat4x4(CubismMatrix44& matrix) +{ + csmFloat32* srcArray = matrix.GetArray(); + return simd::float4x4(simd::float4 {srcArray[0], srcArray[1], srcArray[2], srcArray[3]}, + simd::float4 {srcArray[4], srcArray[5], srcArray[6], srcArray[7]}, + simd::float4 {srcArray[8], srcArray[9], srcArray[10], srcArray[11]}, + simd::float4 {srcArray[12], srcArray[13], srcArray[14], srcArray[15]}); +} + +void CubismShader_Metal::SetColorChannel(CubismShaderUniforms& shaderUniforms, CubismClippingContext_Metal* contextBuffer) +{ + const csmInt32 channelIndex = contextBuffer->_layoutChannelIndex; + CubismRenderer::CubismTextureColor* colorChannel = contextBuffer->GetClippingManager()->GetChannelFlagAsColor(channelIndex); + shaderUniforms.channelFlag = (vector_float4){ colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A }; +} + +void CubismShader_Metal::SetFragmentModelTexture(CubismCommandBuffer_Metal::DrawCommandBuffer* drawCommandBuffer, id renderEncoder + , CubismRenderer_Metal* renderer, const CubismModel& model, const csmInt32 index) +{ + const id texture = renderer->GetBindedTextureId(model.GetDrawableTextureIndex(index)); + [renderEncoder setFragmentTexture:texture atIndex:0]; +} + +void CubismShader_Metal::SetVertexBufferForVerticesAndUvs(CubismCommandBuffer_Metal::DrawCommandBuffer* drawCommandBuffer, id renderEncoder) +{ + [renderEncoder setVertexBuffer:(drawCommandBuffer->GetVertexBuffer()) offset:0 atIndex:MetalVertexInputIndexVertices]; + [renderEncoder setVertexBuffer:(drawCommandBuffer->GetUvBuffer()) offset:0 atIndex:MetalVertexInputUVs]; +} + void CubismShader_Metal::SetupShaderProgramForDraw(CubismCommandBuffer_Metal::DrawCommandBuffer* drawCommandBuffer, id renderEncoder , CubismRenderer_Metal* renderer, const CubismModel& model, const csmInt32 index) { @@ -254,17 +282,15 @@ break; } - // 頂点配列の設定 - [renderEncoder setVertexBuffer:(drawCommandBuffer->GetVertexBuffer()) offset:0 atIndex:MetalVertexInputIndexVertices]; + //テクスチャ設定 + SetFragmentModelTexture(drawCommandBuffer, renderEncoder, renderer, model, index); - // テクスチャ頂点の設定 - [renderEncoder setVertexBuffer:(drawCommandBuffer->GetUvBuffer()) offset:0 atIndex:MetalVertexInputUVs]; + // 頂点・テクスチャバッファの設定 + SetVertexBufferForVerticesAndUvs(drawCommandBuffer, renderEncoder); + CubismShaderUniforms shaderUniforms; if (masked) { - CubismMaskedShaderUniforms maskedShaderUniforms; - CubismFragMaskedShaderUniforms fragMaskedShaderUniforms; - // frameBufferに書かれたテクスチャ id tex = renderer->GetOffscreenSurface(renderer->GetClippingContextBufferForDraw()->_bufferIndex)->GetColorBuffer(); @@ -272,77 +298,31 @@ [renderEncoder setFragmentTexture:tex atIndex:1]; // 使用するカラーチャンネルを設定 - const csmInt32 channelIndex = renderer->GetClippingContextBufferForDraw()->_layoutChannelIndex; - CubismRenderer::CubismTextureColor* colorChannel = renderer->GetClippingContextBufferForDraw()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - - fragMaskedShaderUniforms.channelFlag = (vector_float4){ colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A }; - { - csmFloat32* srcArray = renderer->GetClippingContextBufferForDraw()->_matrixForDraw.GetArray(); - - maskedShaderUniforms.clipMatrix = simd::float4x4( - simd::float4 {srcArray[0], srcArray[1], srcArray[2], srcArray[3]}, - simd::float4 {srcArray[4], srcArray[5], srcArray[6], srcArray[7]}, - simd::float4 {srcArray[8], srcArray[9], srcArray[10], srcArray[11]}, - simd::float4 {srcArray[12], srcArray[13], srcArray[14], srcArray[15]}); - } - { - //座標変換 - CubismMatrix44 matrix4x4 = renderer->GetMvpMatrix(); - csmFloat32* srcArray = matrix4x4.GetArray(); - maskedShaderUniforms.matrix = simd::float4x4( - simd::float4 {srcArray[0], srcArray[1], srcArray[2], srcArray[3]}, - simd::float4 {srcArray[4], srcArray[5], srcArray[6], srcArray[7]}, - simd::float4 {srcArray[8], srcArray[9], srcArray[10], srcArray[11]}, - simd::float4 {srcArray[12], srcArray[13], srcArray[14], srcArray[15]}); - } + SetColorChannel(shaderUniforms, renderer->GetClippingContextBufferForDraw()); - //テクスチャ設定 - const id texture = renderer->GetBindedTextureId(model.GetDrawableTextureIndex(index)); - [renderEncoder setFragmentTexture:texture atIndex:0]; + // クリッピング変換行列設定 + shaderUniforms.clipMatrix = ConvertCubismMatrix44IntoSimdFloat4x4(renderer->GetClippingContextBufferForDraw()->_matrixForDraw); + } - CubismRenderer::CubismTextureColor baseColor = renderer->GetModelColorWithOpacity(model.GetDrawableOpacity(index)); - CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); - CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); - maskedShaderUniforms.baseColor = (vector_float4){ baseColor.R, baseColor.G, baseColor.B, baseColor.A }; - fragMaskedShaderUniforms.baseColor = (vector_float4){ baseColor.R, baseColor.G, baseColor.B, baseColor.A }; - fragMaskedShaderUniforms.multiplyColor = (vector_float4){ multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A }; - fragMaskedShaderUniforms.screenColor = (vector_float4){ screenColor.R, screenColor.G, screenColor.B, screenColor.A }; + // MVP行列設定 + CubismMatrix44 mvp = renderer->GetMvpMatrix(); + shaderUniforms.matrix = ConvertCubismMatrix44IntoSimdFloat4x4(mvp); - // 転送 - [renderEncoder setVertexBytes:&maskedShaderUniforms length:sizeof(CubismMaskedShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; - [renderEncoder setFragmentBytes:&fragMaskedShaderUniforms length:sizeof(CubismFragMaskedShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; - [renderEncoder setFragmentSamplerState:shaderSet->SamplerState atIndex:0]; + // 色定数バッファの設定 + CubismRenderer::CubismTextureColor baseColor = renderer->GetModelColorWithOpacity(model.GetDrawableOpacity(index)); + CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); - } else { - CubismNormalShaderUniforms normalShaderUniforms; - - //テクスチャ設定 - const id texture = renderer->GetBindedTextureId(model.GetDrawableTextureIndex(index)); - [renderEncoder setFragmentTexture:texture atIndex:0]; - - //座標変換 - CubismMatrix44 matrix4x4 = renderer->GetMvpMatrix(); - csmFloat32* srcArray = matrix4x4.GetArray(); - normalShaderUniforms.matrix = simd::float4x4( - simd::float4 {srcArray[0], srcArray[1], srcArray[2], srcArray[3]}, - simd::float4 {srcArray[4], srcArray[5], srcArray[6], srcArray[7]}, - simd::float4 {srcArray[8], srcArray[9], srcArray[10], srcArray[11]}, - simd::float4 {srcArray[12], srcArray[13], srcArray[14], srcArray[15]}); - - CubismRenderer::CubismTextureColor baseColor = renderer->GetModelColorWithOpacity(model.GetDrawableOpacity(index)); - CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); - CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); - normalShaderUniforms.baseColor = (vector_float4){ baseColor.R, baseColor.G, baseColor.B, baseColor.A }; - normalShaderUniforms.multiplyColor = (vector_float4){ multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A }; - normalShaderUniforms.screenColor = (vector_float4){ screenColor.R, screenColor.G, screenColor.B, screenColor.A }; - - // 転送 - [renderEncoder setVertexBytes:&normalShaderUniforms length:sizeof(CubismNormalShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; - [renderEncoder setFragmentBytes:&normalShaderUniforms length:sizeof(CubismNormalShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; - [renderEncoder setFragmentSamplerState:shaderSet->SamplerState atIndex:0]; - } + shaderUniforms.baseColor = (vector_float4){ baseColor.R, baseColor.G, baseColor.B, baseColor.A }; + shaderUniforms.multiplyColor = (vector_float4){ multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A }; + shaderUniforms.screenColor = (vector_float4){ screenColor.R, screenColor.G, screenColor.B, screenColor.A }; + // 転送 + [renderEncoder setVertexBytes:&shaderUniforms length:sizeof(CubismShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; + [renderEncoder setFragmentBytes:&shaderUniforms length:sizeof(CubismShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; + [renderEncoder setFragmentSamplerState:shaderSet->SamplerState atIndex:0]; [renderEncoder setDepthStencilState:shaderSet->DepthStencilState]; + drawCommandBuffer->GetCommandDraw()->SetRenderPipelineState(shaderSet->RenderPipelineState); } @@ -355,40 +335,35 @@ GenerateShaders(renderer); } + // シェーダーセットの設定 CubismShaderSet* shaderSet = _shaderSets[ShaderNames_SetupMask]; // テクスチャ設定 - const id texture = renderer->GetBindedTextureId(model.GetDrawableTextureIndex(index)); - [renderEncoder setFragmentTexture:texture atIndex:0]; + SetFragmentModelTexture(drawCommandBuffer, renderEncoder, renderer, model, index); // 頂点・テクスチャバッファの設定 - [renderEncoder setVertexBuffer:(drawCommandBuffer->GetVertexBuffer()) offset:0 atIndex:MetalVertexInputIndexVertices]; - [renderEncoder setVertexBuffer:(drawCommandBuffer->GetUvBuffer()) offset:0 atIndex:MetalVertexInputUVs]; + SetVertexBufferForVerticesAndUvs(drawCommandBuffer, renderEncoder); - CubismSetupMaskedShaderUniforms maskedShaderUniforms; - const csmInt32 channelIndex = renderer->GetClippingContextBufferForMask()->_layoutChannelIndex; - CubismRenderer::CubismTextureColor* colorChannel = renderer->GetClippingContextBufferForMask()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - maskedShaderUniforms.channelFlag = (vector_float4){ colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A }; + CubismShaderUniforms shaderUniforms; - csmFloat32* srcArray = renderer->GetClippingContextBufferForMask()->_matrixForMask.GetArray(); + // 使用するカラーチャンネルを設定 + SetColorChannel(shaderUniforms, renderer->GetClippingContextBufferForMask()); - maskedShaderUniforms.clipMatrix = simd::float4x4( - simd::float4 {srcArray[0], srcArray[1], srcArray[2], srcArray[3]}, - simd::float4 {srcArray[4], srcArray[5], srcArray[6], srcArray[7]}, - simd::float4 {srcArray[8], srcArray[9], srcArray[10], srcArray[11]}, - simd::float4 {srcArray[12], srcArray[13], srcArray[14], srcArray[15]}); + // クリッピング変換行列設定 + shaderUniforms.clipMatrix = ConvertCubismMatrix44IntoSimdFloat4x4(renderer->GetClippingContextBufferForMask()->_matrixForMask); + // 色定数バッファの設定 csmRectF* rect = renderer->GetClippingContextBufferForMask()->_layoutBounds; - - maskedShaderUniforms.baseColor = (vector_float4){ rect->X * 2.0f - 1.0f, + shaderUniforms.baseColor = (vector_float4){ rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, rect->GetBottom() * 2.0f - 1.0f }; // 転送 - [renderEncoder setVertexBytes:&maskedShaderUniforms length:sizeof(CubismSetupMaskedShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; - [renderEncoder setFragmentBytes:&maskedShaderUniforms length:sizeof(CubismSetupMaskedShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; + [renderEncoder setVertexBytes:&shaderUniforms length:sizeof(CubismShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; + [renderEncoder setFragmentBytes:&shaderUniforms length:sizeof(CubismShaderUniforms) atIndex:MetalVertexInputIndexUniforms]; [renderEncoder setFragmentSamplerState:shaderSet->SamplerState atIndex:0]; + drawCommandBuffer->GetCommandDraw()->SetRenderPipelineState(shaderSet->RenderPipelineState); } diff --git a/src/Rendering/Metal/MetalShaderTypes.h b/src/Rendering/Metal/MetalShaderTypes.h index 8726d7a..03c6f40 100644 --- a/src/Rendering/Metal/MetalShaderTypes.h +++ b/src/Rendering/Metal/MetalShaderTypes.h @@ -19,38 +19,16 @@ typedef enum MetalVertexInputIndex MetalVertexInputIndexUniforms = 2, } MetalVertexInputIndex; -typedef struct -{ - simd::float4x4 matrix; - vector_float4 baseColor; - vector_float4 multiplyColor; - vector_float4 screenColor; - -} CubismNormalShaderUniforms; - typedef struct { simd::float4x4 matrix; simd::float4x4 clipMatrix; - vector_float4 baseColor; - -} CubismMaskedShaderUniforms; - -typedef struct -{ - simd::float4x4 clipMatrix; - vector_float4 channelFlag; - vector_float4 baseColor; - -} CubismSetupMaskedShaderUniforms; - -typedef struct -{ vector_float4 channelFlag; vector_float4 baseColor; vector_float4 multiplyColor; vector_float4 screenColor; -} CubismFragMaskedShaderUniforms; +} CubismShaderUniforms; + #endif /* MetalShaderTypes_h */ diff --git a/src/Rendering/Metal/MetalShaders.metal b/src/Rendering/Metal/MetalShaders.metal index 7c699b3..783dd23 100644 --- a/src/Rendering/Metal/MetalShaders.metal +++ b/src/Rendering/Metal/MetalShaders.metal @@ -32,7 +32,7 @@ vertex MaskedRasterizerData VertShaderSrcSetupMask(uint vertexID [[ vertex_id ]], constant float2 *vertexArray [[ buffer(MetalVertexInputIndexVertices) ]], constant float2 *uvArray [[ buffer(MetalVertexInputUVs) ]], - constant CubismSetupMaskedShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]]) + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]]) { MaskedRasterizerData out; float2 vert = vertexArray[vertexID]; @@ -50,7 +50,7 @@ VertShaderSrcSetupMask(uint vertexID [[ vertex_id ]], fragment float4 FragShaderSrcSetupMask(MaskedRasterizerData in [[stage_in]], texture2d texture [[ texture(0) ]], - constant CubismSetupMaskedShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], sampler smp [[sampler(0)]]) { float isInside = @@ -69,7 +69,7 @@ vertex NormalRasterizerData VertShaderSrc(uint vertexID [[ vertex_id ]], constant float2 *vertexArray [[ buffer(MetalVertexInputIndexVertices) ]], constant float2 *uvArray [[ buffer(MetalVertexInputUVs) ]], - constant CubismNormalShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]]) + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]]) { NormalRasterizerData out; @@ -89,7 +89,7 @@ vertex MaskedRasterizerData VertShaderSrcMasked(uint vertexID [[ vertex_id ]], constant float2 *vertexArray [[ buffer(MetalVertexInputIndexVertices) ]], constant float2 *uvArray [[ buffer(MetalVertexInputUVs) ]], - constant CubismMaskedShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]]) + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]]) { MaskedRasterizerData out; float2 vert = vertexArray[vertexID]; @@ -110,7 +110,7 @@ VertShaderSrcMasked(uint vertexID [[ vertex_id ]], fragment float4 FragShaderSrc(NormalRasterizerData in [[stage_in]], texture2d texture [[ texture(0) ]], - constant CubismNormalShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], sampler smp [[sampler(0)]]) { float4 texColor = texture.sample(smp, in.texCoord); @@ -126,7 +126,7 @@ FragShaderSrc(NormalRasterizerData in [[stage_in]], fragment float4 FragShaderSrcPremultipliedAlpha(MaskedRasterizerData in [[stage_in]], texture2d texture [[ texture(0) ]], - constant CubismNormalShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], sampler smp [[sampler(0)]]) { float4 texColor = texture.sample(smp, in.texCoord); @@ -142,7 +142,7 @@ fragment float4 FragShaderSrcMask(MaskedRasterizerData in [[stage_in]], texture2d texture0 [[ texture(0) ]], texture2d texture1 [[ texture(1) ]], - constant CubismFragMaskedShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], sampler smp [[sampler(0)]]) { float4 texColor = texture0.sample(smp, in.texCoord); @@ -162,7 +162,7 @@ fragment float4 FragShaderSrcMaskInverted(MaskedRasterizerData in [[stage_in]], texture2d texture0 [[ texture(0) ]], texture2d texture1 [[ texture(1) ]], - constant CubismFragMaskedShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], sampler smp [[sampler(0)]]) { float4 texColor = texture0.sample(smp, in.texCoord); @@ -182,7 +182,7 @@ fragment float4 FragShaderSrcMaskPremultipliedAlpha(MaskedRasterizerData in [[stage_in]], texture2d texture0 [[ texture(0) ]], texture2d texture1 [[ texture(1) ]], - constant CubismFragMaskedShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], sampler smp [[sampler(0)]]) { float4 texColor = texture0.sample(smp, in.texCoord); @@ -201,7 +201,7 @@ fragment float4 FragShaderSrcMaskInvertedPremultipliedAlpha(MaskedRasterizerData in [[stage_in]], texture2d texture0 [[ texture(0) ]], texture2d texture1 [[ texture(1) ]], - constant CubismFragMaskedShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], + constant CubismShaderUniforms &uniforms [[ buffer(MetalVertexInputIndexUniforms) ]], sampler smp [[sampler(0)]]) { float4 texColor = texture0.sample(smp, in.texCoord); diff --git a/src/Rendering/OpenGL/CubismShader_OpenGLES2.cpp b/src/Rendering/OpenGL/CubismShader_OpenGLES2.cpp index 8563bd1..f97eca0 100644 --- a/src/Rendering/OpenGL/CubismShader_OpenGLES2.cpp +++ b/src/Rendering/OpenGL/CubismShader_OpenGLES2.cpp @@ -843,15 +843,11 @@ void CubismShader_OpenGLES2::SetupShaderProgramForDraw(CubismRenderer_OpenGLES2* glUseProgram(shaderSet->ShaderProgram); - // 頂点配列の設定 - const csmFloat32* vertexArray = model.GetDrawableVertices(index); - glEnableVertexAttribArray(shaderSet->AttributePositionLocation); - glVertexAttribPointer(shaderSet->AttributePositionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(csmFloat32) * 2, vertexArray); + //テクスチャ設定 + SetupTexture(renderer, model, index, shaderSet); - // テクスチャ頂点の設定 - const csmFloat32* uvArray = reinterpret_cast(model.GetDrawableVertexUvs(index)); - glEnableVertexAttribArray(shaderSet->AttributeTexCoordLocation); - glVertexAttribPointer(shaderSet->AttributeTexCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(csmFloat32) * 2, uvArray); + // 頂点属性設定 + SetVertexAttributes(model, index, shaderSet); if (masked) { @@ -867,30 +863,17 @@ void CubismShader_OpenGLES2::SetupShaderProgramForDraw(CubismRenderer_OpenGLES2* glUniformMatrix4fv(shaderSet->UniformClipMatrixLocation, 1, 0, renderer->GetClippingContextBufferForDraw()->_matrixForDraw.GetArray()); // 使用するカラーチャンネルを設定 - const csmInt32 channelIndex = renderer->GetClippingContextBufferForDraw()->_layoutChannelIndex; - CubismRenderer::CubismTextureColor* colorChannel = renderer->GetClippingContextBufferForDraw()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - glUniform4f(shaderSet->UnifromChannelFlagLocation, colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); + SetColorChannelUniformVariables(shaderSet, renderer->GetClippingContextBufferForDraw()); } - //テクスチャ設定 - const csmInt32 textureIndex = model.GetDrawableTextureIndex(index); - const GLuint textureId = renderer->GetBindedTextureId(textureIndex); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); - glUniform1i(shaderSet->SamplerTexture0Location, 0); - //座標変換 - CubismMatrix44 matrix4x4 = renderer->GetMvpMatrix(); - glUniformMatrix4fv(shaderSet->UniformMatrixLocation, 1, 0, matrix4x4.GetArray()); // + glUniformMatrix4fv(shaderSet->UniformMatrixLocation, 1, 0, renderer->GetMvpMatrix().GetArray()); // - //ベース色の取得 + // ユニフォーム変数設定 CubismRenderer::CubismTextureColor baseColor = renderer->GetModelColorWithOpacity(model.GetDrawableOpacity(index)); - const CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); - const CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); - - glUniform4f(shaderSet->UniformBaseColorLocation, baseColor.R, baseColor.G, baseColor.B, baseColor.A); - glUniform4f(shaderSet->UniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); - glUniform4f(shaderSet->UniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A); + CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); + SetColorUniformVariables(renderer, model, index, shaderSet, baseColor, multiplyColor, screenColor); glBlendFuncSeparate(SRC_COLOR, DST_COLOR, SRC_ALPHA, DST_ALPHA); } @@ -903,55 +886,31 @@ void CubismShader_OpenGLES2::SetupShaderProgramForMask(CubismRenderer_OpenGLES2* } // Blending - csmInt32 SRC_COLOR; - csmInt32 DST_COLOR; - csmInt32 SRC_ALPHA; - csmInt32 DST_ALPHA; + csmInt32 SRC_COLOR = GL_ZERO; + csmInt32 DST_COLOR = GL_ONE_MINUS_SRC_COLOR; + csmInt32 SRC_ALPHA = GL_ZERO; + csmInt32 DST_ALPHA = GL_ONE_MINUS_SRC_ALPHA; CubismShaderSet* shaderSet = _shaderSets[ShaderNames_SetupMask]; glUseProgram(shaderSet->ShaderProgram); //テクスチャ設定 - const csmInt32 textureIndex = model.GetDrawableTextureIndex(index); - const GLuint textureId = renderer->GetBindedTextureId(textureIndex); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); - glUniform1i(shaderSet->SamplerTexture0Location, 0); - - // 頂点配列の設定 - const csmFloat32* vertexArray = model.GetDrawableVertices(index); - glEnableVertexAttribArray(shaderSet->AttributePositionLocation); - glVertexAttribPointer(shaderSet->AttributePositionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(csmFloat32) * 2, vertexArray); + SetupTexture(renderer, model, index, shaderSet); - // テクスチャ頂点の設定 - const csmFloat32* uvArray = reinterpret_cast(model.GetDrawableVertexUvs(index)); - glEnableVertexAttribArray(shaderSet->AttributeTexCoordLocation); - glVertexAttribPointer(shaderSet->AttributeTexCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(csmFloat32) * 2, uvArray); + // 頂点属性設定 + SetVertexAttributes(model, index, shaderSet); - // チャンネル - const csmInt32 channelIndex = renderer->GetClippingContextBufferForMask()->_layoutChannelIndex; - CubismRenderer::CubismTextureColor* colorChannel = renderer->GetClippingContextBufferForMask()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - glUniform4f(shaderSet->UnifromChannelFlagLocation, colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); + // 使用するカラーチャンネルを設定 + SetColorChannelUniformVariables(shaderSet, renderer->GetClippingContextBufferForMask()); glUniformMatrix4fv(shaderSet->UniformClipMatrixLocation, 1, GL_FALSE, renderer->GetClippingContextBufferForMask()->_matrixForMask.GetArray()); + // ユニフォーム変数設定 csmRectF* rect = renderer->GetClippingContextBufferForMask()->_layoutBounds; - - glUniform4f(shaderSet->UniformBaseColorLocation, - rect->X * 2.0f - 1.0f, - rect->Y * 2.0f - 1.0f, - rect->GetRight() * 2.0f - 1.0f, - rect->GetBottom() * 2.0f - 1.0f); - - const CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); - const CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); - glUniform4f(shaderSet->UniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); - glUniform4f(shaderSet->UniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A); - - SRC_COLOR = GL_ZERO; - DST_COLOR = GL_ONE_MINUS_SRC_COLOR; - SRC_ALPHA = GL_ZERO; - DST_ALPHA = GL_ONE_MINUS_SRC_ALPHA; + CubismRenderer::CubismTextureColor baseColor = {rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, rect->GetBottom() * 2.0f - 1.0f}; + CubismRenderer::CubismTextureColor multiplyColor = model.GetMultiplyColor(index); + CubismRenderer::CubismTextureColor screenColor = model.GetScreenColor(index); + SetColorUniformVariables(renderer, model, index, shaderSet, baseColor, multiplyColor, screenColor); glBlendFuncSeparate(SRC_COLOR, DST_COLOR, SRC_ALPHA, DST_ALPHA); } @@ -1098,6 +1057,43 @@ GLuint CubismShader_OpenGLES2::LoadShaderProgram(const csmChar* vertShaderSrc, c return shaderProgram; } +void CubismShader_OpenGLES2::SetVertexAttributes(const CubismModel& model, const csmInt32 index, CubismShaderSet* shaderSet) +{ + // 頂点位置属性の設定 + const csmFloat32* vertexArray = model.GetDrawableVertices(index); + glEnableVertexAttribArray(shaderSet->AttributePositionLocation); + glVertexAttribPointer(shaderSet->AttributePositionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(csmFloat32) * 2, vertexArray); + + // テクスチャ座標属性の設定 + const csmFloat32* uvArray = reinterpret_cast(model.GetDrawableVertexUvs(index)); + glEnableVertexAttribArray(shaderSet->AttributeTexCoordLocation); + glVertexAttribPointer(shaderSet->AttributeTexCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(csmFloat32) * 2, uvArray); +} + +void CubismShader_OpenGLES2::SetupTexture(CubismRenderer_OpenGLES2* renderer, const CubismModel& model, const csmInt32 index, CubismShaderSet* shaderSet) +{ + const csmInt32 textureIndex = model.GetDrawableTextureIndex(index); + const GLuint textureId = renderer->GetBindedTextureId(textureIndex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureId); + glUniform1i(shaderSet->SamplerTexture0Location, 0); +} + +void CubismShader_OpenGLES2::SetColorUniformVariables(CubismRenderer_OpenGLES2* renderer, const CubismModel& model, const csmInt32 index, CubismShaderSet* shaderSet, + CubismRenderer::CubismTextureColor& baseColor, CubismRenderer::CubismTextureColor& multiplyColor, CubismRenderer::CubismTextureColor& screenColor) +{ + glUniform4f(shaderSet->UniformBaseColorLocation, baseColor.R, baseColor.G, baseColor.B, baseColor.A); + glUniform4f(shaderSet->UniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); + glUniform4f(shaderSet->UniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A); +} + +void CubismShader_OpenGLES2::SetColorChannelUniformVariables(CubismShaderSet* shaderSet, CubismClippingContext_OpenGLES2* contextBuffer) +{ + const csmInt32 channelIndex = contextBuffer->_layoutChannelIndex; + CubismRenderer::CubismTextureColor* colorChannel = contextBuffer->GetClippingManager()->GetChannelFlagAsColor(channelIndex); + glUniform4f(shaderSet->UnifromChannelFlagLocation, colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); +} + }}}} //------------ LIVE2D NAMESPACE ------------ diff --git a/src/Rendering/OpenGL/CubismShader_OpenGLES2.hpp b/src/Rendering/OpenGL/CubismShader_OpenGLES2.hpp index aa6abbc..025ba93 100644 --- a/src/Rendering/OpenGL/CubismShader_OpenGLES2.hpp +++ b/src/Rendering/OpenGL/CubismShader_OpenGLES2.hpp @@ -38,6 +38,7 @@ namespace Live2D { namespace Cubism { namespace Framework { namespace Rendering { class CubismRenderer_OpenGLES2; +class CubismClippingContext_OpenGLES2; /** * @brief OpenGLES2用のシェーダプログラムを生成・破棄するクラス
@@ -159,6 +160,47 @@ class CubismShader_OpenGLES2 */ csmBool ValidateProgram(GLuint shaderProgram); + /** + * @brief 必要な頂点属性を設定する + * + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画対象のメッシュのインデックス + * @param[in] shaderSet -> シェーダープログラムのセット + */ + void SetVertexAttributes(const CubismModel& model, const csmInt32 index, CubismShaderSet* shaderSet); + + /** + * @brief テクスチャの設定を行う + * + * @param[in] renderer -> レンダラー + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画対象のメッシュのインデックス + * @param[in] shaderSet -> シェーダープログラムのセット + */ + void SetupTexture(CubismRenderer_OpenGLES2* renderer, const CubismModel& model, const csmInt32 index, CubismShaderSet* shaderSet); + + /** + * @brief 色関連のユニフォーム変数の設定を行う + * + * @param[in] renderer -> レンダラー + * @param[in] model -> 描画対象のモデル + * @param[in] index -> 描画対象のメッシュのインデックス + * @param[in] shaderSet -> シェーダープログラムのセット + * @param[in] baseColor -> ベースカラー + * @param[in] multiplyColor -> 乗算カラー + * @param[in] screenColor -> スクリーンカラー + */ + void SetColorUniformVariables(CubismRenderer_OpenGLES2* renderer, const CubismModel& model, const csmInt32 index, CubismShaderSet* shaderSet, + CubismRenderer::CubismTextureColor& baseColor, CubismRenderer::CubismTextureColor& multiplyColor, CubismRenderer::CubismTextureColor& screenColor); + + /** + * @brief カラーチャンネル関連のユニフォーム変数の設定を行う + * + * @param[in] shaderSet -> シェーダープログラムのセット + * @param[in] contextBuffer -> 描画コンテクスト + */ + void SetColorChannelUniformVariables(CubismShaderSet* shaderSet, CubismClippingContext_OpenGLES2* contextBuffer); + #ifdef CSM_TARGET_ANDROID_ES2 public: /** diff --git a/src/Rendering/Vulkan/CubismRenderer_Vulkan.cpp b/src/Rendering/Vulkan/CubismRenderer_Vulkan.cpp index 51cde41..ae3dbdc 100644 --- a/src/Rendering/Vulkan/CubismRenderer_Vulkan.cpp +++ b/src/Rendering/Vulkan/CubismRenderer_Vulkan.cpp @@ -543,7 +543,6 @@ CubismRenderer_Vulkan::CubismRenderer_Vulkan() : , _clippingManager(NULL) , _clippingContextBufferForMask(NULL) , _clippingContextBufferForDraw(NULL) - , _ubo() , _descriptorPool(VK_NULL_HANDLE) , _descriptorSetLayout(VK_NULL_HANDLE) , _clearColor() @@ -1050,6 +1049,7 @@ void CubismRenderer_Vulkan::UpdateDescriptorSet(Descriptor& descriptor, csmUint3 void CubismRenderer_Vulkan::ExecuteDrawForDraw(const CubismModel& model, const csmInt32 index, VkCommandBuffer& cmdBuffer) { + // パイプラインレイアウト設定用のインデックスを取得 csmUint32 blendIndex = 0; csmUint32 shaderIndex = 0; const csmBool masked = GetClippingContextBufferForDraw() != NULL; // この描画オブジェクトはマスク対象か @@ -1075,93 +1075,91 @@ void CubismRenderer_Vulkan::ExecuteDrawForDraw(const CubismModel& model, const c } Descriptor &descriptor = _descriptorSets[index]; + ModelUBO ubo; if (masked) { - CubismMatrix44 mvp = GetClippingContextBufferForDraw()->_matrixForDraw; - UpdateMatrix(_ubo.clipMatrix, mvp); // テクスチャ座標の変換に使用するのでy軸の向きは反転しない - const csmInt32 channelIndex = GetClippingContextBufferForDraw()->_layoutChannelIndex; - CubismTextureColor *colorChannel = GetClippingContextBufferForDraw()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - UpdateColor(_ubo.channelFlag, colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); - } + // クリッピング用行列の設定 + UpdateMatrix(ubo.clipMatrix, GetClippingContextBufferForDraw()->_matrixForDraw); // テクスチャ座標の変換に使用するのでy軸の向きは反転しない - CubismMatrix44 mvp = GetMvpMatrix(); - CubismTextureColor baseColor = GetModelColor(); - baseColor.A *= model.GetDrawableOpacity(index); - if (IsPremultipliedAlpha()) - { - baseColor.R *= baseColor.A; - baseColor.G *= baseColor.A; - baseColor.B *= baseColor.A; + // カラーチャンネルの設定 + SetColorChannel(ubo, GetClippingContextBufferForDraw()); } + + // MVP行列の設定 + UpdateMatrix(ubo.projectionMatrix, GetMvpMatrix()); + + // 色定数バッファの設定 + CubismTextureColor baseColor = GetModelColorWithOpacity(model.GetDrawableOpacity(index)); CubismTextureColor multiplyColor = model.GetMultiplyColor(index); CubismTextureColor screenColor = model.GetScreenColor(index); - UpdateMatrix(_ubo.projectionMatrix, mvp); - UpdateColor(_ubo.baseColor, baseColor.R, baseColor.G, baseColor.B, baseColor.A); - UpdateColor(_ubo.multiplyColor, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); - UpdateColor(_ubo.screenColor, screenColor.R, screenColor.G, screenColor.B, screenColor.A); - descriptor.uniformBuffer.MemCpy(&_ubo, sizeof(ModelUBO)); + SetColorUniformBuffer(ubo, baseColor, multiplyColor, screenColor); - vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - CubismPipeline_Vulkan::GetInstance()->GetPipeline(shaderIndex, blendIndex)); + // ディスクリプタにユニフォームバッファをコピー + descriptor.uniformBuffer.MemCpy(&ubo, sizeof(ModelUBO)); - VkBuffer vertexBuffers[] = {_vertexBuffers[index].GetBuffer()}; - VkDeviceSize offsets[] = {0}; - vkCmdBindVertexBuffers(cmdBuffer, 0, 1, vertexBuffers, offsets); - vkCmdBindIndexBuffer(cmdBuffer, _indexBuffers[index].GetBuffer(), 0, VK_INDEX_TYPE_UINT16); + // 頂点バッファの設定 + BindVertexAndIndexBuffers(index, cmdBuffer); + // テクスチャインデックス取得 csmInt32 textureIndex = model.GetDrawableTextureIndex(index); - if (masked) - { - UpdateDescriptorSet(descriptor, textureIndex, true); - vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - CubismPipeline_Vulkan::GetInstance()->GetPipelineLayout(shaderIndex, blendIndex), 0, - 1, - &_descriptorSets[index].descriptorSetMasked, 0, - nullptr); - } - else - { - UpdateDescriptorSet(descriptor, textureIndex, false); - vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - CubismPipeline_Vulkan::GetInstance()->GetPipelineLayout(shaderIndex, blendIndex), 0, - 1, - &_descriptorSets[index].descriptorSet, 0, - nullptr); - } + // ディスクリプタセットのバインド + UpdateDescriptorSet(descriptor, textureIndex, masked); + VkDescriptorSet* descriptorSet = (masked ? &_descriptorSets[index].descriptorSetMasked + : &_descriptorSets[index].descriptorSet); + vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + CubismPipeline_Vulkan::GetInstance()->GetPipelineLayout(shaderIndex, blendIndex), 0, 1, + descriptorSet, 0, nullptr); + + // パイプラインのバインド + vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + CubismPipeline_Vulkan::GetInstance()->GetPipeline(shaderIndex, blendIndex)); + + // 描画 vkCmdDrawIndexed(cmdBuffer, model.GetDrawableVertexIndexCount(index), 1, 0, 0, 0); } void CubismRenderer_Vulkan::ExecuteDrawForMask(const CubismModel& model, const csmInt32 index, VkCommandBuffer& cmdBuffer) { - const csmInt32 channelIndex = GetClippingContextBufferForMask()->_layoutChannelIndex; - CubismTextureColor *colorChannel = GetClippingContextBufferForMask()->GetClippingManager()->GetChannelFlagAsColor(channelIndex); - csmRectF *rect = GetClippingContextBufferForMask()->_layoutBounds; - UpdateMatrix(_ubo.clipMatrix, GetClippingContextBufferForMask()->_matrixForMask); - UpdateColor(_ubo.baseColor, rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, - rect->GetBottom() * 2.0f - 1.0f); + csmUint32 shaderIndex = ShaderNames_SetupMask; + csmUint32 blendIndex = Blend_Mask; + Descriptor &descriptor = _descriptorSets[index]; + ModelUBO ubo; + + // クリッピング用行列の設定 + UpdateMatrix(ubo.clipMatrix, GetClippingContextBufferForMask()->_matrixForMask); + + // カラーチャンネルの設定 + SetColorChannel(ubo, GetClippingContextBufferForMask()); + + // 色定数バッファの設定 + csmRectF *rect = GetClippingContextBufferForMask()->_layoutBounds; + CubismTextureColor baseColor = {rect->X * 2.0f - 1.0f, rect->Y * 2.0f - 1.0f, rect->GetRight() * 2.0f - 1.0f, rect->GetBottom() * 2.0f - 1.0f}; CubismTextureColor multiplyColor = model.GetMultiplyColor(index); CubismTextureColor screenColor = model.GetScreenColor(index); - UpdateColor(_ubo.multiplyColor, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); - UpdateColor(_ubo.screenColor, screenColor.R, screenColor.G, screenColor.B, screenColor.A); - UpdateColor(_ubo.channelFlag, colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); - Descriptor &descriptor = _descriptorSets[index]; - descriptor.uniformBuffer.MemCpy(&_ubo, sizeof(ModelUBO)); + SetColorUniformBuffer(ubo, baseColor, multiplyColor, screenColor); + + // ディスクリプタにユニフォームバッファをコピー + descriptor.uniformBuffer.MemCpy(&ubo, sizeof(ModelUBO)); + + // 頂点バッファの設定 + BindVertexAndIndexBuffers(index, cmdBuffer); + + // テクスチャインデックス取得 csmInt32 textureIndex = model.GetDrawableTextureIndex(index); - UpdateDescriptorSet(descriptor, textureIndex, false); - csmUint32 shaderIndex = ShaderNames_SetupMask; - csmUint32 blendIndex = Blend_Mask; - vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - CubismPipeline_Vulkan::GetInstance()->GetPipeline(shaderIndex, blendIndex)); - VkBuffer vertexBuffers[] = {_vertexBuffers[index].GetBuffer()}; - VkDeviceSize offsets[] = {0}; - vkCmdBindVertexBuffers(cmdBuffer, 0, 1, vertexBuffers, offsets); - vkCmdBindIndexBuffer(cmdBuffer, _indexBuffers[index].GetBuffer(), 0, VK_INDEX_TYPE_UINT16); + // ディスクリプタセットのバインド + UpdateDescriptorSet(descriptor, textureIndex, false); vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CubismPipeline_Vulkan::GetInstance()->GetPipelineLayout(shaderIndex, blendIndex), 0, 1, &_descriptorSets[index].descriptorSet, 0, nullptr); + + // パイプラインのバインド + vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + CubismPipeline_Vulkan::GetInstance()->GetPipeline(shaderIndex, blendIndex)); + + // 描画 vkCmdDrawIndexed(cmdBuffer, model.GetDrawableVertexIndexCount(index), 1, 0, 0, 0); } @@ -1515,6 +1513,30 @@ CubismOffscreenSurface_Vulkan* CubismRenderer_Vulkan::GetMaskBuffer(csmInt32 ind { return &_offscreenFrameBuffers[index]; } + +void CubismRenderer_Vulkan::SetColorUniformBuffer(ModelUBO& ubo, const CubismTextureColor& baseColor, + const CubismTextureColor& multiplyColor, const CubismTextureColor& screenColor) +{ + UpdateColor(ubo.baseColor, baseColor.R, baseColor.G, baseColor.B, baseColor.A); + UpdateColor(ubo.multiplyColor, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A); + UpdateColor(ubo.screenColor, screenColor.R, screenColor.G, screenColor.B, screenColor.A); +} + +void CubismRenderer_Vulkan::BindVertexAndIndexBuffers(const csmInt32 index, VkCommandBuffer& cmdBuffer) +{ + VkBuffer vertexBuffers[] = {_vertexBuffers[index].GetBuffer()}; + VkDeviceSize offsets[] = {0}; + vkCmdBindVertexBuffers(cmdBuffer, 0, 1, vertexBuffers, offsets); + vkCmdBindIndexBuffer(cmdBuffer, _indexBuffers[index].GetBuffer(), 0, VK_INDEX_TYPE_UINT16); +} + +void CubismRenderer_Vulkan::SetColorChannel(ModelUBO& ubo, CubismClippingContext_Vulkan* contextBuffer) +{ + const csmInt32 channelIndex = contextBuffer->_layoutChannelIndex; + CubismTextureColor *colorChannel = contextBuffer->GetClippingManager()->GetChannelFlagAsColor(channelIndex); + UpdateColor(ubo.channelFlag, colorChannel->R, colorChannel->G, colorChannel->B, colorChannel->A); +} + }}}} //------------ LIVE2D NAMESPACE ------------ diff --git a/src/Rendering/Vulkan/CubismRenderer_Vulkan.hpp b/src/Rendering/Vulkan/CubismRenderer_Vulkan.hpp index 46ef3dc..9b0948e 100644 --- a/src/Rendering/Vulkan/CubismRenderer_Vulkan.hpp +++ b/src/Rendering/Vulkan/CubismRenderer_Vulkan.hpp @@ -586,6 +586,34 @@ class CubismRenderer_Vulkan : public CubismRenderer CubismOffscreenSurface_Vulkan* GetMaskBuffer(csmInt32 index); private: + + /** + * @brief 色定数バッファを設定する + * + * @param[in] ubo -> ユニフォームバッファ + * @param[in] baseColor -> ベースカラー + * @param[in] multiplyColor -> 乗算カラー + * @param[in] screenColor -> スクリーンカラー + */ + void SetColorUniformBuffer(ModelUBO& ubo, const CubismTextureColor& baseColor, + const CubismTextureColor& multiplyColor, const CubismTextureColor& screenColor); + + /** + * @brief 頂点バッファとインデックスバッファをバインドする + * + * @param[in] index -> 描画メッシュのインデックス + * @param[in] commandBuffer -> コマンドバッファ + */ + void BindVertexAndIndexBuffers(const csmInt32 index, VkCommandBuffer& cmdBuffer); + + /** + * @brief 描画に使用するカラーチャンネルを設定 + * + * @param[in] ubo -> ユニフォームバッファ + * @param[in] contextBuffer -> 描画コンテキスト + */ + void SetColorChannel(ModelUBO& ubo, CubismClippingContext_Vulkan* contextBuffer); + PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT; CubismRenderer_Vulkan(const CubismRenderer_Vulkan&); @@ -599,7 +627,6 @@ class CubismRenderer_Vulkan : public CubismRenderer csmVector _vertexBuffers; ///< 頂点バッファ csmVector _stagingBuffers; ///< 頂点バッファを更新する際に使うステージングバッファ csmVector _indexBuffers; ///< インデックスバッファ - ModelUBO _ubo; ///< ユニフォームバッファ VkDescriptorPool _descriptorPool; ///< ディスクリプタプール VkDescriptorSetLayout _descriptorSetLayout; ///< ディスクリプタセットのレイアウト csmVector _descriptorSets; ///< ディスクリプタ管理オブジェクト diff --git a/src/Rendering/Vulkan/Shaders/CMakeLists.txt b/src/Rendering/Vulkan/Shaders/CMakeLists.txt index 147cd1f..154ea34 100644 --- a/src/Rendering/Vulkan/Shaders/CMakeLists.txt +++ b/src/Rendering/Vulkan/Shaders/CMakeLists.txt @@ -10,8 +10,8 @@ foreach(shader ${shader_files}) set(output_dir ${CMAKE_CURRENT_BINARY_DIR}/compiledShaders) string(REGEX REPLACE \\.frag|\\.vert "" output_file ${file_name}) set(output_file ${output_dir}/${output_file}.spv) - set(compiled_shaders ${compiled_shaders} ${output_file}) - set(compiled_shaders ${compiled_shaders} PARENT_SCOPE) + set(compiled_shaders_framework ${compiled_shaders_framework} ${output_file}) + set(compiled_shaders_framework ${compiled_shaders_framework} PARENT_SCOPE) set_source_files_properties(${shader} PROPERTIES HEADER_FILE_ONLY TRUE) add_custom_command( @@ -25,6 +25,6 @@ endforeach() source_group("shaders" FILES ${shader_files}) add_custom_target( FrameworkShaders ALL - DEPENDS ${compiled_shaders} + DEPENDS ${compiled_shaders_framework} SOURCES ${shader_files} )