コード例 #1
0
void SpewPerfStats( studiohdr_t *pStudioHdr, const char *pFilename, unsigned int flags )
{
	char							fileName[260];
	vertexFileHeader_t				*pNewVvdHdr;
	vertexFileHeader_t				*pVvdHdr = 0;
	OptimizedModel::FileHeader_t	*pVtxHdr = 0;
	studiohwdata_t					studioHWData;
	int								vvdSize = 0;
	const char						*prefix[] = {".dx80.vtx", ".dx90.vtx", ".sw.vtx"};
	s_pSavedSpewFunc				= NULL;
	if( !( flags & SPEWPERFSTATS_SHOWSTUDIORENDERWARNINGS ) )
	{
		s_pSavedSpewFunc = GetSpewOutputFunc();
		SpewOutputFunc( NullSpewOutputFunc );
	}

	// no stats on these
	if (!pStudioHdr->numbodyparts)
		return;

	// Need to update the render config to spew perf stats.
	UpdateStudioRenderConfig();

	// persist the vvd data
	Q_StripExtension( pFilename, fileName, sizeof( fileName ) );
	strcat( fileName, ".vvd" );

	if (FileExists( fileName ))
	{
		vvdSize = LoadFile( fileName, (void**)&pVvdHdr );
	}
	else
	{
		MdlError( "Could not open '%s'\n", fileName );
	}

	// validate header
	if (pVvdHdr->id != MODEL_VERTEX_FILE_ID)
	{
		MdlError( "Bad id for '%s' (got %d expected %d)\n", fileName, pVvdHdr->id, MODEL_VERTEX_FILE_ID);
	}
	if (pVvdHdr->version != MODEL_VERTEX_FILE_VERSION)
	{
		MdlError( "Bad version for '%s' (got %d expected %d)\n", fileName, pVvdHdr->version, MODEL_VERTEX_FILE_VERSION);
	}
	if (pVvdHdr->checksum != pStudioHdr->checksum)
	{
		MdlError( "Bad checksum for '%s' (got %d expected %d)\n", fileName, pVvdHdr->checksum, pStudioHdr->checksum);
	}

	if (pVvdHdr->numFixups)
	{
		// need to perform mesh relocation fixups
		// allocate a new copy
		pNewVvdHdr = (vertexFileHeader_t *)malloc( vvdSize );
		if (!pNewVvdHdr)
		{
			MdlError( "Error allocating %d bytes for Vertex File '%s'\n", vvdSize, fileName );
		}

		Studio_LoadVertexes( pVvdHdr, pNewVvdHdr, 0, true );

		// discard original
		free( pVvdHdr );

		pVvdHdr = pNewVvdHdr;
	}
	
	// iterate all ???.vtx files
	for (int j=0; j<sizeof(prefix)/sizeof(prefix[0]); j++)
	{
		// make vtx filename
		Q_StripExtension( pFilename, fileName, sizeof( fileName ) );
		strcat( fileName, prefix[j] );

		// persist the vtx data
		if (FileExists(fileName))
		{
			LoadFile( fileName, (void**)&pVtxHdr );
		}
		else
		{
			MdlError( "Could not open '%s'\n", fileName );
		}

		// validate header
		if (pVtxHdr->version != OPTIMIZED_MODEL_FILE_VERSION)
		{
			MdlError( "Bad version for '%s' (got %d expected %d)\n", fileName, pVtxHdr->version, OPTIMIZED_MODEL_FILE_VERSION );
		}
		if (pVtxHdr->checkSum != pStudioHdr->checksum)
		{
			MdlError( "Bad checksum for '%s' (got %d expected %d)\n", fileName, pVtxHdr->checkSum, pStudioHdr->checksum );
		}

		// studio render will request these through cache interface
		pStudioHdr->pVertexBase = (void *)pVvdHdr;
		pStudioHdr->pIndexBase  = (void *)pVtxHdr;

		g_pStudioRender->LoadModel( pStudioHdr, pVtxHdr, &studioHWData );

		if( flags & SPEWPERFSTATS_SHOWPERF )
		{
			if(  flags & SPEWPERFSTATS_SPREADSHEET )
			{
				printf( "%s,%s,%d,", fileName, prefix[j], studioHWData.m_NumLODs - studioHWData.m_RootLOD );
			}
			else
			{
				printf( "\n" );
				printf( "Performance Stats: %s\n", fileName );
				printf( "------------------\n" );
			}
		}

		int i;
		if( flags & SPEWPERFSTATS_SHOWPERF )
		{
			for( i = studioHWData.m_RootLOD; i < studioHWData.m_NumLODs; i++ )
			{
				DrawModelInfo_t drawModelInfo;
				drawModelInfo.m_Skin = 0;
				drawModelInfo.m_Body = 0;
				drawModelInfo.m_HitboxSet = 0;
				drawModelInfo.m_pClientEntity = 0;
				drawModelInfo.m_pColorMeshes = 0;
				drawModelInfo.m_pStudioHdr = pStudioHdr;
				drawModelInfo.m_pHardwareData = &studioHWData;	
				CUtlBuffer statsOutput( 0, 0, CUtlBuffer::TEXT_BUFFER );
				if( !( flags & SPEWPERFSTATS_SPREADSHEET ) )
				{
					printf( "LOD:%d\n", i );
				}
				drawModelInfo.m_Lod = i;

				DrawModelResults_t results;
				g_pStudioRender->GetPerfStats( &results, drawModelInfo, &statsOutput );
				if( flags & SPEWPERFSTATS_SPREADSHEET )
				{
					printf( "%d,%d,%d,", results.m_ActualTriCount, results.m_NumBatches, results.m_NumMaterials  );
				}
				else
				{
					printf( "    actual tris:%d\n", ( int )results.m_ActualTriCount );
					printf( "    texture memory bytes: %d (only valid in a rendering app)\n", ( int )results.m_TextureMemoryBytes );
					printf( ( char * )statsOutput.Base() );
				}
			}
			if( flags & SPEWPERFSTATS_SPREADSHEET )
			{
				printf( "\n" );
			}
		}
		g_pStudioRender->UnloadModel( &studioHWData );
		free(pVtxHdr);
	}

	if (pVvdHdr)
		free(pVvdHdr);

	if( !( flags & SPEWPERFSTATS_SHOWSTUDIORENDERWARNINGS ) )
	{
		SpewOutputFunc( s_pSavedSpewFunc );
	}
}
コード例 #2
0
ファイル: perfstats.cpp プロジェクト: xsopher/VinHax
void SpewPerfStats( studiohdr_t *pStudioHdr, const char *pFilename )
{
    char							fileName[260];
    vertexFileHeader_t				*pNewVvdHdr;
    vertexFileHeader_t				*pVvdHdr;
    OptimizedModel::FileHeader_t	*pVtxHdr;
    DrawModelInfo_t					drawModelInfo;
    studiohwdata_t					studioHWData;
    int								vvdSize;
    const char						*prefix[] = {".dx80.vtx", ".dx90.vtx", ".sw.vtx", ".xbox.vtx"};

    if (!pStudioHdr->numbodyparts)
    {
        // no stats on these
        return;
    }

    // Need to load up StudioRender.dll to spew perf stats.
    InitStudioRender();

    // persist the vvd data
    Q_StripExtension( pFilename, fileName, sizeof( fileName ) );
    strcat( fileName, ".vvd" );

    if (FileExists( fileName ))
    {
        vvdSize = LoadFile( fileName, (void**)&pVvdHdr );
    }
    else
    {
        MdlError( "Could not open '%s'\n", fileName );
    }

    // validate header
    if (pVvdHdr->id != MODEL_VERTEX_FILE_ID)
    {
        MdlError( "Bad id for '%s' (got %d expected %d)\n", fileName, pVvdHdr->id, MODEL_VERTEX_FILE_ID);
    }
    if (pVvdHdr->version != MODEL_VERTEX_FILE_VERSION)
    {
        MdlError( "Bad version for '%s' (got %d expected %d)\n", fileName, pVvdHdr->version, MODEL_VERTEX_FILE_VERSION);
    }
    if (pVvdHdr->checksum != pStudioHdr->checksum)
    {
        MdlError( "Bad checksum for '%s' (got %d expected %d)\n", fileName, pVvdHdr->checksum, pStudioHdr->checksum);
    }

    if (pVvdHdr->numFixups)
    {
        // need to perform mesh relocation fixups
        // allocate a new copy
        pNewVvdHdr = (vertexFileHeader_t *)malloc( vvdSize );
        if (!pNewVvdHdr)
        {
            MdlError( "Error allocating %d bytes for Vertex File '%s'\n", vvdSize, fileName );
        }

        Studio_LoadVertexes( pVvdHdr, pNewVvdHdr, 0, true );

        // discard original
        free( pVvdHdr );

        pVvdHdr = pNewVvdHdr;
    }

    // iterate all ???.vtx files
    for (int j=0; j<sizeof(prefix)/sizeof(prefix[0]); j++)
    {
        // make vtx filename
        Q_StripExtension( pFilename, fileName, sizeof( fileName ) );
        strcat( fileName, prefix[j] );

        printf( "\n" );
        printf( "Performance Stats: %s\n", fileName );
        printf( "------------------\n" );

        // persist the vtx data
        if (FileExists(fileName))
        {
            LoadFile( fileName, (void**)&pVtxHdr );
        }
        else
        {
            MdlError( "Could not open '%s'\n", fileName );
        }

        // validate header
        if (pVtxHdr->version != OPTIMIZED_MODEL_FILE_VERSION)
        {
            MdlError( "Bad version for '%s' (got %d expected %d)\n", fileName, pVtxHdr->version, OPTIMIZED_MODEL_FILE_VERSION );
        }
        if (pVtxHdr->checkSum != pStudioHdr->checksum)
        {
            MdlError( "Bad checksum for '%s' (got %d expected %d)\n", fileName, pVtxHdr->checkSum, pStudioHdr->checksum );
        }

        // studio render will request these through cache interface
        pStudioHdr->pVertexBase = (void *)pVvdHdr;
        pStudioHdr->pIndexBase  = (void *)pVtxHdr;

        g_pStudioRender->LoadModel( pStudioHdr, pVtxHdr, &studioHWData );
        memset( &drawModelInfo, 0, sizeof( DrawModelInfo_t ) );
        drawModelInfo.m_pStudioHdr = pStudioHdr;
        drawModelInfo.m_pHardwareData = &studioHWData;
        int i;
        for( i = studioHWData.m_RootLOD; i < studioHWData.m_NumLODs; i++ )
        {
            CUtlBuffer statsOutput( 0, 0, true /* text */ );
            printf( "LOD: %d\n", i );
            drawModelInfo.m_Lod = i;
            g_pStudioRender->GetPerfStats( drawModelInfo, &statsOutput );
            printf( "\tactual tris: %d\n", ( int )drawModelInfo.m_ActualTriCount );
            printf( "\ttexture memory bytes: %d\n", ( int )drawModelInfo.m_TextureMemoryBytes );
            printf( ( char * )statsOutput.Base() );
        }
        g_pStudioRender->UnloadModel( &studioHWData );
        free(pVtxHdr);
    }

    if (pVvdHdr)
        free(pVvdHdr);
}
コード例 #3
0
//-------------------------------------------------------------------------------------------------//
// Class:       CHL2LoaderPlugIn
// 
// Function:    LoadGeometry
// 
// Description: This method gets called by the main application to read in geometry data from
//              a particular file ('strFileName') into the specified model data container
//              ('pModelContainer')
//
//-------------------------------------------------------------------------------------------------//
bool CHL2LoaderPlugIn::LoadGeometry( const RM_TCHAR       *strFileName, 
                                                RmMeshModelContainer *pModelContainer )
{
   //----------------------------------------------------------------------
   // Actual loading code goes here
   //----------------------------------------------------------------------
    HRESULT hr;
	// Store the device pointer
	IDirect3DDevice9 *pd3dDevice = RmGfxGetD3DDevice();

	WCHAR vvdwstr[MAX_PATH];
	WCHAR vtxwstr[MAX_PATH];
	WCHAR mdlwstr[MAX_PATH];

	char vvdstr[MAX_PATH];
	char vtxstr[MAX_PATH];
	char mdlstr[MAX_PATH];

	int vvdFileSize;
	int vtxFileSize;
	int mdlFileSize;
	
	WCHAR tmpStringName[MAX_PATH];
	StringCchCopy( tmpStringName, MAX_PATH, strFileName );
	WCHAR* pch = wcsrchr( tmpStringName, L'\.' );
	*pch='\0';

	StringCchCopy( vvdwstr, MAX_PATH, tmpStringName );
	StringCchCopy( vtxwstr, MAX_PATH, tmpStringName );
	StringCchCopy( mdlwstr, MAX_PATH, tmpStringName );

	StringCchCat( vvdwstr, MAX_PATH, L".vvd" );
	StringCchCat( vtxwstr, MAX_PATH, L".dx90.vtx" );
	StringCchCat( mdlwstr, MAX_PATH, L".mdl" );
    
	WideCharToMultiByte( CP_ACP, 0, vvdwstr, -1, vvdstr, MAX_PATH, NULL, NULL );
	WideCharToMultiByte( CP_ACP, 0, vtxwstr, -1, vtxstr, MAX_PATH, NULL, NULL );
	WideCharToMultiByte( CP_ACP, 0, mdlwstr, -1, mdlstr, MAX_PATH, NULL, NULL );

	ifstream vvdFile( vvdstr,ios::binary );
	ifstream vtxFile( vtxstr,ios::binary );
	ifstream mdlFile( mdlstr,ios::binary );

	vvdFile.seekg(0,ios::end);
	vtxFile.seekg(0,ios::end);
	mdlFile.seekg(0,ios::end);

	vvdFileSize   =   vvdFile.tellg();
	vtxFileSize   =   vtxFile.tellg();
	mdlFileSize   =   mdlFile.tellg();

	vvdFile.seekg(0,ios::beg);
	vtxFile.seekg(0,ios::beg);
	mdlFile.seekg(0,ios::beg);

	char *m_pVvdMem = new char[vvdFileSize];
	char *m_pVtxMem = new char[vtxFileSize];
	char *m_pMdlMem = new char[mdlFileSize];
	vvdFile.read(m_pVvdMem,vvdFileSize);
	vtxFile.read(m_pVtxMem,vtxFileSize);
	mdlFile.read(m_pMdlMem,mdlFileSize);

	vertexFileHeader_t* m_pVvdFileHeader=(vertexFileHeader_t *)m_pVvdMem;
	FileHeader_t*	 m_pVtxFileHeader=(FileHeader_t *)m_pVtxMem;
	studiohdr_t*	 m_pMdlFileHeader=(studiohdr_t *)m_pMdlMem;
	unsigned short    m_iLod=0;
	if (m_pVvdFileHeader->numFixups)
	{
		vertexFileHeader_t *	pNewVvdHdr;
		pNewVvdHdr = new vertexFileHeader_t[vvdFileSize];
		Studio_LoadVertexes( m_pVvdFileHeader, pNewVvdHdr, 0, true );
		free( m_pVvdFileHeader );
		m_pVvdFileHeader = pNewVvdHdr;
	}
	// check mdl header
	if (m_pMdlFileHeader->id != IDSTUDIOHEADER)
	{
		getRmApp()->OutputText( _T(".mdl File id error") );
		return false;
	}
	if (m_pMdlFileHeader->version != STUDIO_VERSION)
	{
		getRmApp()->OutputText( _T(".mdl File version error") );
		return false;
	}

	// check vtx header
	if (m_pVtxFileHeader->version != OPTIMIZED_MODEL_FILE_VERSION)
	{
		getRmApp()->OutputText( _T(".vtd File version error") );
		return false;
	}
	if (m_pVtxFileHeader->checkSum != m_pMdlFileHeader->checksum)
	{
		getRmApp()->OutputText( _T(".vtd File checksum error") );
		return false;
	}

	// check vvd header
	if (m_pVvdFileHeader->id != MODEL_VERTEX_FILE_ID)
	{
		getRmApp()->OutputText( _T(".vvd File id error") );
		return false;
	}
	if (m_pVvdFileHeader->version != MODEL_VERTEX_FILE_VERSION)
	{
		getRmApp()->OutputText( _T(".vvd File version error") );
		return false;
	}
	if (m_pVvdFileHeader->checksum != m_pMdlFileHeader->checksum)
	{
		getRmApp()->OutputText( _T(".vvd File checksum error") );
		return false;
	}

	m_pMdlFileHeader->pVertexBase = (void *)m_pVvdFileHeader;
	m_pMdlFileHeader->pIndexBase  = (void *)m_pVtxFileHeader;

	BodyPartHeader_t* pBodyPart = m_pVtxFileHeader->pBodyPart(0);
	ModelHeader_t*  pModel=pBodyPart->pModel(0);
	ModelLODHeader_t* pLod = pModel->pLOD(m_iLod);

	mstudiobodyparts_t* pStudioBodyPart = m_pMdlFileHeader->pBodypart(0);
	mstudiomodel_t* pStudioModel= pStudioBodyPart->pModel(0);
	int numVerts=0;
	int numIndices=0;
	for (int k=0;k<pStudioModel->nummeshes;k++)
	{
		MeshHeader_t* pMesh = pLod->pMesh(k);
		mstudiomesh_t* pStudioMesh = pStudioModel->pMesh( k );
		for (int j=0;j<pMesh->numStripGroups;j++)
		{
			StripGroupHeader_t* pStripGroup = pMesh->pStripGroup(j);
			numVerts+=pStripGroup->numVerts;
			numIndices+=pStripGroup->numIndices;
		}
	}

	RmMeshModel *pRmMesh = new RmMeshModel();
	pModelContainer->AddMeshModel(pRmMesh);
	pRmMesh->GetVertexArray()->SetNumVertices( numVerts, false );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_BLENDWEIGHT, 0, RMVSDT_FLOAT3 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_BLENDINDICES, 0, RMVSDT_UBYTE4 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_POSITION, 0, RMVSDT_FLOAT3 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_NORMAL, 0, RMVSDT_FLOAT3 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_TEXCOORD, 0, RMVSDT_FLOAT2 );
	pRmMesh->GetVertexArray()->CreateVertexElementArray( RM_DECLUSAGE_TANGENT, 0, RMVSDT_FLOAT4 );

	RmVertexElementArray *pBlendWeightElementArray  = pRmMesh->GetVertexArray()->GetVertexElementArray( RM_DECLUSAGE_BLENDWEIGHT, 0, RMVSDT_FLOAT3 );
	RmVertexElementArray *pBlendIndicesElementArray  = pRmMesh->GetVertexArray()->GetVertexElementArray( RM_DECLUSAGE_BLENDINDICES, 0, RMVSDT_UBYTE4 );
	RmVertexElementArray *pPositionElementArray  = pRmMesh->GetVertexArray()->GetVertexElementArray( RM_DECLUSAGE_POSITION, 0, RMVSDT_FLOAT3 );
	RmVertexElementArray *pNormalElementArray = pRmMesh->GetVertexArray()->GetVertexElementArray(RM_DECLUSAGE_NORMAL,0,RMVSDT_FLOAT3);
	RmVertexElementArray *pTexCoordElementArray = pRmMesh->GetVertexArray()->GetVertexElementArray(RM_DECLUSAGE_TEXCOORD,0,RMVSDT_FLOAT2);
	RmVertexElementArray *pTangentElementArray = pRmMesh->GetVertexArray()->GetVertexElementArray(RM_DECLUSAGE_TANGENT,0,RMVSDT_FLOAT4);

	unsigned short indexOffset=0;
	unsigned short iVertex=0;
	unsigned short iIndex=0;
	unsigned short iSubset = 0;	

	for (int k=0;k<pStudioModel->nummeshes;k++)
	{
		MeshHeader_t* pMesh = pLod->pMesh(k);
		mstudiomesh_t* pStudioMesh = pStudioModel->pMesh( k );
		for (int j=0;j<pMesh->numStripGroups;j++)
		{
			StripGroupHeader_t* pStripGroup = pMesh->pStripGroup(j);
			for (int i=0;i<pStripGroup->numVerts;i++)
			{
				float *pBoneWeight  = ( float* ) pBlendWeightElementArray->GetBuffer( iVertex );
				float *pBoneIndices = ( float* ) pBlendIndicesElementArray->GetBuffer( iVertex );
				float *pPosition    = ( float* ) pPositionElementArray->GetBuffer( iVertex );
				float *pNormal      = ( float* ) pNormalElementArray->GetBuffer( iVertex );
				float *pTexCoord    = ( float* ) pTexCoordElementArray->GetBuffer( iVertex );
				float *pTangent     = ( float* ) pTangentElementArray->GetBuffer( iVertex );

				float *pVertex = ( float* ) m_pVvdFileHeader->pVertex( pStudioMesh->vertexoffset+pStripGroup->pVertex(i)->origMeshVertID );
				pBoneWeight[0]=	pVertex[0];
				pBoneWeight[1]=	pVertex[1];
				pBoneWeight[2]=	pVertex[2];
				pBoneIndices[0]=pVertex[3];
				pPosition[0]  =	pVertex[4];
				pPosition[1]  =	pVertex[5];
				pPosition[2]  =	pVertex[6];
				pNormal[0]    =	pVertex[7];
				pNormal[1]    =	pVertex[8];
				pNormal[2]    =	pVertex[9];
				pTexCoord[0]  = pVertex[10];
				pTexCoord[1]  = pVertex[11];

				float *pTan = ( float* ) m_pVvdFileHeader->pTangent(pStripGroup->pVertex(i)->origMeshVertID );
				pTangent[0] = pTan[0];
				pTangent[1] = pTan[1];
				pTangent[2] = pTan[2];
				pTangent[3] = pTan[3];
				iVertex++;
			}
			pRmMesh->SetPrimitiveType( RM_PRIMITIVETYPE_TRIANGLELIST );
			pRmMesh->SetNumIndices( numIndices );
			RM_DWORD *pIndices = pRmMesh->GetIndices();
			for (int i=0;i<pStripGroup->numIndices;i+=3)
			{
				pIndices[iIndex]=indexOffset + *pStripGroup->pIndex(i);
				pIndices[iIndex+1]=indexOffset + *pStripGroup->pIndex(i+1);
				pIndices[iIndex+2]=indexOffset + *pStripGroup->pIndex(i+2);
				iIndex+=3;
			}
			indexOffset=iVertex;
		}
	}


	getRmApp()->OutputText( _T("\nLoad '%s' into RenderMonkey.\n"), vvdwstr );
	getRmApp()->OutputText( _T("Load '%s' into RenderMonkey.\n"), vtxwstr );
	getRmApp()->OutputText( _T("Load '%s' into RenderMonkey.\n"), mdlwstr );

	return true;
} // End of LoadGeometry for CHL2LoaderPlugIn