//////////////////////////////////////////////////////////////////////////// // // Crytek Engine Source File. // Copyright (C), Crytek Studios, 2002. // ------------------------------------------------------------------------- // File name: LeafBufferSerialize.cpp // Version: v1.00 // Created: 28/8/2001 by Vladimir Kajalin // Compilers: Visual Studio.NET // Description: LeafBuffer serialization // ------------------------------------------------------------------------- // History: // //////////////////////////////////////////////////////////////////////////// #include "RenderPCH.h" #include "cryheaders.h" #include "nvtristrip/nvtristrip.h" #include "serializebuffer.h" #include "MakMatInfoFromMAT_ENTITY.h" CryIRGB CF2IRGB(CFColor in) { CryIRGB out; out.r = uchar(in.r*255); out.g = uchar(in.g*255); out.b = uchar(in.b*255); return out; } char *SkipPath (char *pathname) { char *last; last = pathname; while (*pathname) { if (*pathname=='/' || *pathname=='\\') last = pathname+1; pathname++; } return last; } int CLeafBuffer__SetTexType(TextureMap3 *tm) { if (tm->type == TEXMAP_CUBIC) return eTT_Cubemap; else if (tm->type == TEXMAP_AUTOCUBIC) return eTT_AutoCubemap; return eTT_Base; } bool CLeafBuffer::Serialize(int & nPos, uchar * pSerBuf, bool bSave, char * _szFolderName, char * _szFileName, double & dCIndexedMesh__LoadMaterial) { // Load int i; char szSignature[16]=""; if(!LoadBuffer(szSignature, 11, pSerBuf, nPos) || strcmp(szSignature,"LeafBuffer")) return false; LoadBuffer(&m_SecVertCount, sizeof(m_SecVertCount), pSerBuf, nPos); if((*((int*)&pSerBuf[nPos]))) m_arrVertStripMap = new uint[(*((int*)&pSerBuf[nPos]))]; LoadBuffer( m_arrVertStripMap, m_SecVertCount*sizeof(m_arrVertStripMap[0]), pSerBuf, nPos); m_SecIndices.LoadFromBuffer(pSerBuf, nPos); m_NumIndices = m_SecIndices.Num(); if((*((int*)&pSerBuf[nPos])) && !m_pIndicesPreStrip) m_pIndicesPreStrip = new list2; m_pIndicesPreStrip->LoadFromBuffer(pSerBuf, nPos); LoadBuffer(&m_nPrimetiveType,sizeof(m_nPrimetiveType), pSerBuf, nPos); if((*((int*)&pSerBuf[nPos]))) { m_pLoadedColors = new Vec3d[(*((int*)&pSerBuf[nPos]))/sizeof(m_pLoadedColors[0])]; assert((*((int*)&pSerBuf[nPos]))/sizeof(m_pLoadedColors[0]) == m_SecVertCount); } LoadBuffer( m_pLoadedColors, m_SecVertCount*sizeof(m_pLoadedColors[0]), pSerBuf, nPos); // load mat info m_pMats = new list2; m_bMaterialsWasCreatedInRenderer = true; m_pMats->LoadFromBuffer(pSerBuf, nPos); // create materaial for (i=0; iCount(); i++) { m_pMats->GetAt(i).pRE = 0; MAT_ENTITY * pMatEnt = new MAT_ENTITY; LoadBuffer(pMatEnt, sizeof(*pMatEnt), pSerBuf, nPos); m_pMats->Get(i)->pMatEnt = pMatEnt; // skip loading of fake mats if(m_pMats->Get(i)->nNumIndices && m_pMats->Get(i)->nNumVerts) if(_szFileName && _szFolderName) { AUTO_PROFILE_SECTION(iSystem->GetITimer(), dCIndexedMesh__LoadMaterial); CIndexedMesh__LoadMaterial(_szFileName, _szFolderName, m_pMats->GetAt(i), gRenDev, pMatEnt); } delete m_pMats->Get(i)->pMatEnt; m_pMats->Get(i)->pMatEnt=0; if(m_pMats->GetAt(i).m_dwNumSections) { m_pMats->GetAt(i).m_pPrimitiveGroups = new SPrimitiveGroup[m_pMats->GetAt(i).m_dwNumSections]; LoadBuffer((void*)m_pMats->GetAt(i).m_pPrimitiveGroups, sizeof(SPrimitiveGroup)*m_pMats->GetAt(i).m_dwNumSections, pSerBuf, nPos); } } // make system vert buffer m_pSecVertBuffer = new CVertexBuffer(); LoadBuffer( m_pSecVertBuffer, sizeof(CVertexBuffer), pSerBuf, nPos); // need to restore // load positions if(*((int*)&pSerBuf[nPos])) { assert(m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData); // should not be zero before saving m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData = new uchar[m_SecVertCount*m_VertexSize[m_pSecVertBuffer->m_vertexformat]]; } else assert(!m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData); assert(m_SecVertCount*m_VertexSize[m_pSecVertBuffer->m_vertexformat] == (*((int*)&pSerBuf[nPos]))); LoadBuffer( m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData, m_SecVertCount*m_VertexSize[m_pSecVertBuffer->m_vertexformat], pSerBuf, nPos); // load tangents if(*((int*)&pSerBuf[nPos])) { assert(m_pSecVertBuffer->m_VS[VSF_TANGENTS].m_VData); // should not be zero before saving m_pSecVertBuffer->m_VS[VSF_TANGENTS].m_VData = new SPipTangents[m_SecVertCount]; } else assert(!m_pSecVertBuffer->m_VS[VSF_TANGENTS].m_VData); assert(m_SecVertCount*sizeof(SPipTangents) == (*((int*)&pSerBuf[nPos]))); LoadBuffer( m_pSecVertBuffer->m_VS[VSF_TANGENTS].m_VData, m_SecVertCount*sizeof(SPipTangents), pSerBuf, nPos); assert(!m_pVertexBuffer); // not needed LoadBuffer(&m_vBoxMax, sizeof(m_vBoxMax), pSerBuf, nPos); LoadBuffer(&m_vBoxMin, sizeof(m_vBoxMin), pSerBuf, nPos); int bHasVtxMap = 0; LoadBuffer(&bHasVtxMap, sizeof(bHasVtxMap), pSerBuf,nPos); if (bHasVtxMap) { m_arrVtxMap = new uint[m_SecVertCount]; LoadBuffer(m_arrVtxMap, sizeof(uint)*m_SecVertCount, pSerBuf,nPos); } // make REs for (i=0; i<(*m_pMats).Count(); i++) { if(m_pMats->Get(i)->nNumIndices && m_pMats->Get(i)->nNumVerts) { CREOcLeaf *re = (CREOcLeaf *)gRenDev->EF_CreateRE(eDATA_OcLeaf); re->m_pChunk = &(*m_pMats)[i]; re->m_pBuffer = this; assert (re->m_pChunk->nNumIndices < 60000); re->m_pChunk->pRE = re; // set sort offset // IShader * ef = m_pMats->Get(i)->shaderItem.m_pShader->GetTemplate(-1); // bool bTwoSided = ef && (ef->GetCull() == eCULL_None); bool bTwoSided = (m_pMats->Get(i)->shaderItem.m_pShaderResources->m_ResFlags & MTLFLAG_2SIDED)!=0;//ef && (ef->GetCull() == e CULL_None); re->m_SortId = i + 2*(!bTwoSided); // render double sided leafs last } else (*m_pMats)[i].pRE = 0; } return 0; } bool CLeafBuffer::LoadMaterial(int m, const char *szFileName, const char *szFolderName, list2 & lstMatTable, IRenderer * pRenderer, MAT_ENTITY * me, bool bFake) { if(m<0 || bFake)//!pCGF->m_lstMaterials[m].IsStdMat) { CMatInfo fake; lstMatTable.Add(fake); return false; } // assert(strlen(szFolderName)+strlen(pCGF->m_lstMaterials[m].map_d.name)<1024); // m_pSystem->GetIConsole()->Exit("LoadCGF: texture path len error"); SInputShaderResources Res; memset(&Res, 0, sizeof(Res)); SLightMaterial LMs; // MAT_ENTITY *me = &pCGF->m_lstMaterials[m]; if (me->m_New && (me->col_d.r>5 || me->col_d.g>5 || me->col_d.b>5 || me->col_s.r>5 || me->col_s.g>5 || me->col_s.b>5)) { Res.m_LMaterial = &LMs; Res.m_LMaterial->Front.m_Ambient = CFColor(me->col_a.r/255.f,me->col_a.g/255.f,me->col_a.b/255.f); Res.m_LMaterial->Front.m_Diffuse = CFColor(me->col_d.r/255.f,me->col_d.g/255.f,me->col_d.b/255.f); Res.m_LMaterial->Front.m_Specular = CFColor(me->col_s.r/255.f,me->col_s.g/255.f,me->col_s.b/255.f); Res.m_LMaterial->Front.m_Specular *= me->specLevel; Res.m_LMaterial->Front.m_Specular.Clamp(); Res.m_LMaterial->Front.m_Emission = Res.m_LMaterial->Front.m_Diffuse * me->selfIllum; Res.m_LMaterial->Front.m_SpecShininess = me->specShininess; } char diffuse[256]=""; strcpy(diffuse, me->map_d.name); char bump[256]=""; strcpy(bump, me->map_b.name); char normalmap[256]=""; if(me->map_displ.name[0] && (me->flags & MTLFLAG_CRYSHADER)) strcpy(normalmap, me->map_displ.name); char opacity[256]=""; char decal[256]=""; if(me->map_o.name[0]) { if (me->flags & MTLFLAG_CRYSHADER) strcpy(decal, me->map_o.name); else strcpy(opacity, me->map_o.name); } char gloss[256]=""; if(me->map_g.name[0]) strcpy(gloss, me->map_g.name); char cubemap[256]=""; char env[256]=""; if(me->map_e.name[0]) strcpy(env, me->map_e.name); char spec[256]=""; if(me->map_s.name[0]) strcpy(spec, me->map_s.name); char det[256]=""; if(me->map_detail.name[0]) strcpy(det, me->map_detail.name); char subsurf[256]=""; if(me->map_subsurf.name[0]) strcpy(subsurf, me->map_subsurf.name); char refl[256]=""; if(me->map_e.name[0]) strcpy(refl, me->map_e.name); char * mat_name = me->name; // fill MatInfo struct CMatInfo & newMat = lstMatTable[m]; // strcpy(newMat.szDiffuse, diffuse); if (me->Dyn_Bounce == 1.0f) newMat.m_Flags |= MIF_PHYSIC; if (me->Dyn_StaticFriction == 1.0f) newMat.m_Flags |= MIF_NOCASTSHADOWS; /* if (nLM > 0) { Res.m_Textures[EFTT_LIGHTMAP].m_TU.m_ITexPic = m_pSystem->GetIRenderer()->EF_GetTextureByID(nLM); Res.m_Textures[EFTT_LIGHTMAP].m_Name = Res.m_Textures[EFTT_LIGHTMAP].m_TU.m_ITexPic->GetName(); } if (nLM_LD > 0) { Res.m_Textures[EFTT_LIGHTMAP_DIR].m_TU.m_ITexPic = m_pSystem->GetIRenderer()->EF_GetTextureByID(nLM_LD); Res.m_Textures[EFTT_LIGHTMAP_DIR].m_Name = Res.m_Textures[EFTT_LIGHTMAP].m_TU.m_ITexPic->GetName(); }*/ Res.m_TexturePath = szFolderName; Res.m_Textures[EFTT_DIFFUSE].m_Name = diffuse; Res.m_Textures[EFTT_GLOSS].m_Name = gloss; Res.m_Textures[EFTT_SUBSURFACE].m_Name = subsurf; Res.m_Textures[EFTT_BUMP].m_Name = bump; Res.m_Textures[EFTT_NORMALMAP].m_Name = normalmap; Res.m_Textures[EFTT_CUBEMAP].m_Name = cubemap[0] ? cubemap : env; Res.m_Textures[EFTT_SPECULAR].m_Name = spec; Res.m_Textures[EFTT_DETAIL_OVERLAY].m_Name = det; Res.m_Textures[EFTT_OPACITY].m_Name = opacity; Res.m_Textures[EFTT_DECAL_OVERLAY].m_Name = decal; Res.m_Textures[EFTT_SUBSURFACE].m_Name = subsurf; Res.m_Textures[EFTT_REFLECTION].m_Name = refl; Res.m_Textures[EFTT_REFLECTION].m_TU.m_eTexType = (ETexType)SetTexType(&me->map_e); Res.m_Textures[EFTT_CUBEMAP].m_TU.m_eTexType = (ETexType)SetTexType(&me->map_e); Res.m_Textures[EFTT_SUBSURFACE].m_TU.m_eTexType = (ETexType)SetTexType(&me->map_subsurf); Res.m_Textures[EFTT_BUMP].m_TU.m_eTexType = eTT_Bumpmap; Res.m_ResFlags = me->flags; Res.m_Opacity = me->opacity; Res.m_AlphaRef = me->Dyn_SlidingFriction; if (me->flags & MTLFLAG_CRYSHADER) Res.m_AlphaRef = me->alpharef; if (decal[0]) Res.m_Textures[EFTT_DECAL_OVERLAY].m_Amount = me->map_o.Amount; Res.m_Textures[EFTT_DIFFUSE].m_Amount = me->map_d.Amount; Res.m_Textures[EFTT_BUMP].m_Amount = me->map_b.Amount; if (me->flags & MTLFLAG_CRYSHADER) Res.m_Textures[EFTT_NORMALMAP].m_Amount = me->map_displ.Amount; Res.m_Textures[EFTT_OPACITY].m_Amount = me->map_o.Amount; Res.m_Textures[EFTT_REFLECTION].m_Amount = me->map_e.Amount; Res.m_Textures[EFTT_SUBSURFACE].m_Amount = me->map_subsurf.Amount; Res.m_Textures[EFTT_DIFFUSE].m_TexFlags = me->map_d.flags; //Res.m_Textures[EFTT_SUBSURFACE].m_TexFlags = me->map_d.flags; Res.m_Textures[EFTT_GLOSS].m_TexFlags = me->map_g.flags; Res.m_Textures[EFTT_BUMP].m_TexFlags = me->map_b.flags; Res.m_Textures[EFTT_CUBEMAP].m_TexFlags = me->map_e.flags; Res.m_Textures[EFTT_SPECULAR].m_TexFlags = me->map_s.flags; Res.m_Textures[EFTT_DETAIL_OVERLAY].m_TexFlags = me->map_detail.flags; Res.m_Textures[EFTT_SUBSURFACE].m_TexFlags = me->map_subsurf.flags; if (!Res.m_Textures[EFTT_DETAIL_OVERLAY].m_Name.empty()) { Res.m_Textures[EFTT_DETAIL_OVERLAY].m_TexModificator.m_Tiling[0] = me->map_detail.uscl_val; Res.m_Textures[EFTT_DETAIL_OVERLAY].m_TexModificator.m_Tiling[1] = me->map_detail.vscl_val; } if (!Res.m_Textures[EFTT_OPACITY].m_Name.empty()) { Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Tiling[0] = me->map_o.uscl_val; Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Tiling[1] = me->map_o.vscl_val; Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Rot[0] = Degr2Word(me->map_o.urot_val); Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Rot[1] = Degr2Word(me->map_o.vrot_val); Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Offs[0] = me->map_o.uoff_val; Res.m_Textures[EFTT_OPACITY].m_TexModificator.m_Offs[1] = me->map_o.voff_val; Res.m_Textures[EFTT_OPACITY].m_bUTile = me->map_o.utile; Res.m_Textures[EFTT_OPACITY].m_bVTile = me->map_o.vtile; } if (!Res.m_Textures[EFTT_DECAL_OVERLAY].m_Name.empty()) { Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Tiling[0] = me->map_o.uscl_val; Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Tiling[1] = me->map_o.vscl_val; Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Rot[0] = Degr2Word(me->map_o.urot_val); Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Rot[1] = Degr2Word(me->map_o.vrot_val); Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Offs[0] = me->map_o.uoff_val; Res.m_Textures[EFTT_DECAL_OVERLAY].m_TexModificator.m_Offs[1] = me->map_o.voff_val; Res.m_Textures[EFTT_DECAL_OVERLAY].m_bUTile = me->map_o.utile; Res.m_Textures[EFTT_DECAL_OVERLAY].m_bVTile = me->map_o.vtile; } char mName[128]; strcpy(mName, mat_name); char *str = strchr(mat_name, '/'); if (str) { mName[str-mat_name] = 0; strncpy(newMat.sScriptMaterial, &str[1], sizeof(newMat.sScriptMaterial)); newMat.sScriptMaterial[sizeof(newMat.sScriptMaterial)-1]=0; } else { newMat.sScriptMaterial[0] = 0; } char *templName = NULL;; if(strnicmp(mName, "$s_",3)==0) { templName = &mName[3]; } else if(str=strchr(mName, '(')) { mName[str-mName] = 0; templName = &mName[str-mName+1]; if(str=strchr(templName, ')')) templName[str-templName] = 0; } uchar nInvert = 0; if (templName && templName[0] == '#') { templName++; nInvert = 1; } // strcpy(newMat.szMatName, mName); // load shader if(mName[0]==0) strcpy(mName,"nodraw"); newMat.shaderItem = pRenderer->EF_LoadShaderItem(mName, eSH_World, true, templName, 0, &Res); //newMat.shaderItem->m_pShader->AdjustResources(newMat.shaderItem->m_pShaderResources); //IShader * ef = newMat.shaderItem.m_pShader->GetTemplate(-1); //if(ef->GetPhysMaterialFlags() & MATF_NOCLIP) // newMat.m_Flags &= ~MIF_PHYSIC; // strcpy(newMat.szFolderName, szFolderName); // remember polybump state newMat.m_Flags &= ~MIF_POLYBUMP; // pFace->shader_id = m_lstMatTable.Count(); newMat.fAlpha = me->opacity; return true; } int CLeafBuffer::SetTexType(TextureMap3 *tm) { if (tm->type == TEXMAP_CUBIC) return eTT_Cubemap; else if (tm->type == TEXMAP_AUTOCUBIC) return eTT_AutoCubemap; return eTT_Base; }