void CComponentInstanceManager::UnloadFile(uint32_t uFileId, std::vector<CComponentBase*>* pUnloadComponents) { std::vector<uint32_t>::iterator iterFile = std::find(m_loadedFiles.begin(), m_loadedFiles.end(), uFileId); BEATS_WARNING(iterFile != m_loadedFiles.end(), "Close an unopened file %d, this may be right if we are exiting the program.", uFileId); if (iterFile != m_loadedFiles.end()) { m_loadedFiles.erase(iterFile); const std::map<uint32_t, std::map<uint32_t, std::set<uint32_t> > >* pFileToComponentMap = m_pProject->GetFileToComponentMap(); auto iter = pFileToComponentMap->find(uFileId); if (iter != pFileToComponentMap->end()) { for (auto subIter = iter->second.begin(); subIter != iter->second.end(); ++subIter) { for (auto idIter = subIter->second.begin(); idIter != subIter->second.end(); ++idIter) { uint32_t uComponentId = *idIter; BEATS_ASSERT(uComponentId != 0xFFFFFFFF); CComponentBase* pComponentBase = CComponentInstanceManager::GetInstance()->GetComponentInstance(uComponentId); // This may be null, because some components can be uninitialized by other component's un-initialize. if (pComponentBase != NULL) { BEATS_ASSERT(pComponentBase->IsLoaded()); pComponentBase->Unload(); pUnloadComponents->push_back(pComponentBase); } } } } } }
void CComponentProxyManager::UnloadFile(uint32_t uFileId, std::vector<CComponentBase*>* pUnloadComponents) { BEATS_ASSERT(pUnloadComponents != nullptr); std::vector<uint32_t>::iterator iterFile = std::find(m_loadedFiles.begin(), m_loadedFiles.end(), uFileId); BEATS_WARNING(iterFile != m_loadedFiles.end(), "Close an unopened file %d, this may be right if we are exiting the program.", uFileId); if (iterFile != m_loadedFiles.end()) { // query id from the static data: m_pProject. const std::map<uint32_t, std::map<uint32_t, std::set<uint32_t> > >* pFileToComponentMap = m_pProject->GetFileToComponentMap(); auto iter = pFileToComponentMap->find(uFileId); if (iter != pFileToComponentMap->end()) { for (auto subIter = iter->second.begin(); subIter != iter->second.end(); ++subIter) { for (auto idIter = subIter->second.begin(); idIter != subIter->second.end(); ++idIter) { uint32_t uComponentId = *idIter; CComponentProxy* pComponentProxy = static_cast<CComponentProxy*>(CComponentProxyManager::GetInstance()->GetComponentInstance(uComponentId)); BEATS_ASSERT(pComponentProxy != NULL && pComponentProxy->IsLoaded()); pComponentProxy->Unload(); pComponentProxy->GetHostComponent()->Unload(); pUnloadComponents->push_back(pComponentProxy); } } } m_loadedFiles.erase(iterFile); } }
bool CSkin::Load() { bool bRet = false; BEATS_ASSERT(!IsLoaded(), _T("Can't Load a skin which is already loaded!")); // Load From File CSerializer serializer(_T("..\\Resource\\skin\\org.skin")); CSerializer tmpVerticesBufferPos, tmpVerticesBufferUV; CSerializer indexBuffer; size_t uVertexCount = 0; serializer >> uVertexCount; m_uVertexCount = uVertexCount; m_vertices = new CVertexPTB[uVertexCount]; float x, y, z; float u,v; for (size_t i = 0; i < uVertexCount; ++i) { ESkeletonBoneType bone, bone1, bone2, bone3; float weight, weight1, weight2,weight3; serializer >> x >> y >> z >> u >> v; serializer >> bone; serializer >> weight; serializer >> bone1; serializer >> weight1; serializer >> bone2; serializer >> weight2; serializer >> bone3; serializer >> weight3; CVertexPTB &vertex = m_vertices[i]; kmVec3Fill(&vertex.position,x,y,z); vertex.tex = CTex(u,v); vertex.bones = CIVector4(bone, bone1, bone2, bone3); kmVec4Fill(&vertex.weights,weight,weight1,weight2,weight3); #ifdef _DEBUG float sum = weight + weight1 + weight2+weight3; BEATS_ASSERT(sum < 1.01F, _T("Weight can't be greater than 1.01F, cur Value : %f!"), sum); BEATS_WARNING(sum > 0.99F, _T("Weight can't be smaller than 0.99F, cur Value : %f!"), sum); #endif } for (size_t i = 0; i < uVertexCount; ++i) { indexBuffer << (short)i; } CRenderer* pRenderer = CRenderer::GetInstance(); pRenderer->GenVertexArrays(1, &m_uVAO); pRenderer->GenBuffers(2, m_uVBO); #ifndef SW_SKEL_ANIM buildVBOVertex(m_vertices, m_uVertexCount*sizeof(CVertexPTB)); BEATS_SAFE_DELETE_ARRAY(m_vertices); #endif buildVBOIndex(indexBuffer.GetBuffer(), indexBuffer.GetWritePos()); buildVAO(); SetLoadedFlag(true); return bRet; }
bool CEnumStrGenerator::ScanEnumInFile( const TCHAR* pFileName, const TCHAR* pSpecifyEnumName ) { bool bRet = false; CSerializer serializer(pFileName); while (serializer.GetReadPos() != serializer.GetWritePos()) { if (ScanKeyWordInCPlusPlusFile(ENUM_KEYWORD_STR, &serializer)) { bool bIsKeyWord = IsEnumKeyword(&serializer); uint32_t startPos = serializer.GetReadPos(); startPos += (uint32_t)strlen(ENUM_KEYWORD_STR); serializer.SetReadPos(startPos); if (bIsKeyWord && ScanKeyWordInCPlusPlusFile("{", &serializer)) { uint32_t endPos = serializer.GetReadPos(); uint32_t enumNameLength = endPos - startPos; char* enumName = new char[enumNameLength + 1]; enumName[enumNameLength] = 0; serializer.SetReadPos(startPos); serializer.Deserialize(enumName, enumNameLength); char* enumNewName = new char[enumNameLength + 1]; enumNewName[enumNameLength] = 0; FilterCPlusPlusFileComments(enumName, enumNewName, enumNameLength); BEATS_SAFE_DELETE_ARRAY(enumName); BEATS_ASSERT(serializer.GetReadPos() == endPos); std::set<TString> filters; filters.insert(_T("\r\n")); filters.insert(_T(" ")); filters.insert(_T("\n")); filters.insert(_T("class"));// such as enum class ETest{} TString strEnumName = CStringHelper::GetInstance()->FilterString(enumNewName, filters); BEATS_SAFE_DELETE_ARRAY(enumNewName); int nFindColonPos = CStringHelper::GetInstance()->FindFirstString(strEnumName.c_str(), ":", false); if (nFindColonPos != TString::npos) { strEnumName = strEnumName.substr(0, nFindColonPos); } std::map<TString, SEnumScanData*>::iterator iter = m_enumStrPool.find(strEnumName.c_str()); if (pSpecifyEnumName == NULL || _tcscmp(pSpecifyEnumName, strEnumName.c_str()) == 0) { bool bExisting = iter != m_enumStrPool.end(); BEATS_WARNING(!bExisting, _T("The enum type %s in %s is already scanned in %s, it may be you have scaned same file twice or a enum type with same name under different name space."), strEnumName.c_str(), pFileName, iter->second->m_enumFilePath.c_str()); // If the length is 0, it means we meet no name enum declare or a typedef. if (strEnumName.length() != 0 && !bExisting) { startPos = endPos + 1; // Escape "{" ScanKeyWordInCPlusPlusFile("}", &serializer); endPos = serializer.GetReadPos(); serializer.SetReadPos(startPos); uint32_t dataLength = endPos - startPos; char* textBuff = new char[dataLength + 1]; textBuff[dataLength] = 0; serializer.Deserialize(textBuff, dataLength); BEATS_ASSERT(serializer.GetReadPos() == endPos); char* newTextBuff = new char[dataLength + 1]; newTextBuff[dataLength] = 0; uint32_t length = 0; FilterCPlusPlusFileComments(textBuff, newTextBuff, length); BEATS_SAFE_DELETE_ARRAY(textBuff); TString strNewText = CStringHelper::GetInstance()->FilterString(newTextBuff, filters); BEATS_SAFE_DELETE_ARRAY(newTextBuff); SEnumScanData* pEnumData = new SEnumScanData; std::vector<TString> rawEnumString; CStringHelper::GetInstance()->SplitString(strNewText.c_str(), _T(","), rawEnumString); int iDefaultEnumValue = 0; for (uint32_t i = 0; i < rawEnumString.size(); ++i) { // The last enum string could be empty, such as // enum {E_1, E_2,} if (!rawEnumString[i].empty()) { SEnumData* pData = AnalyseRawEnumString(rawEnumString[i], iDefaultEnumValue); pEnumData->m_enumValue.push_back(pData); } else { BEATS_ASSERT(i == rawEnumString.size() - 1); } } pEnumData->m_enumFilePath.assign(pFileName); m_enumStrPool[strEnumName] = pEnumData; bRet = true; } } } } } return bRet; }
bool CSkin::Load() { bool bRet = false; BEATS_ASSERT(!IsLoaded(), _T("Can't Load a skin which is already loaded!")); if (m_pSkinMaterial == NULL) { m_pSkinMaterial = new CMaterial(); m_pSkinMaterial->SetSharders( _T("SkinShader.vs"), _T("SkinShader.ps")); m_pSkinMaterial->GetRenderState()->SetBoolState(CBoolRenderStateParam::eBSP_DepthTest, true); m_pSkinMaterial->GetRenderState()->SetBoolState(CBoolRenderStateParam::eBSP_Blend, false); m_pSkinMaterial->GetRenderState()->SetBoolState(CBoolRenderStateParam::eBSP_ScissorTest, false); m_pSkinMaterial->Initialize(); } // Load From File const TString& strFilePath = GetFilePath(); if (!strFilePath.empty()) { CSerializer serializer(strFilePath.c_str()); size_t uMeshcount = 0; serializer >> uMeshcount; // HACK: TODO: temp fix uMeshcount = 1; for (size_t i = 0; i < uMeshcount; ++i) { std::vector<CVertexPTB> vertices; std::vector<unsigned short> indices; size_t uMaterialCount = 0; serializer >> uMaterialCount; BEATS_ASSERT(uMaterialCount == 1, _T("Only support one material!")); for (size_t j = 0; j < uMaterialCount; ++j) { TString strTextureName; serializer >> strTextureName; BEATS_ASSERT(!strTextureName.empty(), _T("Texutre can't be empty in skin!")); SharePtr<CTexture> pTexture = CResourceManager::GetInstance()->GetResource<CTexture>(strTextureName); BEATS_ASSERT(pTexture != NULL); m_pSkinMaterial->SetTexture(0, pTexture); } CSerializer tmpVerticesBufferPos, tmpVerticesBufferUV; size_t uVertexCount = 0; serializer >> uVertexCount; for (size_t k = 0; k < uVertexCount; ++k) { CVertexPTB vertexPTB; serializer >> vertexPTB.position.x >> vertexPTB.position.y >> vertexPTB.position.z >> vertexPTB.tex.u >> vertexPTB.tex.v; serializer >> vertexPTB.bones.x; serializer >> vertexPTB.weights.x; serializer >> vertexPTB.bones.y; serializer >> vertexPTB.weights.y; serializer >> vertexPTB.bones.z; serializer >> vertexPTB.weights.z; serializer >> vertexPTB.bones.w; serializer >> vertexPTB.weights.w; vertices.push_back(vertexPTB); #ifdef _DEBUG float sum = vertexPTB.weights.x + vertexPTB.weights.y + vertexPTB.weights.z + vertexPTB.weights.w; BEATS_ASSERT(sum < 1.01F, _T("Weight can't be greater than 1.01F, cur Value : %f!"), sum); BEATS_WARNING(sum > 0.99F, _T("Weight can't be smaller than 0.99F, cur Value : %f!"), sum); #endif } size_t uIndexCount = 0; serializer >> uIndexCount; for (size_t l = 0; l < uIndexCount; ++l) { int nIndex = 0; serializer >> nIndex; BEATS_ASSERT(nIndex < (int)vertices.size() && nIndex < 0xFFFF, _T("Invalid index %d"), nIndex); indices.push_back((unsigned short)nIndex); } CRenderGroup *p3DRenderGroup = CRenderGroupManager::GetInstance()->GetRenderGroup(CRenderGroupManager::LAYER_3D); CRenderBatch* pRenderBatch = p3DRenderGroup->GetRenderBatch(VERTEX_FORMAT(CVertexPTB), m_pSkinMaterial, GL_TRIANGLES, true); pRenderBatch->SetStatic(true); pRenderBatch->AddIndexedVertices(vertices.data(), vertices.size(), indices.data(), indices.size()); pRenderBatch->SetGroup(p3DRenderGroup); bool bAlreadyExists = false; for (size_t w = 0; w < m_renderBatches.size(); ++w) { if (m_renderBatches[w] == pRenderBatch) { bAlreadyExists = true; break; } } if (!bAlreadyExists) { m_renderBatches.push_back(pRenderBatch); } } bRet = true; }
const CFontGlyph *CFreetypeFontFace::PrepareChar(wchar_t character, bool& bGlyphRestFlag) { bGlyphRestFlag = false; m_glyphMapLocker.lock(); auto itr = m_glyphMap.find(character); CFreetypeFontGlyph *pGlyph = itr != m_glyphMap.end() ? down_cast<CFreetypeFontGlyph *>(itr->second) : nullptr; m_glyphMapLocker.unlock(); if (!pGlyph) { float outlineWidth = GetBorderWeight() * GetScaleFactor(); ApplyFTSize(); FT_Face pFontFace = m_pFont->GetFontFace(); BEATS_ASSERT(pFontFace != NULL); bool bFindCharacterGlyph = FT_Get_Char_Index(pFontFace, character) != 0; BEYONDENGINE_UNUSED_PARAM(bFindCharacterGlyph); BEATS_ASSERT(bFindCharacterGlyph, _T("Character %d can't be found in all font face!"), character); FT_Error err = FT_Load_Char(pFontFace, character, FT_LOAD_NO_BITMAP); BEYONDENGINE_UNUSED_PARAM(err); BEATS_ASSERT(!err); FT_GlyphSlot pGlyphSlot = pFontFace->glyph; BEATS_ASSERT(pGlyphSlot != NULL); int32_t nBorderAdvanceX = pGlyphSlot->metrics.horiAdvance >> FT_SHIFT_NUM; int32_t nBorderAdvanceY = m_nLineHeight + (uint32_t)ceil(outlineWidth * 2.0f); int32_t nFontAdvanceX = nBorderAdvanceX; int32_t nFontHeight = 0; int32_t nBorderOriginWidth = 0; int32_t nFontOriginWidth = 0; int32_t nBorderHeight = 0; FT_BBox borderBox; FT_BBox fontBox; int32_t x = 0, y = 0; if (pGlyphSlot->format == FT_GLYPH_FORMAT_OUTLINE) { FT_Library ftLib = CFont::GetLibrary(); // Set up a stroker. FT_Stroker stroker; FT_Stroker_New(ftLib, &stroker); FT_Stroker_Set(stroker, (int32_t)(outlineWidth * 64), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); FT_Glyph pOutlineGlyph, pInnerGlyph; if (FT_Get_Glyph(pGlyphSlot, &pOutlineGlyph) == 0 && FT_Get_Glyph(pGlyphSlot, &pInnerGlyph) == 0) { FT_Glyph_StrokeBorder(&pOutlineGlyph, stroker, 0, 1); BEATS_ASSERT(pOutlineGlyph->format == FT_GLYPH_FORMAT_OUTLINE && pInnerGlyph->format == FT_GLYPH_FORMAT_OUTLINE); FT_Outline *pOutLine = &reinterpret_cast<FT_OutlineGlyph>(pOutlineGlyph)->outline; FT_Glyph_Get_CBox(pOutlineGlyph, FT_GLYPH_BBOX_GRIDFIT, &borderBox); FT_Glyph_Get_CBox(pInnerGlyph, FT_GLYPH_BBOX_GRIDFIT, &fontBox); nBorderOriginWidth = (borderBox.xMax - borderBox.xMin) >> FT_SHIFT_NUM; nFontOriginWidth = (fontBox.xMax - fontBox.xMin) >> FT_SHIFT_NUM; int32_t nBorderWidth = nextMOE(nBorderOriginWidth); // Because our GL_UNPACK_ALIGNMENT should be 8 here. nBorderHeight = (borderBox.yMax - borderBox.yMin) >> FT_SHIFT_NUM; nFontHeight = (fontBox.yMax - fontBox.yMin) >> FT_SHIFT_NUM; x = pGlyphSlot->metrics.horiBearingX >> FT_SHIFT_NUM; y = pGlyphSlot->metrics.horiBearingY >> FT_SHIFT_NUM; if(nBorderAdvanceX < x + nBorderOriginWidth) // It is true for most of the time, because border size always greater than nAdvanceX { nBorderAdvanceX = x + nBorderOriginWidth; } if (nFontAdvanceX < x + nFontOriginWidth) { nFontAdvanceX = nFontOriginWidth; } if(m_uCurrX + x + nBorderWidth > PAGE_WIDTH) { m_uCurrX = 0; m_uCurrY += (nBorderAdvanceY + m_nBorderSpace); if (m_uCurrY + nBorderAdvanceY > PAGE_HEIGHT) { BEATS_WARNING(false, "Freetype texture buffer overflow for %d glyphs, we will rebuild this texture buffer.", (uint32_t)m_glyphMap.size()); ResetGlyphs(); bGlyphRestFlag = true; return nullptr; } } int32_t nDataSize = nBorderWidth * nBorderHeight; float fBorderOffsetY = 1.0f; // Makes it look like a shadow. unsigned char* pBorderData = RenderFontDataToBmp(nBorderWidth, nBorderHeight, -borderBox.xMin, (int32_t)(-borderBox.yMin * fBorderOffsetY), pOutLine); FT_Outline *pInnerOutLine = &reinterpret_cast<FT_OutlineGlyph>(pInnerGlyph)->outline; unsigned char* pFontData = RenderFontDataToBmp(nBorderWidth, nBorderHeight, -borderBox.xMin, -borderBox.yMin, pInnerOutLine); unsigned char* pAllData = new unsigned char[nDataSize * 2]; for (int32_t i = 0; i < nDataSize; ++i) { pAllData[i * 2] = pBorderData[i]; pAllData[i * 2 + 1] = pFontData[i]; } BEATS_ASSERT(m_pTexture.Get() != nullptr); GLint nX = MAX((int32_t)m_uCurrX + x, 0); GLint nY = MAX((int32_t)m_uCurrY + (m_nAscender - y), 0); SFontUpdateImageInfo* pImageInfo = new SFontUpdateImageInfo; pImageInfo->m_pTexture = m_pTexture; pImageInfo->m_nWidth = nBorderWidth; pImageInfo->m_nHeight = nBorderHeight; pImageInfo->m_x = nX; pImageInfo->m_y = nY; pImageInfo->m_pData = pAllData; m_fontUpdateImageCacheMutex.lock(); m_fontUpdateImageCache.push_back(pImageInfo); m_fontUpdateImageCacheMutex.unlock(); // Clean up afterwards. FT_Stroker_Done(stroker); FT_Done_Glyph(pOutlineGlyph); FT_Done_Glyph(pInnerGlyph); BEATS_SAFE_DELETE_ARRAY(pBorderData); BEATS_SAFE_DELETE_ARRAY(pFontData); }