Fixes
This commit is contained in:
@ -31,6 +31,7 @@ namespace ia::iae
|
|||||||
VOID TextureComponent::Draw()
|
VOID TextureComponent::Draw()
|
||||||
{
|
{
|
||||||
const auto t = Engine::GetImageExtent(m_texture);
|
const auto t = Engine::GetImageExtent(m_texture);
|
||||||
|
const auto t2 = Engine::GetImageOriginalExtent(m_texture);
|
||||||
m_textureExtent = {t.x, t.y};
|
m_textureExtent = {t.x, t.y};
|
||||||
m_drawnSize = m_node->GetScale() * m_textureExtent * m_scaleOffset;
|
m_drawnSize = m_node->GetScale() * m_textureExtent * m_scaleOffset;
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ namespace ia::iae
|
|||||||
Engine::SetRenderState_ColorOverlay(m_colorOverlay);
|
Engine::SetRenderState_ColorOverlay(m_colorOverlay);
|
||||||
Engine::SetRenderState_TextureOffset(m_textureOffset);
|
Engine::SetRenderState_TextureOffset(m_textureOffset);
|
||||||
Engine::SetRenderState_CameraRelative(m_isCameraRelative);
|
Engine::SetRenderState_CameraRelative(m_isCameraRelative);
|
||||||
Engine::SetRenderState_Transform(m_node->GetPosition() + m_positionOffset, m_drawnSize, m_node->GetRotation() + m_rotationOffset, m_node->Layer(), m_node->SortIndex());
|
Engine::SetRenderState_Transform(m_node->GetPosition() + m_positionOffset, m_node->GetScale() * Vec2{t2.x, t2.y} * m_scaleOffset, m_node->GetRotation() + m_rotationOffset, m_node->Layer(), m_node->SortIndex());
|
||||||
|
|
||||||
Engine::DrawGeometry(Engine::GetGeometry_Quad());
|
Engine::DrawGeometry(Engine::GetGeometry_Quad());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,7 +96,8 @@ namespace ia::iae
|
|||||||
{
|
{
|
||||||
const auto data = File::ReadToVector(path.c_str());
|
const auto data = File::ReadToVector(path.c_str());
|
||||||
const auto handle = CreateImage(name, data.data(), data.size());
|
const auto handle = CreateImage(name, data.data(), data.size());
|
||||||
return (resizeToWidth && resizeToHeight) ? ResizeImage(handle, resizeToWidth, resizeToHeight) : handle;
|
const auto extent = GetImageExtent(handle);
|
||||||
|
return (resizeToWidth && resizeToHeight) ? RescaleImage(handle, {(FLOAT32)resizeToWidth/(FLOAT32)extent.x, (FLOAT32)resizeToHeight/(FLOAT32)extent.y}) : handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle Engine::CreateSoundFromFile(IN CONST String &name, IN CONST String &path)
|
Handle Engine::CreateSoundFromFile(IN CONST String &name, IN CONST String &path)
|
||||||
@ -105,9 +106,9 @@ namespace ia::iae
|
|||||||
return CreateSound(name, data.data(), data.size());
|
return CreateSound(name, data.data(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle Engine::ResizeImage(IN CONST String &name, IN INT32 newWidth, IN INT32 newHeight)
|
Handle Engine::RescaleImage(IN CONST String &name, IN Vec2 factor)
|
||||||
{
|
{
|
||||||
return ResizeImage(GetImage(name), newWidth, newHeight);
|
return RescaleImage(GetImage(name), factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
String Engine::GetUniqueResourceName()
|
String Engine::GetUniqueResourceName()
|
||||||
|
|||||||
@ -29,9 +29,9 @@ namespace ia::iae
|
|||||||
SDL_GPUSamplerCreateInfo createInfo{.min_filter = SDL_GPU_FILTER_LINEAR,
|
SDL_GPUSamplerCreateInfo createInfo{.min_filter = SDL_GPU_FILTER_LINEAR,
|
||||||
.mag_filter = SDL_GPU_FILTER_LINEAR,
|
.mag_filter = SDL_GPU_FILTER_LINEAR,
|
||||||
.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR,
|
.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR,
|
||||||
.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_REPEAT,
|
.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||||
.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_REPEAT,
|
.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||||
.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_REPEAT,
|
.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||||
.enable_anisotropy = false};
|
.enable_anisotropy = false};
|
||||||
|
|
||||||
g_linearClampSampler = SDL_CreateGPUSampler(Renderer::GetDevice(), &createInfo);
|
g_linearClampSampler = SDL_CreateGPUSampler(Renderer::GetDevice(), &createInfo);
|
||||||
|
|||||||
@ -288,7 +288,7 @@ namespace ia::iae
|
|||||||
s_fragmentUniform.FlippedV = s_state.FlippedV;
|
s_fragmentUniform.FlippedV = s_state.FlippedV;
|
||||||
s_fragmentUniform.TextureOffset = s_state.TextureOffset;
|
s_fragmentUniform.TextureOffset = s_state.TextureOffset;
|
||||||
SDL_GPUTextureSamplerBinding textureBinding{.texture = s_state.ActiveTexture,
|
SDL_GPUTextureSamplerBinding textureBinding{.texture = s_state.ActiveTexture,
|
||||||
.sampler = GPUResourceManager::GetSampler_LinearRepeat()};
|
.sampler = ((s_state.TextureOffset.x <= FLOAT32_EPSILON) && (s_state.TextureOffset.y <= FLOAT32_EPSILON)) ? GPUResourceManager::GetSampler_LinearClamp() : GPUResourceManager::GetSampler_LinearRepeat()};
|
||||||
SDL_BindGPUFragmentSamplers(s_state.ActiveRenderPass, 0, &textureBinding, 1);
|
SDL_BindGPUFragmentSamplers(s_state.ActiveRenderPass, 0, &textureBinding, 1);
|
||||||
SDL_PushGPUFragmentUniformData(s_state.ActiveCommandBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform));
|
SDL_PushGPUFragmentUniformData(s_state.ActiveCommandBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform));
|
||||||
|
|
||||||
|
|||||||
@ -28,11 +28,9 @@
|
|||||||
|
|
||||||
namespace ia::iae
|
namespace ia::iae
|
||||||
{
|
{
|
||||||
Vector<SDL_GPUTexture *> ResourceManager::s_imageHandles;
|
|
||||||
Map<String, Handle> ResourceManager::s_images;
|
Map<String, Handle> ResourceManager::s_images;
|
||||||
Map<String, Handle> ResourceManager::s_sounds;
|
Map<String, Handle> ResourceManager::s_sounds;
|
||||||
Map<Handle, UINT64> ResourceManager::s_imageExtents;
|
Vector<ResourceManager::ImageResource> ResourceManager::s_imageHandles;
|
||||||
Map<Handle, UINT64> ResourceManager::s_nonScaledImageExtents;
|
|
||||||
|
|
||||||
VOID ResourceManager::Initialize()
|
VOID ResourceManager::Initialize()
|
||||||
{
|
{
|
||||||
@ -47,7 +45,7 @@ namespace ia::iae
|
|||||||
VOID ResourceManager::Terminate()
|
VOID ResourceManager::Terminate()
|
||||||
{
|
{
|
||||||
for (const auto &t : s_images)
|
for (const auto &t : s_images)
|
||||||
GPUResourceManager::DestroyTexture(s_imageHandles[t->Value]);
|
GPUResourceManager::DestroyTexture(s_imageHandles[t->Value].Handle);
|
||||||
for (const auto &t : s_sounds)
|
for (const auto &t : s_sounds)
|
||||||
AudioManager::DestoryAudio(t->Value);
|
AudioManager::DestoryAudio(t->Value);
|
||||||
}
|
}
|
||||||
@ -65,11 +63,15 @@ namespace ia::iae
|
|||||||
{
|
{
|
||||||
const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, width, height, rgbaData,
|
const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, width, height, rgbaData,
|
||||||
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
|
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
|
||||||
s_imageHandles.pushBack(texture);
|
s_imageHandles.pushBack(ImageResource{.OriginalWidth = width,
|
||||||
|
.OriginalHeight = height,
|
||||||
|
.OriginalPixelData = new UINT8[width * height * 4],
|
||||||
|
.Width = width,
|
||||||
|
.Height = height,
|
||||||
|
.Handle = texture});
|
||||||
|
ia_memcpy(s_imageHandles.back().OriginalPixelData, rgbaData, width * height * 4);
|
||||||
Handle handle = s_imageHandles.size() - 1;
|
Handle handle = s_imageHandles.size() - 1;
|
||||||
s_images[name] = handle;
|
s_images[name] = handle;
|
||||||
s_imageExtents[handle] = (((UINT64) width) << 32) | height;
|
|
||||||
s_nonScaledImageExtents[handle] = s_imageExtents[handle];
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +116,8 @@ namespace ia::iae
|
|||||||
|
|
||||||
VOID ResourceManager::DestroyImage(IN Handle image)
|
VOID ResourceManager::DestroyImage(IN Handle image)
|
||||||
{
|
{
|
||||||
GPUResourceManager::DestroyTexture(s_imageHandles[image]);
|
GPUResourceManager::DestroyTexture(s_imageHandles[image].Handle);
|
||||||
s_imageHandles[image] = nullptr;
|
s_imageHandles[image] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID ResourceManager::DestroySound(IN Handle sound)
|
VOID ResourceManager::DestroySound(IN Handle sound)
|
||||||
@ -125,23 +127,38 @@ namespace ia::iae
|
|||||||
|
|
||||||
IVec2 ResourceManager::GetImageExtent(IN Handle image)
|
IVec2 ResourceManager::GetImageExtent(IN Handle image)
|
||||||
{
|
{
|
||||||
const auto t = s_imageExtents[image];
|
const auto t = s_imageHandles[image];
|
||||||
return {(INT32) (t >> 32), (INT32) t};
|
return {t.Width, t.Height};
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle ResourceManager::ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight)
|
IVec2 ResourceManager::GetImageOriginalExtent(IN Handle image)
|
||||||
{
|
{
|
||||||
const auto currentExtent = GetImageExtent(image);
|
const auto t = s_imageHandles[image];
|
||||||
const auto pixelData =
|
return {t.OriginalWidth, t.OriginalHeight};
|
||||||
GPUResourceManager::GetTexturePixelData(s_imageHandles[image], currentExtent.x, currentExtent.y);
|
}
|
||||||
|
|
||||||
|
Handle ResourceManager::RescaleImage(IN Handle image, IN Vec2 factor)
|
||||||
|
{
|
||||||
|
if (!s_imageHandles[image].OriginalPixelData)
|
||||||
|
return image;
|
||||||
|
|
||||||
|
const auto newWidth = (INT32) (s_imageHandles[image].OriginalWidth * factor.x);
|
||||||
|
const auto newHeight = (INT32) (s_imageHandles[image].OriginalHeight * factor.y);
|
||||||
|
|
||||||
|
if (!newWidth || !newHeight ||
|
||||||
|
((newWidth <= s_imageHandles[image].OriginalWidth) && (newHeight <= s_imageHandles[image].OriginalHeight)))
|
||||||
|
return image;
|
||||||
|
|
||||||
const auto newPixelData =
|
const auto newPixelData =
|
||||||
stbir_resize_uint8_linear(pixelData.data(), currentExtent.x, currentExtent.y, currentExtent.x * 4, nullptr,
|
stbir_resize_uint8_linear(s_imageHandles[image].OriginalPixelData, s_imageHandles[image].OriginalWidth,
|
||||||
newWidth, newHeight, newWidth * 4, stbir_pixel_layout::STBIR_RGBA);
|
s_imageHandles[image].OriginalHeight, s_imageHandles[image].OriginalWidth * 4,
|
||||||
|
nullptr, newWidth, newHeight, newWidth * 4, stbir_pixel_layout::STBIR_RGBA);
|
||||||
const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, newWidth, newHeight,
|
const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, newWidth, newHeight,
|
||||||
newPixelData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
|
newPixelData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
|
||||||
s_imageExtents[image] = (((UINT64) newWidth) << 32) | newHeight;
|
GPUResourceManager::DestroyTexture(s_imageHandles[image].Handle);
|
||||||
GPUResourceManager::DestroyTexture(s_imageHandles[image]);
|
s_imageHandles[image].Handle = texture;
|
||||||
s_imageHandles[image] = texture;
|
s_imageHandles[image].Width = newWidth;
|
||||||
|
s_imageHandles[image].Height = newHeight;
|
||||||
free(newPixelData);
|
free(newPixelData);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@ -153,24 +170,24 @@ namespace ia::iae
|
|||||||
const auto h = unitHeight * unitCountY;
|
const auto h = unitHeight * unitCountY;
|
||||||
Vector<SDL_GPUTexture *> textures;
|
Vector<SDL_GPUTexture *> textures;
|
||||||
for (const auto &t : images)
|
for (const auto &t : images)
|
||||||
textures.pushBack(s_imageHandles[t]);
|
textures.pushBack(s_imageHandles[t].Handle);
|
||||||
const auto texture =
|
const auto texture =
|
||||||
GPUResourceManager::CombineTextures(textures.data(), unitWidth, unitHeight, unitCountX, unitCountY);
|
GPUResourceManager::CombineTextures(textures.data(), unitWidth, unitHeight, unitCountX, unitCountY);
|
||||||
s_imageHandles.pushBack(texture);
|
s_imageHandles.pushBack(ImageResource{.OriginalWidth = w,
|
||||||
|
.OriginalHeight = h,
|
||||||
|
.OriginalPixelData = nullptr,
|
||||||
|
.Width = w,
|
||||||
|
.Height = h,
|
||||||
|
.Handle = texture});
|
||||||
Handle handle = s_imageHandles.size() - 1;
|
Handle handle = s_imageHandles.size() - 1;
|
||||||
s_images[Engine::GetUniqueResourceName()] = handle;
|
s_images[Engine::GetUniqueResourceName()] = handle;
|
||||||
s_imageExtents[handle] = (((UINT64) w) << 32) | h;
|
|
||||||
s_nonScaledImageExtents[handle] = s_imageExtents[handle];
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID ResourceManager::RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY)
|
VOID ResourceManager::RescaleAllImages(IN Vec2 factor)
|
||||||
{
|
{
|
||||||
for (auto &t : s_images)
|
for (auto &t : s_images)
|
||||||
{
|
t->Value = RescaleImage(t->Value, factor);
|
||||||
const auto p = s_nonScaledImageExtents[t->Value];
|
|
||||||
t->Value = ResizeImage(t->Value, ((INT32) (p >> 32)) * factorX, ((INT32) p) * factorY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // namespace ia::iae
|
} // namespace ia::iae
|
||||||
|
|
||||||
@ -216,14 +233,19 @@ namespace ia::iae
|
|||||||
return ResourceManager::GetImageExtent(image);
|
return ResourceManager::GetImageExtent(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle Engine::ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight)
|
IVec2 Engine::GetImageOriginalExtent(IN Handle image)
|
||||||
{
|
{
|
||||||
return ResourceManager::ResizeImage(image, newWidth, newHeight);
|
return ResourceManager::GetImageOriginalExtent(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID Engine::RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY)
|
Handle Engine::RescaleImage(IN Handle image, IN Vec2 factor)
|
||||||
{
|
{
|
||||||
ResourceManager::RescaleAllImages(factorX, factorY);
|
return ResourceManager::RescaleImage(image, factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID Engine::RescaleAllImages(IN Vec2 factor)
|
||||||
|
{
|
||||||
|
ResourceManager::RescaleAllImages(factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle Engine::CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
Handle Engine::CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
||||||
|
|||||||
@ -76,19 +76,20 @@ namespace ia::iae
|
|||||||
std::string result;
|
std::string result;
|
||||||
std::string::const_iterator search_start(text.cbegin());
|
std::string::const_iterator search_start(text.cbegin());
|
||||||
|
|
||||||
SIZE_T t1 = 0, t2 = 0;
|
SIZE_T t = 0;
|
||||||
while (std::regex_search(search_start, text.cend(), match, std::regex(pattern.c_str())))
|
while (std::regex_search(search_start, text.cend(), match, std::regex(pattern.c_str())))
|
||||||
{
|
{
|
||||||
for(SIZE_T i = 1; i < match.size(); i++)
|
for(SIZE_T i = 1; i < match.size(); i++)
|
||||||
{
|
{
|
||||||
result += text.substr(t1, match.position(i) - t1);
|
const auto p = match.position(i) + (search_start - text.cbegin());
|
||||||
result += std::string(groupTransformer(i - 1, match.str(i).c_str()).c_str());
|
const auto l = match.length(i);
|
||||||
t1 = match.position(i);
|
result += text.substr(t, p - t);
|
||||||
t2 = match.str(i).length();
|
result += groupTransformer(i - 1, text.substr(p, l).c_str()).c_str();
|
||||||
|
t = p + l;
|
||||||
}
|
}
|
||||||
result += text.substr(match.suffix().first - text.begin() - 1);
|
search_start = text.cbegin() + t;
|
||||||
search_start = match.suffix().first;
|
|
||||||
}
|
}
|
||||||
|
result += text.substr(t, text.size() - t);
|
||||||
|
|
||||||
return result.c_str();
|
return result.c_str();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,9 +26,13 @@ namespace ia::iae
|
|||||||
{
|
{
|
||||||
struct ImageResource
|
struct ImageResource
|
||||||
{
|
{
|
||||||
|
INT32 OriginalWidth{};
|
||||||
|
INT32 OriginalHeight{};
|
||||||
|
PUINT8 OriginalPixelData{};
|
||||||
|
|
||||||
INT32 Width{};
|
INT32 Width{};
|
||||||
INT32 Height{};
|
INT32 Height{};
|
||||||
SDL_GPUTexture *Texture{};
|
SDL_GPUTexture *Handle{};
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -47,22 +51,21 @@ namespace ia::iae
|
|||||||
STATIC VOID DestroyImage(IN Handle image);
|
STATIC VOID DestroyImage(IN Handle image);
|
||||||
STATIC VOID DestroySound(IN Handle sound);
|
STATIC VOID DestroySound(IN Handle sound);
|
||||||
STATIC IVec2 GetImageExtent(IN Handle image);
|
STATIC IVec2 GetImageExtent(IN Handle image);
|
||||||
STATIC VOID RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY);
|
STATIC IVec2 GetImageOriginalExtent(IN Handle image);
|
||||||
STATIC Handle ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight);
|
STATIC VOID RescaleAllImages(IN Vec2 factor);
|
||||||
|
STATIC Handle RescaleImage(IN Handle image, IN Vec2 factor);
|
||||||
STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
||||||
IN INT32 unitCountX, IN INT32 unitCountY);
|
IN INT32 unitCountX, IN INT32 unitCountY);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC SDL_GPUTexture *GetTextureFromImage(IN Handle image)
|
STATIC SDL_GPUTexture *GetTextureFromImage(IN Handle image)
|
||||||
{
|
{
|
||||||
return s_imageHandles[image];
|
return s_imageHandles[image].Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC Vector<SDL_GPUTexture *> s_imageHandles;
|
|
||||||
STATIC Map<String, Handle> s_images;
|
STATIC Map<String, Handle> s_images;
|
||||||
STATIC Map<String, Handle> s_sounds;
|
STATIC Map<String, Handle> s_sounds;
|
||||||
STATIC Map<Handle, UINT64> s_imageExtents;
|
STATIC Vector<ImageResource> s_imageHandles;
|
||||||
STATIC Map<Handle, UINT64> s_nonScaledImageExtents;
|
|
||||||
};
|
};
|
||||||
} // namespace ia::iae
|
} // namespace ia::iae
|
||||||
@ -82,9 +82,10 @@ namespace ia::iae
|
|||||||
STATIC VOID DestroyImage(IN Handle image);
|
STATIC VOID DestroyImage(IN Handle image);
|
||||||
STATIC VOID DestroySound(IN Handle sound);
|
STATIC VOID DestroySound(IN Handle sound);
|
||||||
STATIC IVec2 GetImageExtent(IN Handle image);
|
STATIC IVec2 GetImageExtent(IN Handle image);
|
||||||
STATIC Handle ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight);
|
STATIC IVec2 GetImageOriginalExtent(IN Handle image);
|
||||||
STATIC Handle ResizeImage(IN CONST String &name, IN INT32 newWidth, IN INT32 newHeight);
|
STATIC Handle RescaleImage(IN Handle image, IN Vec2 factor);
|
||||||
STATIC VOID RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY);
|
STATIC Handle RescaleImage(IN CONST String &name, IN Vec2 factor);
|
||||||
|
STATIC VOID RescaleAllImages(IN Vec2 factor);
|
||||||
STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
||||||
IN INT32 unitCountX, IN INT32 unitCountY);
|
IN INT32 unitCountX, IN INT32 unitCountY);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user