axmol/tests/live2d-tests/Classes/LAppModel.cpp

811 lines
26 KiB
C++
Raw Normal View History

/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
//Cubism Framework
#include "LAppDefine.hpp"
#include "LAppModel.hpp"
#include "LAppPal.hpp"
#include <CubismModelSettingJson.hpp>
#include <Motion/CubismMotion.hpp>
#include <Physics/CubismPhysics.hpp>
#include <CubismDefaultParameterId.hpp>
2022-10-01 16:24:52 +08:00
#include <Rendering/axmol/CubismRenderer_Cocos2dx.hpp>
#include <Utils/CubismString.hpp>
#include <Id/CubismIdManager.hpp>
#include "Motion/CubismMotionQueueEntry.hpp"
#include "SampleScene.h"
//cocos2d
#include "base/CCDirector.h"
#include "renderer/CCTexture2D.h"
#include "renderer/CCTextureCache.h"
using namespace std;
using namespace Csm;
using namespace Csm::Constant;
using namespace Csm::DefaultParameterId;
using namespace LAppDefine;
using namespace ax::backend;
#if USE_AUDIO_ENGINE
#include "audio/include/AudioEngine.h"
using namespace ax::experimental;
#elif USE_SIMPLE_AUDIO_ENGINE
#include "audio/include/SimpleAudioEngine.h"
using namespace CocosDenshion;
#endif
USING_NS_AX;
namespace {
csmByte* CreateBuffer(const csmChar* path, csmSizeInt* size)
{
if (DebugLogEnable)LAppPal::PrintLog("[APP]create buffer: %s ", path);
return LAppPal::LoadFileAsBytes(path, size);
}
void DeleteBuffer(csmByte* buffer, const csmChar* path = "")
{
if (DebugLogEnable) LAppPal::PrintLog("[APP]delete buffer: %s", path);
LAppPal::ReleaseBytes(buffer);
}
}
LAppModel::LAppModel()
: CubismUserModel()
, _modelSetting(NULL)
, _userTimeSeconds(0.0f)
, _renderSprite(NULL)
{
if (DebugLogEnable)
{
_debugMode = true;
}
_idParamAngleX = CubismFramework::GetIdManager()->GetId(ParamAngleX);
_idParamAngleY = CubismFramework::GetIdManager()->GetId(ParamAngleY);
_idParamAngleZ = CubismFramework::GetIdManager()->GetId(ParamAngleZ);
_idParamBodyAngleX = CubismFramework::GetIdManager()->GetId(ParamBodyAngleX);
_idParamEyeBallX = CubismFramework::GetIdManager()->GetId(ParamEyeBallX);
_idParamEyeBallY = CubismFramework::GetIdManager()->GetId(ParamEyeBallY);
_clearColor[0] = 1.0f;
_clearColor[1] = 1.0f;
_clearColor[2] = 1.0f;
_clearColor[3] = 0.0f;
_renderBuffer = new Csm::Rendering::CubismOffscreenFrame_Cocos2dx;
_groupCommand.init(0.0);
}
LAppModel::~LAppModel()
{
if (_debugMode)LAppPal::PrintLog("[APP]delete model: %s", _modelSetting->GetModelFileName());
if (_renderSprite)
{
// Cocos本体が消滅した後ではこの呼び出しが出来ないことに注意
_renderSprite->removeFromParentAndCleanup(true);
_renderSprite = NULL;
}
_renderBuffer->DestroyOffscreenFrame();
ReleaseMotions();
ReleaseExpressions();
for (csmInt32 i = 0; i < _modelSetting->GetMotionGroupCount(); i++)
{
const csmChar* group = _modelSetting->GetMotionGroupName(i);
ReleaseMotionGroup(group);
}
CSM_DELETE(_modelSetting);
//cocos2d
Director::getInstance()->getTextureCache()->removeAllTextures();
}
void LAppModel::LoadAssets(const csmChar* dir, const csmChar* fileName)
{
_modelHomeDir = dir;
if (_debugMode)LAppPal::PrintLog("[APP]load model setting: %s", fileName);
csmSizeInt size;
const csmString path = csmString(dir) + fileName;
csmByte* buffer = CreateBuffer(path.GetRawString(), &size);
ICubismModelSetting* setting = new CubismModelSettingJson(buffer, size);
DeleteBuffer(buffer, path.GetRawString());
SetupModel(setting);
CreateRenderer();
SetupTextures();
}
void LAppModel::SetupModel(ICubismModelSetting* setting)
{
_updating = true;
_initialized = false;
_modelSetting = setting;
csmByte* buffer;
csmSizeInt size;
//Cubism Model
if (strcmp(_modelSetting->GetModelFileName(), "") != 0)
{
csmString path = _modelSetting->GetModelFileName();
path = _modelHomeDir + path;
if (_debugMode)LAppPal::PrintLog("[APP]create model: %s", setting->GetModelFileName());
buffer = CreateBuffer(path.GetRawString(), &size);
LoadModel(buffer, size);
DeleteBuffer(buffer, path.GetRawString());
}
//Expression
if (_modelSetting->GetExpressionCount() > 0)
{
const csmInt32 count = _modelSetting->GetExpressionCount();
for (csmInt32 i = 0; i < count; i++)
{
csmString name = _modelSetting->GetExpressionName(i);
csmString path = _modelSetting->GetExpressionFileName(i);
path = _modelHomeDir + path;
buffer = CreateBuffer(path.GetRawString(), &size);
ACubismMotion* motion = LoadExpression(buffer, size, name.GetRawString());
if (_expressions[name] != NULL)
{
ACubismMotion::Delete(_expressions[name]);
_expressions[name] = NULL;
}
_expressions[name] = motion;
DeleteBuffer(buffer, path.GetRawString());
}
}
//Physics
if (strcmp(_modelSetting->GetPhysicsFileName(), "") != 0)
{
csmString path = _modelSetting->GetPhysicsFileName();
path = _modelHomeDir + path;
buffer = CreateBuffer(path.GetRawString(), &size);
LoadPhysics(buffer, size);
DeleteBuffer(buffer, path.GetRawString());
}
//Pose
if (strcmp(_modelSetting->GetPoseFileName(), "") != 0)
{
csmString path = _modelSetting->GetPoseFileName();
path = _modelHomeDir + path;
buffer = CreateBuffer(path.GetRawString(), &size);
LoadPose(buffer, size);
DeleteBuffer(buffer, path.GetRawString());
}
//EyeBlink
if (_modelSetting->GetEyeBlinkParameterCount() > 0)
{
_eyeBlink = CubismEyeBlink::Create(_modelSetting);
}
//Breath
{
_breath = CubismBreath::Create();
csmVector<CubismBreath::BreathParameterData> breathParameters;
breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleX, 0.0f, 15.0f, 6.5345f, 0.5f));
breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleY, 0.0f, 8.0f, 3.5345f, 0.5f));
breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleZ, 0.0f, 10.0f, 5.5345f, 0.5f));
breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamBodyAngleX, 0.0f, 4.0f, 15.5345f, 0.5f));
breathParameters.PushBack(CubismBreath::BreathParameterData(CubismFramework::GetIdManager()->GetId(ParamBreath), 0.5f, 0.5f, 3.2345f, 0.5f));
_breath->SetParameters(breathParameters);
}
//UserData
if (strcmp(_modelSetting->GetUserDataFile(), "") != 0)
{
csmString path = _modelSetting->GetUserDataFile();
path = _modelHomeDir + path;
buffer = CreateBuffer(path.GetRawString(), &size);
LoadUserData(buffer,size);
DeleteBuffer(buffer, path.GetRawString());
}
// EyeBlinkIds
{
csmInt32 eyeBlinkIdCount = _modelSetting->GetEyeBlinkParameterCount();
for (csmInt32 i = 0; i < eyeBlinkIdCount; ++i)
{
_eyeBlinkIds.PushBack(_modelSetting->GetEyeBlinkParameterId(i));
}
}
// LipSyncIds
{
csmInt32 lipSyncIdCount = _modelSetting->GetLipSyncParameterCount();
for (csmInt32 i = 0; i < lipSyncIdCount; ++i)
{
_lipSyncIds.PushBack(_modelSetting->GetLipSyncParameterId(i));
}
}
//Layout
csmMap<csmString, csmFloat32> layout;
_modelSetting->GetLayoutMap(layout);
_modelMatrix->SetupFromLayout(layout);
_model->SaveParameters();
for (csmInt32 i = 0; i < _modelSetting->GetMotionGroupCount(); i++)
{
const csmChar* group = _modelSetting->GetMotionGroupName(i);
PreloadMotionGroup(group);
}
_motionManager->StopAllMotions();
_updating = false;
_initialized = true;
}
void LAppModel::PreloadMotionGroup(const csmChar* group)
{
const csmInt32 count = _modelSetting->GetMotionCount(group);
for (csmInt32 i = 0; i < count; i++)
{
//ex) idle_0
csmString name = Utils::CubismString::GetFormatedString("%s_%d", group, i);
csmString path = _modelSetting->GetMotionFileName(group, i);
path = _modelHomeDir + path;
if (_debugMode)LAppPal::PrintLog("[APP]load motion: %s => [%s_%d] ", path.GetRawString(), group, i);
csmByte* buffer;
csmSizeInt size;
buffer = CreateBuffer(path.GetRawString(), &size);
CubismMotion* tmpMotion = static_cast<CubismMotion*>(LoadMotion(buffer, size, name.GetRawString()));
csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, i);
if (fadeTime >= 0.0f)
{
tmpMotion->SetFadeInTime(fadeTime);
}
fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, i);
if (fadeTime >= 0.0f)
{
tmpMotion->SetFadeOutTime(fadeTime);
}
tmpMotion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
if (_motions[name] != NULL)
{
ACubismMotion::Delete(_motions[name]);
}
_motions[name] = tmpMotion;
DeleteBuffer(buffer, path.GetRawString());
csmString voice = _modelSetting->GetMotionSoundFileName(group, i);
if (strcmp(voice.GetRawString(), "") != 0)
{
csmString path = voice;
path = _modelHomeDir + path;
#if USE_AUDIO_ENGINE
AudioEngine::preload(path.GetRawString());
#elif USE_SIMPLE_AUDIO_ENGINE
SimpleAudioEngine::getInstance()->preloadEffect(path.GetRawString());
#endif
}
}
}
void LAppModel::ReleaseMotionGroup(const csmChar* group) const
{
const csmInt32 count = _modelSetting->GetMotionCount(group);
for (csmInt32 i = 0; i < count; i++)
{
csmString voice = _modelSetting->GetMotionSoundFileName(group, i);
if (strcmp(voice.GetRawString(), "") != 0)
{
csmString path = voice;
path = _modelHomeDir + path;
#if USE_AUDIO_ENGINE
AudioEngine::uncache(path.GetRawString());
#elif USE_SIMPLE_AUDIO_ENGINE
SimpleAudioEngine::getInstance()->unloadEffect(path.GetRawString());
#endif
}
}
}
/**
* @brief
*
*
*/
void LAppModel::ReleaseMotions()
{
for (csmMap<csmString, ACubismMotion*>::const_iterator iter = _motions.Begin(); iter != _motions.End(); ++iter)
{
ACubismMotion::Delete(iter->Second);
}
_motions.Clear();
}
/**
* @brief
*
*
*/
void LAppModel::ReleaseExpressions()
{
for (csmMap<csmString, ACubismMotion*>::const_iterator iter = _expressions.Begin(); iter != _expressions.End(); ++iter)
{
ACubismMotion::Delete(iter->Second);
}
_expressions.Clear();
}
void LAppModel::Update()
{
const csmFloat32 deltaTimeSeconds = LAppPal::GetDeltaTime();
_userTimeSeconds += deltaTimeSeconds;
_dragManager->Update(deltaTimeSeconds);
_dragX = _dragManager->GetX();
_dragY = _dragManager->GetY();
// モーションによるパラメータ更新の有無
csmBool motionUpdated = false;
//-----------------------------------------------------------------
_model->LoadParameters(); // 前回セーブされた状態をロード
if (_motionManager->IsFinished())
{
// モーションの再生がない場合、待機モーションの中からランダムで再生する
StartRandomMotion(MotionGroupIdle, PriorityIdle);
}
else
{
motionUpdated = _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
}
_model->SaveParameters(); // 状態を保存
//-----------------------------------------------------------------
// まばたき
if (!motionUpdated)
{
if (_eyeBlink != NULL)
{
// メインモーションの更新がないとき
_eyeBlink->UpdateParameters(_model, deltaTimeSeconds); // 目パチ
}
}
if (_expressionManager != NULL)
{
_expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
}
//ドラッグによる変化
//ドラッグによる顔の向きの調整
_model->AddParameterValue(_idParamAngleX, _dragX * 30); // -30から30の値を加える
_model->AddParameterValue(_idParamAngleY, _dragY * 30);
_model->AddParameterValue(_idParamAngleZ, _dragX * _dragY * -30);
//ドラッグによる体の向きの調整
_model->AddParameterValue(_idParamBodyAngleX, _dragX * 10); // -10から10の値を加える
//ドラッグによる目の向きの調整
_model->AddParameterValue(_idParamEyeBallX, _dragX); // -1から1の値を加える
_model->AddParameterValue(_idParamEyeBallY, _dragY);
// 呼吸など
if (_breath != NULL)
{
_breath->UpdateParameters(_model, deltaTimeSeconds);
}
// 物理演算の設定
if (_physics != NULL)
{
_physics->Evaluate(_model, deltaTimeSeconds);
}
// リップシンクの設定
if (_lipSync)
{
csmFloat32 value = 0; // リアルタイムでリップシンクを行う場合、システムから音量を取得して01の範囲で値を入力します。
for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
{
_model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
}
}
// ポーズの設定
if (_pose != NULL)
{
_pose->UpdateParameters(_model, deltaTimeSeconds);
}
_model->Update();
}
CubismMotionQueueEntryHandle LAppModel::StartMotion(const csmChar* group, csmInt32 no, csmInt32 priority, ACubismMotion::FinishedMotionCallback onFinishedMotionHandler)
{
if (priority == PriorityForce)
{
_motionManager->SetReservePriority(priority);
}
else if (!_motionManager->ReserveMotion(priority))
{
if (_debugMode) LAppPal::PrintLog("[APP]can't start motion.");
return InvalidMotionQueueEntryHandleValue;
}
const csmString fileName = _modelSetting->GetMotionFileName(group, no);
//ex) idle_0
csmString name = Utils::CubismString::GetFormatedString("%s_%d", group, no);
CubismMotion* motion = static_cast<CubismMotion*>(_motions[name.GetRawString()]);
csmBool autoDelete = false;
if (motion == NULL)
{
csmString path = fileName;
path = _modelHomeDir + path;
csmByte* buffer;
csmSizeInt size;
buffer = CreateBuffer(path.GetRawString(), &size);
motion = static_cast<CubismMotion*>(LoadMotion(buffer, size, NULL, onFinishedMotionHandler));
csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, no);
if (fadeTime >= 0.0f)
{
motion->SetFadeInTime(fadeTime);
}
fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, no);
if (fadeTime >= 0.0f)
{
motion->SetFadeOutTime(fadeTime);
}
motion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
autoDelete = true; // 終了時にメモリから削除
DeleteBuffer(buffer, path.GetRawString());
}
else
{
motion->SetFinishedMotionHandler(onFinishedMotionHandler);
}
//voice
csmString voice = _modelSetting->GetMotionSoundFileName(group, no);
if (strcmp(voice.GetRawString(), "") != 0)
{
csmString path = voice;
path = _modelHomeDir + path;
#if USE_AUDIO_ENGINE
AudioEngine::play2d(path.GetRawString());
#elif USE_SIMPLE_AUDIO_ENGINE
SimpleAudioEngine::getInstance()->playEffect(path.GetRawString());
#endif
}
if (_debugMode)LAppPal::PrintLog("[APP]start motion: [%s_%d]", group, no);
return _motionManager->StartMotionPriority(motion, autoDelete, priority);
}
CubismMotionQueueEntryHandle LAppModel::StartRandomMotion(const csmChar* group, csmInt32 priority, ACubismMotion::FinishedMotionCallback onFinishedMotionHandler)
{
if (_modelSetting->GetMotionCount(group) == 0)
{
return InvalidMotionQueueEntryHandleValue;
}
csmInt32 no = rand() % _modelSetting->GetMotionCount(group);
return StartMotion(group, no, priority, onFinishedMotionHandler);
}
void LAppModel::DoDraw()
{
if (_model == NULL)return;
GetRenderer<Rendering::CubismRenderer_Cocos2dx>()->DrawModel();
}
void LAppModel::Draw(Csm::Rendering::CubismCommandBuffer_Cocos2dx* commandBuffer, CubismMatrix44& matrix)
{
if (_model == NULL)return;
Csm::Rendering::CubismRenderer_Cocos2dx::StartFrame(commandBuffer);
//commandBuffer->PushCommandGroup();
if (_renderBuffer->IsValid())
{
_renderBuffer->BeginDraw(commandBuffer, NULL);
_renderBuffer->Clear(commandBuffer, _clearColor[0], _clearColor[1], _clearColor[2], _clearColor[3]);
}
matrix.MultiplyByMatrix(_modelMatrix);
GetRenderer<Rendering::CubismRenderer_Cocos2dx>()->SetMvpMatrix(&matrix);
DoDraw();
if (_renderBuffer->IsValid())
{
_renderBuffer->EndDraw(commandBuffer);
}
//commandBuffer->PopCommandGroup();
}
csmBool LAppModel::HitTest(const csmChar* hitAreaName, csmFloat32 x, csmFloat32 y)
{
if (_opacity < 1)return false; // 透明時は当たり判定なし。
const csmInt32 count = _modelSetting->GetHitAreasCount();
for (csmInt32 i = 0; i < count; i++)
{
if (strcmp(_modelSetting->GetHitAreaName(i), hitAreaName) == 0)
{
const CubismIdHandle drawID = _modelSetting->GetHitAreaId(i);
return IsHit(drawID, x, y);
}
}
return false; // 存在しない場合はfalse
}
void LAppModel::SetExpression(const csmChar* expressionID)
{
ACubismMotion* motion = _expressions[expressionID];
if (_debugMode) LAppPal::PrintLog("[APP]expression: [%s]", expressionID);
if (motion != NULL)
{
_expressionManager->StartMotionPriority(motion, false, PriorityForce);
}
else
{
if (_debugMode) LAppPal::PrintLog("[APP]expression[%s] is null ", expressionID);
}
}
void LAppModel::SetRandomExpression()
{
if (_expressions.GetSize() == 0) return;
csmInt32 no = rand() % _expressions.GetSize();
csmMap<csmString, ACubismMotion*>::const_iterator map_ite;
csmInt32 i = 0;
for (map_ite = _expressions.Begin(); map_ite != _expressions.End(); map_ite++)
{
if (i == no)
{
csmString name = (*map_ite).First;
SetExpression(name.GetRawString());
return;
}
i++;
}
}
void LAppModel::ReloadRnederer()
{
DeleteRenderer();
CreateRenderer();
SetupTextures();
}
void LAppModel::SetupTextures()
{
_loadedTextures.Clear();
for (csmInt32 modelTextureNumber = 0; modelTextureNumber < _modelSetting->GetTextureCount(); modelTextureNumber++)
{
// テクスチャ名が空文字だった場合はロード・バインド処理をスキップ
if (strcmp(_modelSetting->GetTextureFileName(modelTextureNumber), "") == 0) continue;
csmString texturePath = _modelSetting->GetTextureFileName(modelTextureNumber);
texturePath = _modelHomeDir + texturePath;
// Cocos2d-x
// テクスチャをファイルからロードする. ロードできなければnullptrが返る
Texture2D* texture = Director::getInstance()->getTextureCache()->addImage(std::string(texturePath.GetRawString()));
// テクスチャが読めていなければバインド処理をスキップ
if(!texture) continue;
const SamplerDescriptor texParams = {
SamplerFilter::LINEAR_MIPMAP_LINEAR,
SamplerFilter::LINEAR,
SamplerAddressMode::CLAMP_TO_EDGE,
SamplerAddressMode::CLAMP_TO_EDGE
};
texture->setTexParameters(texParams);
texture->generateMipmap();
_loadedTextures.PushBack(texture);
//Cocos2d
GetRenderer<Rendering::CubismRenderer_Cocos2dx>()->BindTexture(modelTextureNumber, texture);
}
GetRenderer<Rendering::CubismRenderer_Cocos2dx>()->IsPremultipliedAlpha(true);
}
void LAppModel::MotionEventFired(const csmString& eventValue)
{
CubismLogInfo("%s is fired on LAppModel!!", eventValue.GetRawString());
}
const csmVector<csmRectF>& LAppModel::GetHitAreas(const Csm::CubismMatrix44& vpMatrix, const CubismVector2& windowSize)
{
_hitArea.Clear();
for (csmInt32 i = 0; i < _modelSetting->GetHitAreasCount(); ++i)
{
_hitArea.PushBack(GetDrawableArea(GetModel()->GetDrawableIndex(_modelSetting->GetHitAreaId(i)),vpMatrix, windowSize));
}
return _hitArea;
}
const csmVector<csmRectF>& LAppModel::GetUserDataAreas(const CubismMatrix44& vpMatrix, const CubismVector2& windowSize)
{
_userArea.Clear();
if ( _modelUserData == NULL)
{
return _userArea;
}
const csmVector<const CubismModelUserData::CubismModelUserDataNode*>& ans = _modelUserData->GetArtMeshUserDatas();
for ( csmUint32 i = 0; i < ans.GetSize(); ++i)
{
_userArea.PushBack(GetDrawableArea(GetModel()->GetDrawableIndex(ans[i]->TargetId), vpMatrix, windowSize));
}
return _userArea;
}
csmRectF LAppModel::GetDrawableArea(csmInt32 drawableIndex, const CubismMatrix44& vpMatrix, const CubismVector2& windowSize) const
{
CubismMatrix44 currentMatrix(vpMatrix); //Matrixをコピーしないと変質が次回に影響する
currentMatrix.MultiplyByMatrix(_modelMatrix);
const csmInt32 count = _model->GetDrawableVertexCount(drawableIndex);
const csmFloat32* vertices = _model->GetDrawableVertices(drawableIndex);
csmFloat32 left = vertices[0];
csmFloat32 right = vertices[0];
csmFloat32 top = vertices[1];
csmFloat32 bottom = vertices[1];
for (csmInt32 j = 1; j < count; ++j)
{
CubismVector2 pos;
pos.X = vertices[Constant::VertexOffset + j * Constant::VertexStep];
pos.Y = vertices[Constant::VertexOffset + j * Constant::VertexStep + 1];
if (pos.X < left)
{
left = pos.X; // Min x
}
if (pos.X > right)
{
right = pos.X; // Max x
}
if (pos.Y < top)
{
top = pos.Y; // Min y
}
if (pos.Y > bottom)
{
bottom = pos.Y; // Max y
}
}
csmFloat32 convertLeft = left * currentMatrix.GetArray()[0] + top * currentMatrix.GetArray()[1];
convertLeft = convertLeft * windowSize.X / 2 + windowSize.X / 2;
csmFloat32 convertTop = left * currentMatrix.GetArray()[4] + top * currentMatrix.GetArray()[5];
convertTop = convertTop * windowSize.Y / 2 + windowSize.Y / 2;
csmFloat32 convertRight = right * currentMatrix.GetArray()[0] + bottom * currentMatrix.GetArray()[1];
convertRight = convertRight * windowSize.X / 2 + windowSize.X / 2;
csmFloat32 convertBottom = right * currentMatrix.GetArray()[4] + bottom * currentMatrix.GetArray()[5];
convertBottom = convertBottom * windowSize.Y / 2 + windowSize.Y / 2;
return csmRectF(convertLeft, convertTop, (convertRight - convertLeft), (convertBottom - convertTop));
}
void LAppModel::MakeRenderingTarget()
{
// RenderTexture::createは描画タイミングで呼ぶとAssert扱いになるので注意すること
if (!_renderSprite && !_renderBuffer->IsValid())
{
float aspectFactor = 1.0f;
int frameW = Director::getInstance()->getOpenGLView()->getFrameSize().width, frameH = Director::getInstance()->getOpenGLView()->getFrameSize().height;
2022-07-15 19:17:01 +08:00
#if (AX_TARGET_PLATFORM == AX_PLATFORM_MAC)
// Retina対策でこっちからとる
GLViewImpl *glimpl = (GLViewImpl *)Director::getInstance()->getOpenGLView();
int renderW = frameW;
int renderH = frameH;
glfwGetFramebufferSize(glimpl->getWindow(), &frameW, &frameH);
aspectFactor = static_cast<float>(renderW) / frameW;
#endif
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
2022-10-18 19:17:36 +08:00
_renderSprite = RenderTexture::create(frameW, frameH, ax::backend::PixelFormat::RGBA8);
_renderSprite->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
_renderSprite->getSprite()->getTexture()->setAntiAliasTexParameters();
_renderSprite->getSprite()->setBlendFunc(BlendFunc::ALPHA_NON_PREMULTIPLIED);
_renderSprite->getSprite()->setOpacityModifyRGB(false);
// サンプルシーンへ登録
SampleScene::getInstance()->addChild(_renderSprite);
_renderSprite->setVisible(true);
// _renderSpriteのテクスチャを作成する
_renderSprite->getSprite()->getTexture()->setTexParameters(
2022-10-18 19:17:36 +08:00
ax::Texture2D::TexParams(
ax::backend::SamplerFilter::LINEAR, // MagFilter
ax::backend::SamplerFilter::LINEAR, // MinFilter
ax::backend::SamplerAddressMode::CLAMP_TO_EDGE, // AddressingMode S
ax::backend::SamplerAddressMode::CLAMP_TO_EDGE // AddressingMode T
)
);
// レンダリングバッファの描画先をそのテクスチャにする
_renderBuffer->CreateOffscreenFrame(frameW, frameH, _renderSprite);
_renderSprite->setScale(aspectFactor);
}
}
void LAppModel::SetSpriteColor(float r, float g, float b, float a)
{
if (_renderSprite != NULL)
{
_renderSprite->getSprite()->setColor(Color3B(static_cast<unsigned char>(255.0f * r), static_cast<unsigned char>(255.0f * g), static_cast<unsigned char>(255.0f * b)));
_renderSprite->getSprite()->setOpacity(static_cast<unsigned char>(255.0f * a));
}
}