void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName, const char *pNewKey, const char *pNewValue ) { char oldVMTFile[ 512 ]; char newVMTFile[ 512 ]; AddNewTranslation( pOriginalMaterialName, pNewMaterialName ); sprintf( oldVMTFile, "materials/%s.vmt", pOriginalMaterialName ); sprintf( newVMTFile, "materials/%s.vmt", pNewMaterialName ); // printf( "Creating material patch file %s which points at %s\n", newVMTFile, oldVMTFile ); KeyValues *kv = new KeyValues( "patch" ); if ( !kv ) { Error( "Couldn't allocate KeyValues for %s!!!", pNewMaterialName ); } kv->SetString( "include", oldVMTFile ); KeyValues *section = kv->FindKey( "insert", true ); section->SetString( pNewKey, pNewValue ); // Write patched .vmt into a memory buffer CUtlBuffer buf( 0, 0, true ); kv->RecursiveSaveToFile( buf, 0 ); // Add to pak file for this .bsp AddBufferToPack( newVMTFile, (void*)buf.Base(), buf.TellPut(), true ); // Cleanup kv->deleteThis(); }
void CreateDefaultCubemaps( bool bHDR ) { memset( g_IsCubemapTexData, 0, sizeof(g_IsCubemapTexData) ); // NOTE: This implementation depends on the fact that all VTF files contain // all mipmap levels const char *pSkyboxBaseName = FindSkyboxMaterialName(); char skyboxMaterialName[MAX_PATH]; Q_snprintf( skyboxMaterialName, MAX_PATH, "skybox/%s", pSkyboxBaseName ); IVTFTexture *pSrcVTFTextures[6]; if( !skyboxMaterialName ) { if( s_DefaultCubemapNames.Count() ) { Warning( "This map uses env_cubemap, and you don't have a skybox, so no default env_cubemaps will be generated.\n" ); } return; } int unionTextureFlags = 0; if( !LoadSrcVTFFiles( pSrcVTFTextures, skyboxMaterialName, &unionTextureFlags, bHDR ) ) { Warning( "Can't load skybox file %s to build the default cubemap!\n", skyboxMaterialName ); return; } Msg( "Creating default %scubemaps for env_cubemap using skybox materials:\n%s*.vmt\n" "Run buildcubemaps in the engine to get the correct cube maps.\n\n", bHDR ? "HDR " : "", skyboxMaterialName ); // Figure out the mip differences between the two textures int iMipLevelOffset = 0; int tmp = pSrcVTFTextures[0]->Width(); while( tmp > DEFAULT_CUBEMAP_SIZE ) { iMipLevelOffset++; tmp >>= 1; } // Create the destination cubemap IVTFTexture *pDstCubemap = CreateVTFTexture(); pDstCubemap->Init( DEFAULT_CUBEMAP_SIZE, DEFAULT_CUBEMAP_SIZE, 1, pSrcVTFTextures[0]->Format(), unionTextureFlags | TEXTUREFLAGS_ENVMAP, pSrcVTFTextures[0]->FrameCount() ); // First iterate over all frames for (int iFrame = 0; iFrame < pDstCubemap->FrameCount(); ++iFrame) { // Next iterate over all normal cube faces (we know there's 6 cause it's an envmap) for (int iFace = 0; iFace < 6; ++iFace ) { // Finally, iterate over all mip levels in the *destination* for (int iMip = 0; iMip < pDstCubemap->MipCount(); ++iMip ) { // Copy the bits from the source images into the cube faces unsigned char *pSrcBits = pSrcVTFTextures[iFace]->ImageData( iFrame, 0, iMip + iMipLevelOffset ); unsigned char *pDstBits = pDstCubemap->ImageData( iFrame, iFace, iMip ); int iSize = pDstCubemap->ComputeMipSize( iMip ); memcpy( pDstBits, pSrcBits, iSize ); } } } ImageFormat originalFormat = pDstCubemap->Format(); if( !bHDR ) { // Convert the cube to format that we can apply tools to it... pDstCubemap->ConvertImageFormat( IMAGE_FORMAT_DEFAULT, false ); } // Fixup the cubemap facing pDstCubemap->FixCubemapFaceOrientation(); // Now that the bits are in place, compute the spheremaps... pDstCubemap->GenerateSpheremap(); if( !bHDR ) { // Convert the cubemap to the final format pDstCubemap->ConvertImageFormat( originalFormat, false ); } // Write the puppy out! char dstVTFFileName[1024]; if( bHDR ) { sprintf( dstVTFFileName, "materials/maps/%s/cubemapdefault.hdr.vtf", mapbase ); } else { sprintf( dstVTFFileName, "materials/maps/%s/cubemapdefault.vtf", mapbase ); } CUtlBuffer outputBuf; if (!pDstCubemap->Serialize( outputBuf )) { Warning( "Error serializing default cubemap %s\n", dstVTFFileName ); return; } // spit out the default one. AddBufferToPack( dstVTFFileName, outputBuf.Base(), outputBuf.TellPut(), false ); // spit out all of the ones that are attached to world geometry. int i; for( i = 0; i < s_DefaultCubemapNames.Count(); i++ ) { char vtfName[MAX_PATH]; VTFNameToHDRVTFName( s_DefaultCubemapNames[i], vtfName, MAX_PATH, bHDR ); if( FileExistsInPack( vtfName ) ) { continue; } AddBufferToPack( vtfName, outputBuf.Base(),outputBuf.TellPut(), false ); } // Clean up the textures for( i = 0; i < 6; i++ ) { DestroyVTFTexture( pSrcVTFTextures[i] ); } DestroyVTFTexture( pDstCubemap ); }
//----------------------------------------------------------------------------- // Write the lighitng to bsp pak lump //----------------------------------------------------------------------------- void CVradStaticPropMgr::SerializeLighting() { char filename[MAX_PATH]; CUtlBuffer utlBuf; // illuminate them all int count = m_StaticProps.Count(); if ( !count ) { // nothing to do return; } char mapName[MAX_PATH]; Q_FileBase( source, mapName, sizeof( mapName ) ); int size; for (int i = 0; i < count; ++i) { sprintf( filename, "sp_%d.vhv", i ); int totalVertexes = 0; for ( int j=0; j<m_StaticProps[i].m_MeshData.Count(); j++ ) { totalVertexes += m_StaticProps[i].m_MeshData[j].m_Verts.Count(); } // allocate a buffer with enough padding for alignment size = sizeof( HardwareVerts::FileHeader_t ) + m_StaticProps[i].m_MeshData.Count()*sizeof(HardwareVerts::MeshHeader_t) + totalVertexes*4 + 2*512; utlBuf.EnsureCapacity( size ); Q_memset( utlBuf.Base(), 0, size ); HardwareVerts::FileHeader_t *pVhvHdr = (HardwareVerts::FileHeader_t *)utlBuf.Base(); // align to start of vertex data unsigned char *pVertexData = (unsigned char *)(sizeof( HardwareVerts::FileHeader_t ) + m_StaticProps[i].m_MeshData.Count()*sizeof(HardwareVerts::MeshHeader_t)); pVertexData = (unsigned char*)pVhvHdr + ALIGN_TO_POW2( (unsigned int)pVertexData, 512 ); // construct header pVhvHdr->m_nVersion = VHV_VERSION; pVhvHdr->m_nChecksum = m_StaticPropDict[m_StaticProps[i].m_ModelIdx].m_pStudioHdr->checksum; pVhvHdr->m_nVertexFlags = VERTEX_COLOR; pVhvHdr->m_nVertexSize = 4; pVhvHdr->m_nVertexes = totalVertexes; pVhvHdr->m_nMeshes = m_StaticProps[i].m_MeshData.Count(); for (int n=0; n<pVhvHdr->m_nMeshes; n++) { // construct mesh dictionary HardwareVerts::MeshHeader_t *pMesh = pVhvHdr->pMesh( n ); pMesh->m_nLod = m_StaticProps[i].m_MeshData[n].m_nLod; pMesh->m_nVertexes = m_StaticProps[i].m_MeshData[n].m_Verts.Count(); pMesh->m_nOffset = (unsigned int)pVertexData - (unsigned int)pVhvHdr; // construct vertexes for (int k=0; k<pMesh->m_nVertexes; k++) { Vector &vector = m_StaticProps[i].m_MeshData[n].m_Verts[k]; ColorRGBExp32 rgbColor; VectorToColorRGBExp32( vector, rgbColor ); unsigned char dstColor[4]; ConvertRGBExp32ToRGBA8888( &rgbColor, dstColor ); // b,g,r,a order pVertexData[0] = dstColor[2]; pVertexData[1] = dstColor[1]; pVertexData[2] = dstColor[0]; pVertexData[3] = dstColor[3]; pVertexData += 4; } } // align to end of file pVertexData = (unsigned char *)((unsigned int)pVertexData - (unsigned int)pVhvHdr); pVertexData = (unsigned char*)pVhvHdr + ALIGN_TO_POW2( (unsigned int)pVertexData, 512 ); AddBufferToPack( filename, (void*)pVhvHdr, pVertexData - (unsigned char*)pVhvHdr, false ); } }