実行時に画像を乗算済みアルファにするのに加えて、他にも色々画素操作を行えるようにしたいと考えています。
そこで、乗算済みアルファにする方法として今までSetUsePremulAlphaConvertLoad()を用いていた処理を、
一旦CPUで扱える形式で読み込んでからGPUに転送するよう変えることにしました。
ところが、
(1)読み込みフラグを利用して
SetUsePremulAlphaConvertLoad(TRUE);
LoadGraph()
とした場合と、
(2)ソフトウェアイメージを使って、
LoadARGB8ColorSoftImage()
ConvertPremulAlphaSoftImage()
CreateGraphFromSoftImage()
DeleteSoftImage();
とした場合とでは、後者の方がメモリ使用量が多くなってしまいます。
後者のやり方でも前者と同程度のメモリ使用量に抑えるにはどうしたらよいのでしょうか?
[大きさ4096x4096のPNGを4枚読み込んだ際のメモリ使用量]
imgur.com/a/PO0MNvN
挙動として、
(3)BASEIMAGEを使った場合でも、ソフトウェアイメージを使った場合と同程度の消費量でした。
CreateBaseImageToFile()
ConvertPremulAlphaBaseImage()
CreateGraphFromGraphImage()
ReleaseBaseImage()
また、何度か再読み込みを行っても時間が経てば大体同じ使用量に落ち着きます。
試したコードを抜粋したものが以下になります。
========================================
#if defined(_WIN32) && defined(_UNICODE)
static constexpr size_t kMaxPathLength = 1024;
/// @brief 現在DxLibに設定されているコードページを元に、固定長バッファ上でchar文字列をwchar_t文字列に変換
/// @param dstSize 変換先の大きさ。既定引数の場合、変換前の大きさ超過確認を行わない。
/// @return 実際に書き込まれた長さ
static int WidenInBuffer(const char* str, wchar_t* dst, int dstSize = -1)
{
int iCharCode = DxLib::GetUseCharCodeFormat();
int iWcharCode = DxLib::Get_wchar_t_CharCodeFormat();
if (dstSize != -1)
{
int iRet = DxLib::ConvertStringCharCodeFormat(iCharCode, str, iWcharCode, nullptr);
if (iRet < sizeof(wchar_t))return 0;
if (iRet >= dstSize * sizeof(wchar_t))return 0;
}
int iLength = DxLib::ConvertStringCharCodeFormat(iCharCode, str, iWcharCode, dst);
iLength = iLength / sizeof(wchar_t) - 1;
return iLength;
}
#endif /* defined(_WIN32) && defined(_UNICODE) */
void CDxLibTextureLoader::load(const char* textureFilePath)
{
#if defined(_WIN32) && defined(_UNICODE)
wchar_t wcharPathBuffer[kMaxPathLength]{};
int nWritten = WidenInBuffer(textureFilePath, wcharPathBuffer);
#endif
#if 0 /* BASEIMAGEを使った処理 */
DxLib::BASEIMAGE baseImage{};
#if defined(_WIN32) && defined(_UNICODE)
DxLib::CreateBaseImageToFile(wcharPathBuffer, &baseImage);
#else
DxLib::CreateBaseImageToFile(textureFilePath, &baseImage);
#endif
if (baseImage.GraphData == nullptr)return;
if (m_toConvertToPma)
{
DxLib::ConvertPremulAlphaBaseImage(&baseImage);
}
int iDxLibTexture = DxLib::CreateGraphFromGraphImage(&baseImage);
DxLib::ReleaseBaseImage(&baseImage);
if (iDxLibTexture == -1)return;
#elif 0 /* ソフトウェアイメージを使った処理 */
int softwareImageHandle = -1;
#if defined(_WIN32) && defined(_UNICODE)
softwareImageHandle = DxLib::LoadARGB8ColorSoftImage(wcharPathBuffer);
#else
softwareImageHandle = DxLib::LoadARGB8ColorSoftImage(textureFilePath);
#endif
if (softwareImageHandle == -1)return;
if (m_toConvertToPma)
{
DxLib::ConvertPremulAlphaSoftImage(softwareImageHandle);
}
int iDxLibTexture = DxLib::CreateGraphFromSoftImage(softwareImageHandle);
DxLib::DeleteSoftImage(softwareImageHandle);
if (iDxLibTexture == -1)return;
#else /* 読み込みフラグを用いた場合 */
DxLib::SetUsePremulAlphaConvertLoad(m_toConvertToPma ? TRUE : FALSE);
#if defined(_WIN32) && defined(_UNICODE)
int iDxLibTexture = DxLib::LoadGraph(wcharPathBuffer);
#else
int iDxLibTexture = DxLib::LoadGraph(textureFilePath);
#endif
if (iDxLibTexture == -1)return;
#endif
/* 以下略 */
}
========================================