1. 规范了一些Live2D实例代码的内容
2. 增加了窗口大小随着模型大小变化而变化的功能
This commit is contained in:
+14
-14
@@ -159,43 +159,43 @@ public:
|
|||||||
void Update() const;
|
void Update() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the width of the canvas.
|
* Returns the width of the canvas.<br>
|
||||||
*
|
* 返回画布的像素宽度。
|
||||||
* @return Width of the canvas in pixels
|
* @return Width of the canvas in pixels
|
||||||
*/
|
*/
|
||||||
csmFloat32 GetCanvasWidthPixel() const;
|
csmFloat32 GetCanvasWidthPixel() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the height of the canvas.
|
* Returns the height of the canvas.<br>
|
||||||
*
|
* 返回画布的像素高度。
|
||||||
* @return Height of the canvas in pixels
|
* @return Height of the canvas in pixels
|
||||||
*/
|
*/
|
||||||
csmFloat32 GetCanvasHeightPixel() const;
|
csmFloat32 GetCanvasHeightPixel() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the pixels per unit (PPU).
|
* Returns the pixels per unit (PPU). <br>
|
||||||
*
|
* 返回 PPU(Pixels Per Unit),即 Live2D 坐标系中的 $1.0$ 单位对应多少像素。 (Misaki注解)
|
||||||
* @return Pixels per unit
|
* @return Pixels per unit
|
||||||
*/
|
*/
|
||||||
csmFloat32 GetPixelsPerUnit() const;
|
csmFloat32 GetPixelsPerUnit() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the width of the canvas.
|
* Returns the width of the canvas.
|
||||||
*
|
* 返回画布在 PPU 单位下的宽度(例如 1.0)
|
||||||
* @return Width of the canvas in PPU (pixels per unit)
|
* @return Width of the canvas in PPU (pixels per unit)
|
||||||
*/
|
*/
|
||||||
csmFloat32 GetCanvasWidth() const;
|
csmFloat32 GetCanvasWidth() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the height of the canvas.
|
* Returns the height of the canvas.
|
||||||
*
|
* 返回画布在 PPU 单位下的高度(例如 2.155300)。
|
||||||
* @return Height of the canvas in PPU (pixels per unit)
|
* @return Height of the canvas in PPU (pixels per unit)
|
||||||
*/
|
*/
|
||||||
csmFloat32 GetCanvasHeight() const;
|
csmFloat32 GetCanvasHeight() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of the part.
|
* Returns the index of the part.
|
||||||
*
|
* 根据部件 ID (例如 PartId::HairFront) 获取其在数组中的索引。
|
||||||
* @param partId Part ID
|
* @param partId Part ID
|
||||||
*
|
*
|
||||||
* @return Index of the part
|
* @return Index of the part
|
||||||
@@ -204,7 +204,7 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the part.
|
* Returns the ID of the part.
|
||||||
*
|
* 根据索引获取部件 ID。
|
||||||
* @param partIndex Index of the part
|
* @param partIndex Index of the part
|
||||||
* @return Part ID
|
* @return Part ID
|
||||||
*/
|
*/
|
||||||
@@ -212,21 +212,21 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of parts.
|
* Returns the number of parts.
|
||||||
*
|
* 返回模型中部件的总数。
|
||||||
* @return Number of parts
|
* @return Number of parts
|
||||||
*/
|
*/
|
||||||
csmInt32 GetPartCount() const;
|
csmInt32 GetPartCount() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index of the parent parts for the parts.
|
* Returns the index of the parent parts for the parts.
|
||||||
*
|
* 获取每个部件的父部件索引数组,用于确定绘制顺序或层级关系。
|
||||||
* @return Index of parent parts for the parts.
|
* @return Index of parent parts for the parts.
|
||||||
*/
|
*/
|
||||||
const csmInt32* GetPartParentPartIndices() const;
|
const csmInt32* GetPartParentPartIndices() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the opacity of the part.
|
* Sets the opacity of the part.
|
||||||
*
|
* 设置或获取部件的不透明度(0.0 到 1.0)。常用于实现部件的动态隐藏或显示效果。
|
||||||
* @param partId Part ID
|
* @param partId Part ID
|
||||||
* @param opacity Opacity
|
* @param opacity Opacity
|
||||||
*/
|
*/
|
||||||
@@ -234,7 +234,7 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the opacity of the part.
|
* Sets the opacity of the part.
|
||||||
*
|
* 设置或获取部件的不透明度(0.0 到 1.0)。常用于实现部件的动态隐藏或显示效果。
|
||||||
* @param partIndex Part index
|
* @param partIndex Part index
|
||||||
* @param opacity Part opacity
|
* @param opacity Part opacity
|
||||||
*/
|
*/
|
||||||
|
|||||||
+21
-2
@@ -48,6 +48,25 @@ public:
|
|||||||
*/
|
*/
|
||||||
int getTapBodyMotionCount();
|
int getTapBodyMotionCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取 Live2D 模型的 Canvas 宽度像素 (在 Live2D 坐标系下)
|
||||||
|
* @return Canvas 宽度
|
||||||
|
*/
|
||||||
|
Live2D::Cubism::Framework::csmFloat32 GetModelCanvasWidthPixel() const
|
||||||
|
{
|
||||||
|
// _model 是 CubismModel 的基类指针
|
||||||
|
return _model ? _model->GetCanvasWidthPixel() : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取 Live2D 模型的 Canvas 高度像素 (在 Live2D 坐标系下)
|
||||||
|
* @return Canvas 高度
|
||||||
|
*/
|
||||||
|
Live2D::Cubism::Framework::csmFloat32 GetModelCanvasHeightPixel() const
|
||||||
|
{
|
||||||
|
return _model ? _model->GetCanvasHeightPixel() : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 启动唇形同步并播放指定的 WAV 文件
|
* @brief 启动唇形同步并播放指定的 WAV 文件
|
||||||
* @param filePath WAV 文件的路径(csmString 类型)
|
* @param filePath WAV 文件的路径(csmString 类型)
|
||||||
@@ -64,8 +83,8 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief model3.jsonが置かれたディレクトリとファイルパスからモデルを生成する
|
* @brief model3.jsonが置かれたディレクトリとファイルパスからモデルを生成する \n
|
||||||
*
|
* 从 model3.json 所在的目录和文件路径生成模型
|
||||||
*/
|
*/
|
||||||
void LoadAssets(const Csm::csmChar* dir, const Csm::csmChar* fileName);
|
void LoadAssets(const Csm::csmChar* dir, const Csm::csmChar* fileName);
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -63,7 +63,7 @@ bool LAppDelegate::Initialize(GLCore* window)
|
|||||||
// Windowの生成_
|
// Windowの生成_
|
||||||
//_window = glfwCreateWindow(RenderTargetWidth, RenderTargetHeight, "SAMPLE", NULL, NULL);
|
//_window = glfwCreateWindow(RenderTargetWidth, RenderTargetHeight, "SAMPLE", NULL, NULL);
|
||||||
_window = window; // Misaki 修改
|
_window = window; // Misaki 修改
|
||||||
if (_window == NULL)
|
if (_window == nullptr)
|
||||||
{
|
{
|
||||||
if (DebugLogEnable)
|
if (DebugLogEnable)
|
||||||
{
|
{
|
||||||
@@ -217,7 +217,7 @@ void LAppDelegate::update()
|
|||||||
|
|
||||||
LAppDelegate::LAppDelegate():
|
LAppDelegate::LAppDelegate():
|
||||||
_cubismOption(),
|
_cubismOption(),
|
||||||
_window(NULL),
|
_window(nullptr),
|
||||||
_captured(false),
|
_captured(false),
|
||||||
_mouseX(0.0f),
|
_mouseX(0.0f),
|
||||||
_mouseY(0.0f),
|
_mouseY(0.0f),
|
||||||
@@ -259,7 +259,7 @@ void LAppDelegate::InitializeCubism()
|
|||||||
|
|
||||||
void LAppDelegate::OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
|
void LAppDelegate::OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
|
||||||
{
|
{
|
||||||
if (_view == NULL)
|
if (_view == nullptr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -292,7 +292,7 @@ void LAppDelegate::OnMouseCallBack(GLFWwindow* window, double x, double y)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_view == NULL)
|
if (_view == nullptr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -313,7 +313,7 @@ GLuint LAppDelegate::CreateShader()
|
|||||||
" gl_Position = vec4(position, 1.0);"
|
" gl_Position = vec4(position, 1.0);"
|
||||||
" vuv = uv;"
|
" vuv = uv;"
|
||||||
"}";
|
"}";
|
||||||
glShaderSource(vertexShaderId, 1, &vertexShader, NULL);
|
glShaderSource(vertexShaderId, 1, &vertexShader, nullptr);
|
||||||
glCompileShader(vertexShaderId);
|
glCompileShader(vertexShaderId);
|
||||||
if(!CheckShader(vertexShaderId))
|
if(!CheckShader(vertexShaderId))
|
||||||
{
|
{
|
||||||
@@ -330,7 +330,7 @@ GLuint LAppDelegate::CreateShader()
|
|||||||
"void main(void){"
|
"void main(void){"
|
||||||
" gl_FragColor = texture2D(texture, vuv) * baseColor;"
|
" gl_FragColor = texture2D(texture, vuv) * baseColor;"
|
||||||
"}";
|
"}";
|
||||||
glShaderSource(fragmentShaderId, 1, &fragmentShader, NULL);
|
glShaderSource(fragmentShaderId, 1, &fragmentShader, nullptr);
|
||||||
glCompileShader(fragmentShaderId);
|
glCompileShader(fragmentShaderId);
|
||||||
if (!CheckShader(fragmentShaderId))
|
if (!CheckShader(fragmentShaderId))
|
||||||
{
|
{
|
||||||
|
|||||||
+16
-11
@@ -29,7 +29,7 @@ using namespace LAppDefine;
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
LAppLive2DManager* s_instance = NULL;
|
LAppLive2DManager* s_instance = nullptr;
|
||||||
|
|
||||||
void FinishedMotion(ACubismMotion* self)
|
void FinishedMotion(ACubismMotion* self)
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ namespace {
|
|||||||
|
|
||||||
LAppLive2DManager* LAppLive2DManager::GetInstance()
|
LAppLive2DManager* LAppLive2DManager::GetInstance()
|
||||||
{
|
{
|
||||||
if (s_instance == NULL)
|
if (s_instance == nullptr)
|
||||||
{
|
{
|
||||||
s_instance = new LAppLive2DManager();
|
s_instance = new LAppLive2DManager();
|
||||||
}
|
}
|
||||||
@@ -55,22 +55,22 @@ LAppLive2DManager* LAppLive2DManager::GetInstance()
|
|||||||
|
|
||||||
void LAppLive2DManager::ReleaseInstance()
|
void LAppLive2DManager::ReleaseInstance()
|
||||||
{
|
{
|
||||||
if (s_instance != NULL)
|
if (s_instance != nullptr)
|
||||||
{
|
{
|
||||||
delete s_instance;
|
delete s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_instance = NULL;
|
s_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LAppLive2DManager::LAppLive2DManager()
|
LAppLive2DManager::LAppLive2DManager()
|
||||||
: _viewMatrix(NULL)
|
: _viewMatrix(nullptr)
|
||||||
, _sceneIndex(0)
|
, _sceneIndex(0)
|
||||||
{
|
{
|
||||||
_viewMatrix = new CubismMatrix44();
|
_viewMatrix = new CubismMatrix44();
|
||||||
//SetUpModel();
|
//SetUpModel();
|
||||||
// Resources/Haru/ Haru.model3.json
|
// Resources/Haru/ Haru.model3.json
|
||||||
LoadModelFromPath("Resources/Live2DModels/KITU17/", "KITU17.model3.json");
|
LoadModelFromPath("Resources/Live2DModels/KITU17/", "KITU17.model3.json"); // 默认加载的模型
|
||||||
//ChangeScene(_sceneIndex);
|
//ChangeScene(_sceneIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ void LAppLive2DManager::SetUpModel()
|
|||||||
if (fs::exists(modelJson))
|
if (fs::exists(modelJson))
|
||||||
_modelDir.PushBack(csmString(dirName.c_str()));
|
_modelDir.PushBack(csmString(dirName.c_str()));
|
||||||
}
|
}
|
||||||
/* 保持与原代码相同的排序 */
|
// 保持与原代码相同的排序
|
||||||
qsort(_modelDir.GetPtr(), _modelDir.GetSize(), sizeof(csmString), CompareCsmString);
|
qsort(_modelDir.GetPtr(), _modelDir.GetSize(), sizeof(csmString), CompareCsmString);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -162,7 +162,7 @@ LAppModel* LAppLive2DManager::GetModel(csmUint32 no) const
|
|||||||
return _models[no];
|
return _models[no];
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -229,7 +229,7 @@ void LAppLive2DManager::OnUpdate() const
|
|||||||
CubismMatrix44 projection;
|
CubismMatrix44 projection;
|
||||||
LAppModel* model = GetModel(i);
|
LAppModel* model = GetModel(i);
|
||||||
|
|
||||||
if (model->GetModel() == NULL)
|
if (model->GetModel() == nullptr)
|
||||||
{
|
{
|
||||||
LAppPal::PrintLogLn("Failed to model->GetModel().");
|
LAppPal::PrintLogLn("Failed to model->GetModel().");
|
||||||
continue;
|
continue;
|
||||||
@@ -247,7 +247,7 @@ void LAppLive2DManager::OnUpdate() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 必要があればここで乗算
|
// 必要があればここで乗算
|
||||||
if (_viewMatrix != NULL)
|
if (_viewMatrix != nullptr)
|
||||||
{
|
{
|
||||||
projection.MultiplyByMatrix(_viewMatrix);
|
projection.MultiplyByMatrix(_viewMatrix);
|
||||||
}
|
}
|
||||||
@@ -262,7 +262,7 @@ void LAppLive2DManager::OnUpdate() const
|
|||||||
LAppDelegate::GetInstance()->GetView()->PostModelDraw(*model);
|
LAppDelegate::GetInstance()->GetView()->PostModelDraw(*model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#include <AppContext.h>
|
||||||
void LAppLive2DManager::LoadModelFromPath(const std::string& modelPath, const std::string& fileName)
|
void LAppLive2DManager::LoadModelFromPath(const std::string& modelPath, const std::string& fileName)
|
||||||
{
|
{
|
||||||
csmString modelPathStr(modelPath.c_str());
|
csmString modelPathStr(modelPath.c_str());
|
||||||
@@ -272,6 +272,11 @@ void LAppLive2DManager::LoadModelFromPath(const std::string& modelPath, const st
|
|||||||
_models.PushBack(new LAppModel()); // 这样在加载的时候都使用的models[0]这一个位置,自行实现模型选择器要注意注意
|
_models.PushBack(new LAppModel()); // 这样在加载的时候都使用的models[0]这一个位置,自行实现模型选择器要注意注意
|
||||||
_models[0]->LoadAssets(modelPathStr.GetRawString(), modelJsonName.GetRawString());
|
_models[0]->LoadAssets(modelPathStr.GetRawString(), modelJsonName.GetRawString());
|
||||||
|
|
||||||
|
// 加载完后根据模型大小来重新设置当前窗口大小
|
||||||
|
const int width = static_cast<int>(_models[0]->GetModel()->GetCanvasWidthPixel() / 15.0);
|
||||||
|
const int height = static_cast<int>(_models[0]->GetModel()->GetCanvasHeightPixel() / 15.0);
|
||||||
|
AppContext::GetGLCore()->setWindowSize(width, height);
|
||||||
|
LAppPal::PrintLogLn("[APP]窗口尺寸重新设置为: W: %d H: %d", width, height);
|
||||||
/*
|
/*
|
||||||
* 提供一个半透明表示模型的示例。
|
* 提供一个半透明表示模型的示例。
|
||||||
* 如果定义了USE_RENDER_TARGET或USE_MODEL_RENDER_TARGET,
|
* 如果定义了USE_RENDER_TARGET或USE_MODEL_RENDER_TARGET,
|
||||||
|
|||||||
+18
-18
@@ -47,7 +47,7 @@ namespace {
|
|||||||
|
|
||||||
LAppModel::LAppModel()
|
LAppModel::LAppModel()
|
||||||
: CubismUserModel()
|
: CubismUserModel()
|
||||||
, _modelSetting(NULL)
|
, _modelSetting(nullptr)
|
||||||
, _userTimeSeconds(0.0f)
|
, _userTimeSeconds(0.0f)
|
||||||
{
|
{
|
||||||
if (MocConsistencyValidationEnable)
|
if (MocConsistencyValidationEnable)
|
||||||
@@ -101,7 +101,7 @@ void LAppModel::LoadAssets(const csmChar* dir, const csmChar* fileName)
|
|||||||
|
|
||||||
SetupModel(setting);
|
SetupModel(setting);
|
||||||
|
|
||||||
if (_model == NULL)
|
if (_model == nullptr)
|
||||||
{
|
{
|
||||||
LAppPal::PrintLogLn("Failed to LoadAssets().");
|
LAppPal::PrintLogLn("Failed to LoadAssets().");
|
||||||
return;
|
return;
|
||||||
@@ -123,7 +123,7 @@ void LAppModel::SetupModel(ICubismModelSetting* setting)
|
|||||||
csmSizeInt size;
|
csmSizeInt size;
|
||||||
|
|
||||||
//Cubism Model
|
//Cubism Model
|
||||||
if (strcmp(_modelSetting->GetModelFileName(), "") != 0)
|
if (strcmp(_modelSetting->GetModelFileName(), "") != 0) // 如果模型文件名不为空
|
||||||
{
|
{
|
||||||
csmString path = _modelSetting->GetModelFileName();
|
csmString path = _modelSetting->GetModelFileName();
|
||||||
path = _modelHomeDir + path;
|
path = _modelHomeDir + path;
|
||||||
@@ -153,10 +153,10 @@ void LAppModel::SetupModel(ICubismModelSetting* setting)
|
|||||||
|
|
||||||
if (motion)
|
if (motion)
|
||||||
{
|
{
|
||||||
if (_expressions[name] != NULL)
|
if (_expressions[name] != nullptr)
|
||||||
{
|
{
|
||||||
ACubismMotion::Delete(_expressions[name]);
|
ACubismMotion::Delete(_expressions[name]);
|
||||||
_expressions[name] = NULL;
|
_expressions[name] = nullptr;
|
||||||
}
|
}
|
||||||
_expressions[name] = motion;
|
_expressions[name] = motion;
|
||||||
}
|
}
|
||||||
@@ -240,7 +240,7 @@ void LAppModel::SetupModel(ICubismModelSetting* setting)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_modelSetting == NULL || _modelMatrix == NULL)
|
if (_modelSetting == nullptr || _modelMatrix == nullptr)
|
||||||
{
|
{
|
||||||
LAppPal::PrintLogLn("Failed to SetupModel().");
|
LAppPal::PrintLogLn("Failed to SetupModel().");
|
||||||
return;
|
return;
|
||||||
@@ -258,11 +258,11 @@ void LAppModel::SetupModel(ICubismModelSetting* setting)
|
|||||||
const csmChar* group = _modelSetting->GetMotionGroupName(i);
|
const csmChar* group = _modelSetting->GetMotionGroupName(i);
|
||||||
PreloadMotionGroup(group);
|
PreloadMotionGroup(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
_motionManager->StopAllMotions();
|
_motionManager->StopAllMotions();
|
||||||
|
|
||||||
_updating = false;
|
_updating = false;
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
|
LAppPal::PrintLogLn("[APP]当前模型像素大小: H: %lf W: %lf", GetModelCanvasHeightPixel(), GetModelCanvasWidthPixel());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LAppModel::PreloadMotionGroup(const csmChar* group)
|
void LAppModel::PreloadMotionGroup(const csmChar* group)
|
||||||
@@ -301,7 +301,7 @@ void LAppModel::PreloadMotionGroup(const csmChar* group)
|
|||||||
}
|
}
|
||||||
tmpMotion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
|
tmpMotion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
|
||||||
|
|
||||||
if (_motions[name] != NULL)
|
if (_motions[name] != nullptr)
|
||||||
{
|
{
|
||||||
ACubismMotion::Delete(_motions[name]);
|
ACubismMotion::Delete(_motions[name]);
|
||||||
}
|
}
|
||||||
@@ -389,14 +389,14 @@ void LAppModel::Update()
|
|||||||
// まばたき 眨眼
|
// まばたき 眨眼
|
||||||
if (!motionUpdated)
|
if (!motionUpdated)
|
||||||
{
|
{
|
||||||
if (_eyeBlink != NULL)
|
if (_eyeBlink != nullptr)
|
||||||
{
|
{
|
||||||
// メインモーションの更新がないとき 当主动作没有更新时
|
// メインモーションの更新がないとき 当主动作没有更新时
|
||||||
_eyeBlink->UpdateParameters(_model, deltaTimeSeconds); // 目パチ
|
_eyeBlink->UpdateParameters(_model, deltaTimeSeconds); // 目パチ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_expressionManager != NULL)
|
if (_expressionManager != nullptr)
|
||||||
{
|
{
|
||||||
_expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
|
_expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
|
||||||
}
|
}
|
||||||
@@ -415,13 +415,13 @@ void LAppModel::Update()
|
|||||||
_model->AddParameterValue(_idParamEyeBallY, _dragY);
|
_model->AddParameterValue(_idParamEyeBallY, _dragY);
|
||||||
|
|
||||||
// 呼吸など
|
// 呼吸など
|
||||||
if (_breath != NULL)
|
if (_breath != nullptr)
|
||||||
{
|
{
|
||||||
_breath->UpdateParameters(_model, deltaTimeSeconds);
|
_breath->UpdateParameters(_model, deltaTimeSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 物理演算の設定
|
// 物理演算の設定
|
||||||
if (_physics != NULL)
|
if (_physics != nullptr)
|
||||||
{
|
{
|
||||||
_physics->Evaluate(_model, deltaTimeSeconds);
|
_physics->Evaluate(_model, deltaTimeSeconds);
|
||||||
}
|
}
|
||||||
@@ -455,7 +455,7 @@ void LAppModel::Update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ポーズの設定
|
// ポーズの設定
|
||||||
if (_pose != NULL)
|
if (_pose != nullptr)
|
||||||
{
|
{
|
||||||
_pose->UpdateParameters(_model, deltaTimeSeconds);
|
_pose->UpdateParameters(_model, deltaTimeSeconds);
|
||||||
}
|
}
|
||||||
@@ -516,7 +516,7 @@ CubismMotionQueueEntryHandle LAppModel::StartMotion(const csmChar* group, csmInt
|
|||||||
CubismMotion* motion = static_cast<CubismMotion*>(_motions[name.GetRawString()]);
|
CubismMotion* motion = static_cast<CubismMotion*>(_motions[name.GetRawString()]);
|
||||||
csmBool autoDelete = false;
|
csmBool autoDelete = false;
|
||||||
|
|
||||||
if (motion == NULL)
|
if (motion == nullptr)
|
||||||
{
|
{
|
||||||
csmString path = fileName;
|
csmString path = fileName;
|
||||||
path = _modelHomeDir + path;
|
path = _modelHomeDir + path;
|
||||||
@@ -524,7 +524,7 @@ CubismMotionQueueEntryHandle LAppModel::StartMotion(const csmChar* group, csmInt
|
|||||||
csmByte* buffer;
|
csmByte* buffer;
|
||||||
csmSizeInt size;
|
csmSizeInt size;
|
||||||
buffer = CreateBuffer(path.GetRawString(), &size);
|
buffer = CreateBuffer(path.GetRawString(), &size);
|
||||||
motion = static_cast<CubismMotion*>(LoadMotion(buffer, size, NULL, onFinishedMotionHandler));
|
motion = static_cast<CubismMotion*>(LoadMotion(buffer, size, nullptr, onFinishedMotionHandler));
|
||||||
|
|
||||||
if (motion)
|
if (motion)
|
||||||
{
|
{
|
||||||
@@ -618,7 +618,7 @@ int LAppModel::getTapBodyMotionCount()
|
|||||||
|
|
||||||
void LAppModel::DoDraw()
|
void LAppModel::DoDraw()
|
||||||
{
|
{
|
||||||
if (_model == NULL)
|
if (_model == nullptr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -628,7 +628,7 @@ void LAppModel::DoDraw()
|
|||||||
|
|
||||||
void LAppModel::Draw(CubismMatrix44& matrix)
|
void LAppModel::Draw(CubismMatrix44& matrix)
|
||||||
{
|
{
|
||||||
if (_model == NULL)
|
if (_model == nullptr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -667,7 +667,7 @@ void LAppModel::SetExpression(const csmChar* expressionID)
|
|||||||
LAppPal::PrintLogLn("[APP]expression: [%s]", expressionID);
|
LAppPal::PrintLogLn("[APP]expression: [%s]", expressionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (motion != NULL)
|
if (motion != nullptr)
|
||||||
{
|
{
|
||||||
_expressionManager->StartMotionPriority(motion, false, PriorityForce);
|
_expressionManager->StartMotionPriority(motion, false, PriorityForce);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -25,7 +25,7 @@ LAppView::LAppView():
|
|||||||
//_back(NULL),
|
//_back(NULL),
|
||||||
//_gear(NULL),
|
//_gear(NULL),
|
||||||
//_power(NULL),
|
//_power(NULL),
|
||||||
_renderSprite(NULL),
|
_renderSprite(nullptr),
|
||||||
_renderTarget(SelectTarget_None)
|
_renderTarget(SelectTarget_None)
|
||||||
{
|
{
|
||||||
_clearColor[0] = 1.0f;
|
_clearColor[0] = 1.0f;
|
||||||
@@ -268,7 +268,7 @@ float LAppView::TransformScreenY(float deviceY) const
|
|||||||
void LAppView::PreModelDraw(LAppModel& refModel)
|
void LAppView::PreModelDraw(LAppModel& refModel)
|
||||||
{
|
{
|
||||||
// 別のレンダリングターゲットへ向けて描画する場合の使用するフレームバッファ
|
// 別のレンダリングターゲットへ向けて描画する場合の使用するフレームバッファ
|
||||||
Csm::Rendering::CubismOffscreenSurface_OpenGLES2* useTarget = NULL;
|
Csm::Rendering::CubismOffscreenSurface_OpenGLES2* useTarget = nullptr;
|
||||||
|
|
||||||
if (_renderTarget != SelectTarget_None)
|
if (_renderTarget != SelectTarget_None)
|
||||||
{// 別のレンダリングターゲットへ向けて描画する場合
|
{// 別のレンダリングターゲットへ向けて描画する場合
|
||||||
@@ -299,7 +299,7 @@ void LAppView::PreModelDraw(LAppModel& refModel)
|
|||||||
void LAppView::PostModelDraw(LAppModel& refModel)
|
void LAppView::PostModelDraw(LAppModel& refModel)
|
||||||
{
|
{
|
||||||
// 別のレンダリングターゲットへ向けて描画する場合の使用するフレームバッファ
|
// 別のレンダリングターゲットへ向けて描画する場合の使用するフレームバッファ
|
||||||
Csm::Rendering::CubismOffscreenSurface_OpenGLES2* useTarget = NULL;
|
Csm::Rendering::CubismOffscreenSurface_OpenGLES2* useTarget = nullptr;
|
||||||
|
|
||||||
if (_renderTarget != SelectTarget_None)
|
if (_renderTarget != SelectTarget_None)
|
||||||
{// 別のレンダリングターゲットへ向けて描画する場合
|
{// 別のレンダリングターゲットへ向けて描画する場合
|
||||||
|
|||||||
@@ -8,11 +8,13 @@
|
|||||||
(本项目由Yosuga[Qt5] 发展更新而来,项目架构与代码都有所不同,最显著的特点是本项目支持多平台)
|
(本项目由Yosuga[Qt5] 发展更新而来,项目架构与代码都有所不同,最显著的特点是本项目支持多平台)
|
||||||
环境为:
|
环境为:
|
||||||
|
|
||||||
cmake version 3.31.3
|
- cmake version 3.5
|
||||||
|
|
||||||
Qt6.6.3
|
- C++ 20
|
||||||
|
|
||||||
IDE: Clion
|
- Qt6.6.3
|
||||||
|
|
||||||
|
- IDE: Clion
|
||||||
|
|
||||||
如何构建本项目:
|
如何构建本项目:
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ int main(int argc, char *argv[])
|
|||||||
// 设置日志过滤规则,将这个特定分类的警告级别设置为“关闭”
|
// 设置日志过滤规则,将这个特定分类的警告级别设置为“关闭”
|
||||||
QLoggingCategory::setFilterRules("qt.multimedia.ffmpeg.libsymbolsresolver.warning=false");
|
QLoggingCategory::setFilterRules("qt.multimedia.ffmpeg.libsymbolsresolver.warning=false");
|
||||||
#endif
|
#endif
|
||||||
GLCore w(360, 480);
|
GLCore w(360, 480); // 创建默认的窗口
|
||||||
w.show();
|
w.show();
|
||||||
return a.exec();
|
return QApplication::exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <QOpenGLWidget>
|
#include <QOpenGLWidget>
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
class GLCore : public QOpenGLWidget
|
class GLCore final : public QOpenGLWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -19,15 +19,18 @@ public:
|
|||||||
// 删除移动运算符
|
// 删除移动运算符
|
||||||
GLCore& operator=(GLCore&&) = delete;
|
GLCore& operator=(GLCore&&) = delete;
|
||||||
|
|
||||||
~GLCore();
|
~GLCore() override;
|
||||||
|
|
||||||
// 帧率控制
|
// 帧率控制
|
||||||
void setFrameRate(double fps);
|
void setFrameRate(double fps);
|
||||||
double getFrameRate();
|
[[nodiscard]] double getFrameRate() const;
|
||||||
// 帧率表
|
// 帧率表
|
||||||
static QMap<QString, double> getFrameRateMap();
|
static QMap<QString, double> getFrameRateMap();
|
||||||
static QStringList getFrameRateList();
|
static QStringList getFrameRateList();
|
||||||
|
|
||||||
|
// 安全地设置窗口的实际像素尺寸
|
||||||
|
void setWindowSize(int w, int h);
|
||||||
|
|
||||||
void mouseMoveEvent(QMouseEvent* event) override;
|
void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
void mousePressEvent(QMouseEvent* event) override;
|
void mousePressEvent(QMouseEvent* event) override;
|
||||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
|
|||||||
+26
-11
@@ -61,7 +61,7 @@ GLCore::GLCore(int w, int h, QWidget *parent)
|
|||||||
TextRenderer::getInstance()->setGravity(600.0f); // 更快的下坠速度
|
TextRenderer::getInstance()->setGravity(600.0f); // 更快的下坠速度
|
||||||
TextRenderer::getInstance()->setDampFactor(0.85f); // 更强的弹性效果
|
TextRenderer::getInstance()->setDampFactor(0.85f); // 更强的弹性效果
|
||||||
|
|
||||||
this->setWindowFlag(Qt::FramelessWindowHint); // 设置无边框窗口
|
// this->setWindowFlag(Qt::FramelessWindowHint); // 设置无边框窗口
|
||||||
this->setWindowFlag(Qt::WindowStaysOnTopHint); // 设置窗口始终在顶部
|
this->setWindowFlag(Qt::WindowStaysOnTopHint); // 设置窗口始终在顶部
|
||||||
this->setWindowFlag(Qt::Tool); // 隐藏应用程序图标
|
this->setWindowFlag(Qt::Tool); // 隐藏应用程序图标
|
||||||
this->setAttribute(Qt::WA_TranslucentBackground); // 设置窗口背景透明
|
this->setAttribute(Qt::WA_TranslucentBackground); // 设置窗口背景透明
|
||||||
@@ -75,7 +75,7 @@ GLCore::GLCore(int w, int h, QWidget *parent)
|
|||||||
frameTimer->start(static_cast<int>((1.0 / frameRate) * 1000)); // 使用成员变量计算间隔
|
frameTimer->start(static_cast<int>((1.0 / frameRate) * 1000)); // 使用成员变量计算间隔
|
||||||
|
|
||||||
|
|
||||||
// 启用鼠标跟踪,不启用鼠标按下才会回调mouseMoveEvent函数
|
// 启用鼠标跟踪,不启用的话鼠标按下才会回调mouseMoveEvent函数
|
||||||
this->setMouseTracking(true);
|
this->setMouseTracking(true);
|
||||||
|
|
||||||
// 连接一些必要的信号与槽
|
// 连接一些必要的信号与槽
|
||||||
@@ -114,7 +114,7 @@ void GLCore::setFrameRate(double fps)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前帧率
|
// 获取当前帧率
|
||||||
double GLCore::getFrameRate()
|
double GLCore::getFrameRate() const
|
||||||
{
|
{
|
||||||
return frameRate;
|
return frameRate;
|
||||||
}
|
}
|
||||||
@@ -163,8 +163,8 @@ void GLCore::closeEvent(QCloseEvent* event)
|
|||||||
void GLCore::mouseMoveEvent(QMouseEvent* event)
|
void GLCore::mouseMoveEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
LAppDelegate::GetInstance()->GetView()->OnTouchesMoved(
|
LAppDelegate::GetInstance()->GetView()->OnTouchesMoved(
|
||||||
event->position().x(),
|
static_cast<float>(event->position().x()),
|
||||||
event->position().y()
|
static_cast<float>(event->position().y())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isLeftPressed) {
|
if (isLeftPressed) {
|
||||||
@@ -176,8 +176,8 @@ void GLCore::mouseMoveEvent(QMouseEvent* event)
|
|||||||
void GLCore::mousePressEvent(QMouseEvent* event)
|
void GLCore::mousePressEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
LAppDelegate::GetInstance()->GetView()->OnTouchesBegan(
|
LAppDelegate::GetInstance()->GetView()->OnTouchesBegan(
|
||||||
event->position().x(),
|
static_cast<float>(event->position().x()),
|
||||||
event->position().y()
|
static_cast<float>(event->position().y())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
@@ -198,8 +198,8 @@ void GLCore::mousePressEvent(QMouseEvent* event)
|
|||||||
void GLCore::mouseReleaseEvent(QMouseEvent* event)
|
void GLCore::mouseReleaseEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
LAppDelegate::GetInstance()->GetView()->OnTouchesEnded(
|
LAppDelegate::GetInstance()->GetView()->OnTouchesEnded(
|
||||||
event->position().x(),
|
static_cast<float>(event->position().x()),
|
||||||
event->position().y()
|
static_cast<float>(event->position().y())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
@@ -218,16 +218,31 @@ void GLCore::initializeGL()
|
|||||||
|
|
||||||
void GLCore::paintGL()
|
void GLCore::paintGL()
|
||||||
{
|
{
|
||||||
LAppDelegate::GetInstance()->update();
|
LAppDelegate::GetInstance()->update(); // Live2D画面渲染
|
||||||
// 渲染文本
|
// 渲染文本
|
||||||
TextRenderer::getInstance()->update();
|
TextRenderer::getInstance()->update();
|
||||||
TextRenderer::getInstance()->render();
|
TextRenderer::getInstance()->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCore::resizeGL(int w, int h)
|
void GLCore::resizeGL(const int w, const int h)
|
||||||
{
|
{
|
||||||
// 设置文本渲染器窗口大小
|
// 设置文本渲染器窗口大小
|
||||||
TextRenderer::getInstance()->setWindowSize(w, h);
|
TextRenderer::getInstance()->setWindowSize(w, h);
|
||||||
|
|
||||||
LAppDelegate::GetInstance()->resize(w, h);
|
LAppDelegate::GetInstance()->resize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置窗口大小,并触发 resizeGL 事件
|
||||||
|
void GLCore::setWindowSize(const int w, const int h)
|
||||||
|
{
|
||||||
|
// 检查是否需要更新,避免重复调用
|
||||||
|
if (this->width() == w && this->height() == h) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用 QWidget::resize 或 setFixedSize 来改变窗口的实际尺寸
|
||||||
|
setFixedSize(w, h);
|
||||||
|
|
||||||
|
// 调用 setFixedSize 会自动触发 QOpenGLWidget 的 resizeEvent,
|
||||||
|
// 进而调用 resizeGL(w, h),无需手动调用 resizeGL
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Created by Administrator on 2025/2/16.
|
// Created by Administrator on 2025/2/16.
|
||||||
//
|
//
|
||||||
|
#pragma once
|
||||||
#ifndef AIRI_DESKTOPGRIL_TEXTRENDERER_H
|
|
||||||
#define AIRI_DESKTOPGRIL_TEXTRENDERER_H
|
|
||||||
|
|
||||||
#include <QOpenGLWidget>
|
#include <QOpenGLWidget>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
@@ -99,5 +97,3 @@ private:
|
|||||||
float gravity; /// 重力加速度(像素/秒²)
|
float gravity; /// 重力加速度(像素/秒²)
|
||||||
float dampFactor; /// 碰撞阻尼系数
|
float dampFactor; /// 碰撞阻尼系数
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //AIRI_DESKTOPGRIL_TEXTRENDERER_H
|
|
||||||
|
|||||||
@@ -198,8 +198,8 @@ void TextRenderer::update()
|
|||||||
|
|
||||||
// 最终居中定位
|
// 最终居中定位
|
||||||
int totalWidth = 0;
|
int totalWidth = 0;
|
||||||
for (int w : instance.charWidths) totalWidth += w;
|
for (const int w : instance.charWidths) totalWidth += w;
|
||||||
int startX = (windowWidth - totalWidth) / 2;
|
const int startX = (windowWidth - totalWidth) / 2;
|
||||||
int currentX = startX;
|
int currentX = startX;
|
||||||
|
|
||||||
instance.charPositions.clear();
|
instance.charPositions.clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user