/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #include "StdAfx.h" #include "IconManager.h" #include #include #define HELPER_MATERIAL "Editor/Objects/Helper" namespace { // Object names in this array must correspond to EObject enumeration. const char* g_ObjectNames[eStatObject_COUNT] = { "Editor/Objects/Arrow.cgf", "Editor/Objects/Axis.cgf", "Editor/Objects/Sphere.cgf", "Editor/Objects/Anchor.cgf", "Editor/Objects/entrypoint.cgf", "Editor/Objects/hidepoint.cgf", "Editor/Objects/hidepoint_sec.cgf", "Editor/Objects/reinforcement_point.cgf", }; const char* g_IconNames[eIcon_COUNT] = { "Editor/Icons/ScaleWarning.png", "Editor/Icons/RotationWarning.png", }; }; ////////////////////////////////////////////////////////////////////////// CIconManager::CIconManager() { ZeroStruct(m_icons); ZeroStruct(m_objects); } ////////////////////////////////////////////////////////////////////////// CIconManager::~CIconManager() { } ////////////////////////////////////////////////////////////////////////// void CIconManager::Init() { } ////////////////////////////////////////////////////////////////////////// void CIconManager::Done() { Reset(); } ////////////////////////////////////////////////////////////////////////// void CIconManager::Reset() { I3DEngine* pEngine = GetIEditor()->Get3DEngine(); // Do not unload objects. but clears them. int i; for (i = 0; i < sizeof(m_objects) / sizeof(m_objects[0]); i++) { if (m_objects[i] && pEngine) { m_objects[i]->Release(); } m_objects[i] = 0; } for (i = 0; i < eIcon_COUNT; i++) { m_icons[i] = 0; } // Free icon bitmaps. for (IconsMap::iterator it = m_iconBitmapsMap.begin(); it != m_iconBitmapsMap.end(); ++it) { delete it->second; } m_iconBitmapsMap.clear(); } ////////////////////////////////////////////////////////////////////////// int CIconManager::GetIconTexture(const char* iconName) { int id = 0; if (m_textures.Find(iconName, id)) { return id; } if ((!iconName) || (iconName[0] == 0)) { return 0; } QString ext = Path::GetExt(iconName); QString actualName = iconName; char iconPath[AZ_MAX_PATH_LEN] = { 0 }; gEnv->pFileIO->ResolvePath(actualName.toUtf8().data(), iconPath, AZ_MAX_PATH_LEN); // if we can't find it at the resolved path, try the devroot if necessary: if (!gEnv->pFileIO->Exists(iconPath)) { if (iconName[0] != '@') // it has no specified alias { if (QString::compare(ext, "dds", Qt::CaseInsensitive) != 0) // if its a DDS, it comes out of processed files in @assets@, and assets is assumed by default { // check for a source file AZStd::string iconFullPath; bool pathFound = false; using AssetSysReqBus = AzToolsFramework::AssetSystemRequestBus; AssetSysReqBus::BroadcastResult(pathFound, &AssetSysReqBus::Events::GetFullSourcePathFromRelativeProductPath, iconName, iconFullPath); if (pathFound) { azstrncpy(iconPath, AZ_MAX_PATH_LEN, iconFullPath.c_str(), iconFullPath.length() + 1); } } } } CImageEx image; // Load icon. if (CImageUtil::LoadImage(iconPath, image)) { IRenderer* pRenderer(GetIEditor()->GetRenderer()); if (pRenderer->GetRenderType() != eRT_DX11) { image.SwapRedAndBlue(); } if (QString::compare(ext, "bmp", Qt::CaseInsensitive) == 0 || QString::compare(ext, "jpg", Qt::CaseInsensitive) == 0) { int sz = image.GetWidth() * image.GetHeight(); int h = image.GetHeight(); uint8* buf = (uint8*)image.GetData(); for (int i = 0; i < sz; i++) { uint32 alpha = max(max(buf[i * 4], buf[i * 4 + 1]), buf[i * 4 + 2]); alpha *= 2; buf[i * 4 + 3] = (alpha > 255) ? 255 : alpha; } } id = pRenderer->DownLoadToVideoMemory((unsigned char*)image.GetData(), image.GetWidth(), image.GetHeight(), eTF_R8G8B8A8, eTF_R8G8B8A8, 0, 0, 0); m_textures[iconName] = id; } return id; } ////////////////////////////////////////////////////////////////////////// int CIconManager::GetIconTexture(EIcon icon) { assert(icon >= 0 && icon < eIcon_COUNT); if (m_icons[icon]) { return m_icons[icon]; } m_icons[icon] = GetIconTexture(g_IconNames[icon]); return m_icons[icon]; } ////////////////////////////////////////////////////////////////////////// _smart_ptr CIconManager::GetHelperMaterial() { if (!m_pHelperMtl) { m_pHelperMtl = GetIEditor()->Get3DEngine()->GetMaterialManager()->LoadMaterial(HELPER_MATERIAL); } return m_pHelperMtl; }; ////////////////////////////////////////////////////////////////////////// IStatObj* CIconManager::GetObject(EStatObject object) { assert(object >= 0 && object < eStatObject_COUNT); if (m_objects[object]) { return m_objects[object]; } // Try to load this object. m_objects[object] = GetIEditor()->Get3DEngine()->LoadStatObjUnsafeManualRef(g_ObjectNames[object], NULL, NULL, false); if (!m_objects[object]) { CLogFile::FormatLine("Error: Load Failed: %s", g_ObjectNames[object]); } m_objects[object]->AddRef(); if (GetHelperMaterial()) { m_objects[object]->SetMaterial(GetHelperMaterial()); } return m_objects[object]; } ////////////////////////////////////////////////////////////////////////// QImage* CIconManager::GetIconBitmap(const char* filename, bool& bHaveAlpha, uint32 effects /*=0*/) { QImage* pBitmap = 0; QString iconFilename = filename; if (Path::GetPath(iconFilename).isEmpty()) { QString iconsPath; if (!gSettings.searchPaths[EDITOR_PATH_UI_ICONS].empty()) { iconsPath = gSettings.searchPaths[EDITOR_PATH_UI_ICONS][0]; } iconFilename = Path::Make(iconsPath, iconFilename); } if (Path::GetExt(iconFilename).isEmpty()) { // By default add .bmp extension to the filename without extension. pBitmap = GetIconBitmap((iconFilename + ".png").toUtf8().data(), bHaveAlpha); if (!pBitmap) { pBitmap = GetIconBitmap((iconFilename + ".bmp").toUtf8().data(), bHaveAlpha); } return pBitmap; } BOOL bAlphaBitmap = FALSE; QPixmap pm(iconFilename); bAlphaBitmap = pm.hasAlpha(); bHaveAlpha = (bAlphaBitmap == TRUE); if (!pm.isNull()) { pBitmap = new QImage; *pBitmap = pm.toImage(); m_iconBitmapsMap[filename] = pBitmap; // apply image effects if (bAlphaBitmap) { const DWORD dataSize = pm.width() * pm.height() * 4; BYTE* pImage = pBitmap->bits(); if (effects & eIconEffect_ColorEnabled) { for (DWORD i = 0; i < dataSize; i += 4) { pImage[i + 0] = (BYTE)((DWORD)pImage[i + 0] * 109 / 255); pImage[i + 1] = (BYTE)((DWORD)pImage[i + 1] * 97 / 255); pImage[i + 2] = (BYTE)((DWORD)pImage[i + 2] * 89 / 255); } } if (effects & eIconEffect_ColorDisabled) { for (DWORD i = 0; i < dataSize; i += 4) { pImage[i + 0] = (BYTE)((DWORD)pImage[i + 0] * 168 / 255); pImage[i + 1] = (BYTE)((DWORD)pImage[i + 1] * 164 / 255); pImage[i + 2] = (BYTE)((DWORD)pImage[i + 2] * 162 / 255); } } if (effects & eIconEffect_Dim) { for (DWORD i = 0; i < dataSize; i += 4) { pImage[i + 0] /= 2; pImage[i + 1] /= 2; pImage[i + 2] /= 2; } } if (effects & eIconEffect_HalfAlpha) { for (DWORD i = 0; i < dataSize; i += 4) { pImage[i + 3] /= 2; } } if (effects & eIconEffect_TintGreen) { for (DWORD i = 0; i < dataSize; i += 4) { pImage[i + 0] /= 2; pImage[i + 2] /= 2; } } if (effects & eIconEffect_TintRed) { for (DWORD i = 0; i < dataSize; i += 4) { pImage[i + 0] /= 2; pImage[i + 1] /= 2; } } if (effects & eIconEffect_TintYellow) { for (DWORD i = 0; i < dataSize; i += 4) { pImage[i + 0] /= 2; } } // alpha premultiply for (DWORD i = 0; i < dataSize; i += 4) { pImage[i + 0] = ((DWORD)pImage[i + 0] * (DWORD)pImage[i + 3]) / 255; pImage[i + 1] = ((DWORD)pImage[i + 1] * (DWORD)pImage[i + 3]) / 255; pImage[i + 2] = ((DWORD)pImage[i + 2] * (DWORD)pImage[i + 3]) / 255; } } return pBitmap; } return NULL; }