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);
    }
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
            }