initial
This commit is contained in:
669
vgui2/vgui_perftest/amalg_texture.cpp
Normal file
669
vgui2/vgui_perftest/amalg_texture.cpp
Normal file
@@ -0,0 +1,669 @@
|
||||
//===== Copyright <20> 2005-2006, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: build a sheet data file and a large image out of multiple images
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "amalg_texture.h"
|
||||
#include "tier0/platform.h"
|
||||
#include "tier0/progressbar.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "bitmap/floatbitmap.h"
|
||||
#include "tier2/fileutils.h"
|
||||
#include "stdlib.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
|
||||
static int GetChannelIndexFromChar( char c )
|
||||
{
|
||||
// r->0 b->1 g->2 a->3 else -1
|
||||
|
||||
static char s_ChannelIDs[]="rgba";
|
||||
|
||||
char const *pChanChar = strchr( s_ChannelIDs, c );
|
||||
if ( ! pChanChar )
|
||||
{
|
||||
printf( " bad channel name '%c'\n", c );
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pChanChar - s_ChannelIDs;
|
||||
}
|
||||
}
|
||||
|
||||
static void ZeroChannel( FloatBitMap_t *newBitmap, FloatBitMap_t *pBitmap, int nDestChannel )
|
||||
{
|
||||
for ( int y = 0; y < newBitmap->NumRows(); y++ )
|
||||
{
|
||||
for ( int x = 0; x < newBitmap->NumCols(); x++ )
|
||||
{
|
||||
pBitmap->Pixel( x, y, nDestChannel ) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CopyChannel( FloatBitMap_t *newBitmap, FloatBitMap_t *pBitmap, int nSrcChannel, int nDestChannel )
|
||||
{
|
||||
for ( int y = 0; y < newBitmap->NumRows(); y++ )
|
||||
{
|
||||
for ( int x = 0; x < newBitmap->NumCols(); x++ )
|
||||
{
|
||||
pBitmap->Pixel( x, y, nDestChannel ) = newBitmap->Pixel( x, y, nSrcChannel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FloatBitMap_t *CreateFloatBitmap( const char * fname )
|
||||
{
|
||||
if ( strchr( fname, ',' ) == NULL )
|
||||
{
|
||||
char pFileFullPath[ MAX_PATH ];
|
||||
if ( !GenerateFullPath( fname, NULL, pFileFullPath, sizeof( pFileFullPath ) ) )
|
||||
{
|
||||
Warning( "CDataModel: Unable to generate full path for file %s\n", fname );
|
||||
return false;
|
||||
}
|
||||
return new FloatBitMap_t( pFileFullPath );
|
||||
}
|
||||
|
||||
// parse extended specifications
|
||||
CUtlVector<char *> Images;
|
||||
V_SplitString( fname, ",", Images );
|
||||
FloatBitMap_t *pBitmap = NULL;
|
||||
// now, process bitmaps, performing copy operations specified by {} syntax
|
||||
for( int i = 0; i < Images.Count(); i++ )
|
||||
{
|
||||
char fnamebuf[MAX_PATH];
|
||||
strcpy( fnamebuf, Images[i] );
|
||||
char * pBrace=strchr( fnamebuf, '{' );
|
||||
if ( pBrace )
|
||||
{
|
||||
*pBrace = 0; // null it
|
||||
pBrace++; // point at control specifier
|
||||
char *pEndBrace = strchr( pBrace, '}' );
|
||||
if ( ! pEndBrace )
|
||||
{
|
||||
printf( "bad extended bitmap synax (no close brace) - %s \n", Images[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FloatBitMap_t newBitmap( fnamebuf );
|
||||
if ( !pBitmap )
|
||||
{
|
||||
// first image sets size
|
||||
pBitmap = new FloatBitMap_t( &newBitmap );
|
||||
}
|
||||
|
||||
// now, process operation specifiers of the form "{chan=chan}" or "{chan=0}"
|
||||
if ( pBrace && ( pBrace[1] == '=' ) )
|
||||
{
|
||||
int nDstChan = GetChannelIndexFromChar( pBrace[0] );
|
||||
if ( nDstChan != -1 )
|
||||
{
|
||||
if ( pBrace[2] == '0' )
|
||||
{
|
||||
// zero the channel
|
||||
ZeroChannel( &newBitmap, pBitmap, nDstChan );
|
||||
}
|
||||
else
|
||||
{
|
||||
int nSrcChan = GetChannelIndexFromChar( pBrace[2] );
|
||||
if ( nSrcChan != -1 )
|
||||
{
|
||||
// perform the channel copy
|
||||
CopyChannel( &newBitmap, pBitmap, nSrcChan, nDstChan );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return pBitmap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CAmalgamatedTexture::CAmalgamatedTexture()
|
||||
{
|
||||
m_ePackingMode = PCKM_FLAT;
|
||||
m_pCurSequence = NULL;
|
||||
}
|
||||
|
||||
void CAmalgamatedTexture::Init( const char *pShtFileName )
|
||||
{
|
||||
m_pShtFile = pShtFileName;
|
||||
}
|
||||
|
||||
|
||||
void CAmalgamatedTexture::SetCurrentSequenceClamp( bool bState )
|
||||
{
|
||||
if ( m_pCurSequence )
|
||||
{
|
||||
m_pCurSequence->m_Clamp = bState;
|
||||
}
|
||||
}
|
||||
|
||||
int CAmalgamatedTexture::GetPackingMode()
|
||||
{
|
||||
return m_ePackingMode;
|
||||
}
|
||||
|
||||
void CAmalgamatedTexture::SetPackingMode( int eMode )
|
||||
{
|
||||
// Assign the packing mode read in to member var.
|
||||
if ( !m_Sequences.Count() )
|
||||
{
|
||||
m_ePackingMode = eMode;
|
||||
}
|
||||
else if ( m_ePackingMode != eMode )
|
||||
{
|
||||
// Allow special changes:
|
||||
// flat -> rgb+a
|
||||
if ( m_ePackingMode == PCKM_FLAT && eMode == PCKM_RGB_A )
|
||||
{
|
||||
m_ePackingMode = eMode;
|
||||
}
|
||||
// everything else
|
||||
else
|
||||
{
|
||||
printf( "*** line error: incompatible packmode change when %d sequences already defined!\n", m_Sequences.Count() );
|
||||
//printf( "*** line %d: incompatible packmode change when %d sequences already defined!\n", m_NumActualLinesRead, m_Sequences.Count() );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CAmalgamatedTexture::CreateNewSequence( int sequenceNumber, int mode )
|
||||
{
|
||||
m_pCurSequence = new Sequence;
|
||||
m_pCurSequence->m_nSequenceNumber = sequenceNumber;
|
||||
SetSequenceType( mode );
|
||||
|
||||
m_Sequences.AddToTail( m_pCurSequence );
|
||||
}
|
||||
|
||||
void CAmalgamatedTexture::ValidateSequenceType( int eMode, char *word )
|
||||
{
|
||||
switch ( m_ePackingMode )
|
||||
{
|
||||
case PCKM_FLAT:
|
||||
switch ( eMode )
|
||||
{
|
||||
case SQM_RGBA:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
printf( "*** line error: invalid sequence type '%s', packing 'flat' allows only 'sequence-rgba'!\n", word );
|
||||
//printf( "*** line %d: invalid sequence type '%s', packing 'flat' allows only 'sequence-rgba'!\n", m_NumActualLinesRead, word );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PCKM_RGB_A:
|
||||
switch ( eMode )
|
||||
{
|
||||
case SQM_RGB:
|
||||
case SQM_ALPHA:
|
||||
break;
|
||||
default:
|
||||
{
|
||||
//printf( "*** line %d: invalid sequence type '%s', packing 'rgb+a' allows only 'sequence-rgb' or 'sequence-a'!\n", m_NumActualLinesRead, word );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int CAmalgamatedTexture::GetSequenceType()
|
||||
{
|
||||
return m_pCurSequence->m_eMode;
|
||||
}
|
||||
|
||||
void CAmalgamatedTexture::SetSequenceType( int eMode )
|
||||
{
|
||||
m_pCurSequence->m_eMode = eMode;
|
||||
}
|
||||
|
||||
bool CAmalgamatedTexture::CurrentSequenceExists()
|
||||
{
|
||||
return m_pCurSequence != NULL;
|
||||
}
|
||||
|
||||
// Validate that frame packing is correct
|
||||
void CAmalgamatedTexture::ValidateFramePacking( SequenceFrame *pBitmap, char *fileName )
|
||||
{
|
||||
if ( m_ePackingMode == PCKM_RGB_A )
|
||||
{
|
||||
for ( uint16 idx = 0; idx < pBitmap->m_mapSequences.Count(); ++idx )
|
||||
{
|
||||
Sequence *pSeq = pBitmap->m_mapSequences.Key( idx );
|
||||
if ( pSeq->m_eMode != SQM_RGBA &&
|
||||
pSeq->m_eMode != m_pCurSequence->m_eMode )
|
||||
{
|
||||
printf( "*** line error: 'rgb+a' packing cannot pack frame '%s' belonging to sequences %d and %d!\n",
|
||||
fileName,
|
||||
pSeq->m_nSequenceNumber,
|
||||
m_pCurSequence->m_nSequenceNumber );
|
||||
|
||||
//printf( "*** line %d: 'rgb+a' packing cannot pack frame '%s' belonging to sequences %d and %d!\n",
|
||||
// m_NumActualLinesRead,
|
||||
// fileName,
|
||||
// pSeq->m_nSequenceNumber,
|
||||
// m_pCurSequence->m_nSequenceNumber );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CAmalgamatedTexture::CreateFrame( float ftime, CUtlVector<char *> &frameNames )
|
||||
{
|
||||
SequenceEntry newSequenceEntry;
|
||||
newSequenceEntry.m_fDisplayTime = ftime;
|
||||
|
||||
for ( int i = 0; i < frameNames.Count(); i++ )
|
||||
{
|
||||
LoadFrame( newSequenceEntry, frameNames[i], i );
|
||||
}
|
||||
|
||||
m_pCurSequence->m_Frames.AddToTail( newSequenceEntry );
|
||||
}
|
||||
|
||||
void CAmalgamatedTexture::LoadFrame( SequenceEntry &newSequenceEntry, char *fnamebuf, int frameNumber )
|
||||
{
|
||||
SequenceFrame *pBitmap;
|
||||
// Store the frame in the image list, this is a string - bitmap mapping.
|
||||
if ( ! ( m_ImageList.Defined( fnamebuf ) ) )
|
||||
{
|
||||
SequenceFrame *pNew_frm = new SequenceFrame;
|
||||
pNew_frm->m_pImage = CreateFloatBitmap( fnamebuf );
|
||||
pBitmap = pNew_frm;
|
||||
m_ImageList[ fnamebuf ] = pNew_frm;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBitmap = m_ImageList[ fnamebuf ];
|
||||
}
|
||||
|
||||
newSequenceEntry.m_pSeqFrame[frameNumber] = pBitmap;
|
||||
|
||||
// Validate that frame packing is correct
|
||||
ValidateFramePacking( pBitmap, fnamebuf );
|
||||
|
||||
pBitmap->m_mapSequences.Insert( m_pCurSequence, 1 );
|
||||
|
||||
if ( frameNumber == 0 )
|
||||
{
|
||||
for( int j = 1; j < MAX_IMAGES_PER_FRAME; j++ )
|
||||
{
|
||||
newSequenceEntry.m_pSeqFrame[j] = newSequenceEntry.m_pSeqFrame[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAmalgamatedTexture::DetermineBestPacking()
|
||||
{
|
||||
int nBestWidth = -1;
|
||||
int nBestSize = (1 << 30 );
|
||||
int nBestSquareness = ( 1 << 30 ); // how square the texture is
|
||||
for( int nTryWidth = 2048 ; nTryWidth >= 64; nTryWidth >>= 1 )
|
||||
{
|
||||
bool bSuccess = PackImages( NULL, nTryWidth );
|
||||
if ( bSuccess )
|
||||
{
|
||||
printf( "Packing option: %dx%d (%d pixels)\n", m_nWidth, m_nHeight, m_nWidth * m_nHeight );
|
||||
|
||||
bool bPreferThisPack = false;
|
||||
|
||||
int thisSize = m_nHeight * m_nWidth;
|
||||
int thisSquareness = ( m_nWidth == m_nHeight ) ? 1 : ( m_nHeight / m_nWidth + m_nWidth / m_nHeight );
|
||||
|
||||
if ( thisSize < nBestSize )
|
||||
{
|
||||
bPreferThisPack = true;
|
||||
}
|
||||
else if ( thisSize == nBestSize && thisSquareness < nBestSquareness )
|
||||
{
|
||||
bPreferThisPack = true;
|
||||
}
|
||||
|
||||
if ( bPreferThisPack )
|
||||
{
|
||||
nBestWidth = nTryWidth;
|
||||
nBestSize = thisSize;
|
||||
nBestSquareness = thisSquareness;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nBestWidth < 0 )
|
||||
{
|
||||
printf( "Packing error: failed to pack images!\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
m_nWidth = nBestWidth;
|
||||
m_nHeight = nBestSize / nBestWidth;
|
||||
|
||||
printf( "Best option: %dx%d (%d pixels)%s\n", m_nWidth, m_nHeight, m_nWidth * m_nHeight, ( m_nWidth == m_nHeight ) ? " : square texture" : "" );
|
||||
|
||||
}
|
||||
|
||||
bool CAmalgamatedTexture::PackImages( char const *pFilename, int nWidth )
|
||||
{
|
||||
switch ( m_ePackingMode )
|
||||
{
|
||||
case PCKM_FLAT:
|
||||
return PackImages_Flat( pFilename, nWidth );
|
||||
case PCKM_RGB_A:
|
||||
return PackImages_Rgb_A( pFilename, nWidth );
|
||||
case PCKM_INVALID:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CAmalgamatedTexture::PackImages_Flat( char const *pFilename, int nWidth )
|
||||
{
|
||||
// !! bug !! packing algorithm is dumb and no error checking is done!
|
||||
FloatBitMap_t output( nWidth, 2048 );
|
||||
int cur_line = 0;
|
||||
int cur_column = 0;
|
||||
int next_line = 0;
|
||||
int max_column_written = 0;
|
||||
|
||||
for ( int i = 0; i < m_ImageList.GetNumStrings(); i++ )
|
||||
{
|
||||
SequenceFrame &frm = *(m_ImageList[i]);
|
||||
if ( cur_column+frm.m_pImage->NumCols() > output.NumCols() )
|
||||
{
|
||||
// no room!
|
||||
cur_column = 0;
|
||||
cur_line = next_line;
|
||||
next_line = cur_line;
|
||||
}
|
||||
// now, pack
|
||||
if ( ( cur_column + frm.m_pImage->NumCols() > output.NumCols() ) ||
|
||||
( cur_line + frm.m_pImage->NumRows() > output.NumRows() ) )
|
||||
{
|
||||
return false; // didn't fit! doh
|
||||
}
|
||||
|
||||
frm.m_XCoord = cur_column;
|
||||
frm.m_YCoord = cur_line;
|
||||
|
||||
if ( pFilename ) // don't actually pack the pixel if we're not keeping them
|
||||
{
|
||||
for ( int y = 0; y < frm.m_pImage->NumRows(); y++ )
|
||||
for ( int x = 0; x < frm.m_pImage->NumCols(); x++ )
|
||||
for ( int c = 0; c < 4; c++ )
|
||||
{
|
||||
output.Pixel( x+cur_column,y+cur_line, c ) = frm.m_pImage->Pixel(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
next_line = max( next_line, cur_line+frm.m_pImage->NumRows() );
|
||||
cur_column += frm.m_pImage->NumCols();
|
||||
max_column_written = max( max_column_written, cur_column );
|
||||
}
|
||||
|
||||
// now, truncate height
|
||||
int h = 1;
|
||||
for( h; h < next_line; h *= 2 )
|
||||
;
|
||||
// truncate width;
|
||||
int w = 1;
|
||||
for( 1; w < max_column_written; w *= 2 )
|
||||
;
|
||||
|
||||
if ( pFilename )
|
||||
{
|
||||
FloatBitMap_t cropped_output( w, h );
|
||||
for( int y = 0;y < cropped_output.NumRows(); y++ )
|
||||
{
|
||||
for( int x = 0; x < cropped_output.NumCols(); x++ )
|
||||
{
|
||||
for( int c = 0; c < 4; c++ )
|
||||
{
|
||||
cropped_output.Pixel( x,y,c ) = output.Pixel( x,y,c );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bWritten = cropped_output.WriteTGAFile( pFilename );
|
||||
if ( !bWritten )
|
||||
printf( "Error: failed to save TGA \"%s\"!\n", pFilename );
|
||||
else
|
||||
printf( "Ok: successfully saved TGA \"%s\"\n", pFilename );
|
||||
}
|
||||
|
||||
// Store these for UV calculation later on
|
||||
m_nHeight = h;
|
||||
m_nWidth = w;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAmalgamatedTexture::PackImages_Rgb_A( char const *pFilename, int nWidth )
|
||||
{
|
||||
// !! bug !! packing algorithm is dumb and no error checking is done!
|
||||
FloatBitMap_t output( nWidth, 2048 );
|
||||
int cur_line[2] = {0};
|
||||
int cur_column[2] = {0};
|
||||
int next_line[2] = {0};
|
||||
int max_column_written[2] = {0};
|
||||
|
||||
bool bPackingRGBA = true;
|
||||
|
||||
for ( int i = 0; i < m_ImageList.GetNumStrings(); i++ )
|
||||
{
|
||||
SequenceFrame &frm = *( m_ImageList[i] );
|
||||
|
||||
int idxfrm;
|
||||
int eMode = frm.m_mapSequences.Key( 0 )->m_eMode;
|
||||
switch ( eMode )
|
||||
{
|
||||
case SQM_RGB:
|
||||
idxfrm = 0;
|
||||
bPackingRGBA = false;
|
||||
break;
|
||||
case SQM_ALPHA:
|
||||
idxfrm = 1;
|
||||
bPackingRGBA = false;
|
||||
break;
|
||||
case SQM_RGBA:
|
||||
if ( !bPackingRGBA )
|
||||
{
|
||||
printf( "*** error when packing 'rgb+a', bad sequence %d encountered for frame '%s' after all rgba frames packed!\n",
|
||||
frm.m_mapSequences.Key( 0 )->m_nSequenceNumber,
|
||||
m_ImageList.String( i ) );
|
||||
exit( -1 );
|
||||
}
|
||||
idxfrm = 0;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
printf( "*** error when packing 'rgb+a', bad sequence %d encountered for frame '%s'!\n",
|
||||
frm.m_mapSequences.Key( 0 )->m_nSequenceNumber,
|
||||
m_ImageList.String( i ) );
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( cur_column[idxfrm] + frm.m_pImage->NumCols() > output.NumCols() )
|
||||
{
|
||||
// no room!
|
||||
cur_column[idxfrm] = 0;
|
||||
cur_line[idxfrm] = next_line[idxfrm];
|
||||
next_line[idxfrm] = cur_line[idxfrm];
|
||||
}
|
||||
|
||||
// now, pack
|
||||
if ( ( cur_column[idxfrm] + frm.m_pImage->NumCols() > output.NumCols() ) ||
|
||||
( cur_line[idxfrm] + frm.m_pImage->NumRows() > output.NumRows() ) )
|
||||
{
|
||||
return false; // didn't fit! doh
|
||||
}
|
||||
|
||||
frm.m_XCoord = cur_column[idxfrm];
|
||||
frm.m_YCoord = cur_line[idxfrm];
|
||||
|
||||
if ( pFilename ) // don't actually pack the pixel if we're not keeping them
|
||||
{
|
||||
for ( int y = 0; y < frm.m_pImage->NumRows(); y++ )
|
||||
{
|
||||
for (int x = 0; x < frm.m_pImage->NumCols(); x++ )
|
||||
{
|
||||
for(int c = 0; c < 4; c ++ )
|
||||
{
|
||||
switch ( eMode )
|
||||
{
|
||||
case SQM_RGB:
|
||||
if ( c < 3 )
|
||||
goto setpx;
|
||||
break;
|
||||
case SQM_ALPHA:
|
||||
if ( c == 3 )
|
||||
goto setpx;
|
||||
break;
|
||||
case SQM_RGBA:
|
||||
if ( c < 4 )
|
||||
goto setpx;
|
||||
break;
|
||||
setpx:
|
||||
output.Pixel( x + cur_column[idxfrm], y + cur_line[idxfrm], c ) = frm.m_pImage->Pixel(x, y, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next_line[idxfrm] = max( next_line[idxfrm], cur_line[idxfrm] + frm.m_pImage->NumRows() );
|
||||
cur_column[idxfrm] += frm.m_pImage->NumCols();
|
||||
max_column_written[idxfrm] = max( max_column_written[idxfrm], cur_column[idxfrm] );
|
||||
|
||||
if ( bPackingRGBA )
|
||||
{
|
||||
cur_line[1] = cur_line[0];
|
||||
cur_column[1] = cur_column[0];
|
||||
next_line[1] = next_line[0];
|
||||
max_column_written[1] = max_column_written[0];
|
||||
}
|
||||
}
|
||||
|
||||
// now, truncate height
|
||||
int h = 1;
|
||||
for ( int idxfrm = 0; idxfrm < 2; ++idxfrm )
|
||||
{
|
||||
for ( h; h < next_line[idxfrm]; h *= 2 )
|
||||
continue;
|
||||
}
|
||||
// truncate width;
|
||||
int w = 1;
|
||||
for ( int idxfrm = 0; idxfrm < 2; ++idxfrm )
|
||||
{
|
||||
for ( w; w < max_column_written[idxfrm]; w *= 2 )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pFilename )
|
||||
{
|
||||
FloatBitMap_t cropped_output( w, h );
|
||||
for( int y = 0; y < cropped_output.NumRows(); y++ )
|
||||
{
|
||||
for( int x = 0; x < cropped_output.NumCols(); x++ )
|
||||
{
|
||||
for( int c = 0; c < 4; c++ )
|
||||
{
|
||||
cropped_output.Pixel( x, y, c ) = output.Pixel( x, y, c );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bWritten = cropped_output.WriteTGAFile( pFilename );
|
||||
if ( !bWritten )
|
||||
{
|
||||
printf( "Error: failed to save TGA \"%s\"!\n", pFilename );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Ok: successfully saved TGA \"%s\"\n", pFilename );
|
||||
}
|
||||
}
|
||||
|
||||
// Store these for UV calculation later on
|
||||
m_nHeight = h;
|
||||
m_nWidth = w;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAmalgamatedTexture::WriteFile()
|
||||
{
|
||||
if ( m_pShtFile == NULL )
|
||||
{
|
||||
printf( "Error: No output filename set!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
COutputFile Outfile( m_pShtFile );
|
||||
if ( !Outfile.IsOk() )
|
||||
{
|
||||
printf( "Error: failed to write SHT \"%s\"!\n", m_pShtFile );
|
||||
return;
|
||||
}
|
||||
|
||||
Outfile.PutInt( 1 ); // version #
|
||||
Outfile.PutInt( m_Sequences.Count() );
|
||||
for ( int i = 0; i < m_Sequences.Count(); i++ )
|
||||
{
|
||||
Outfile.PutInt( m_Sequences[i]->m_nSequenceNumber );
|
||||
Outfile.PutInt( m_Sequences[i]->m_Clamp );
|
||||
Outfile.PutInt( m_Sequences[i]->m_Frames.Count() );
|
||||
// write total sequence length
|
||||
float fTotal = 0.0;
|
||||
for ( int j = 0; j < m_Sequences[i]->m_Frames.Count(); j++ )
|
||||
{
|
||||
fTotal += m_Sequences[i]->m_Frames[j].m_fDisplayTime;
|
||||
}
|
||||
Outfile.PutFloat( fTotal );
|
||||
for( int j = 0; j < m_Sequences[i]->m_Frames.Count(); j++ )
|
||||
{
|
||||
Outfile.PutFloat( m_Sequences[i]->m_Frames[j].m_fDisplayTime );
|
||||
// output texture coordinates
|
||||
for( int t = 0; t < MAX_IMAGES_PER_FRAME; t++ )
|
||||
{
|
||||
//xmin
|
||||
Outfile.PutFloat( UCoord( m_Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_XCoord ) );
|
||||
//ymin
|
||||
Outfile.PutFloat( VCoord( m_Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_YCoord ) );
|
||||
//xmax
|
||||
Outfile.PutFloat(
|
||||
UCoord( m_Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_XCoord +
|
||||
m_Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_pImage->NumCols() - 1 ));
|
||||
//ymax
|
||||
Outfile.PutFloat(
|
||||
VCoord( m_Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_YCoord +
|
||||
m_Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_pImage->NumRows() - 1 ));
|
||||
// printf( "T %d UV1:( %.2f, %.2f ) UV2:( %.2f, %.2f )\n", t,
|
||||
// UCoord( Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_XCoord ),
|
||||
// VCoord( Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_YCoord ),
|
||||
// UCoord( Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_XCoord+Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_pImage->NumCols()-1 ),
|
||||
// VCoord( Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_YCoord+Sequences[i]->m_Frames[j].m_pSeqFrame[t]->m_pImage->NumRows()-1 ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Ok: successfully saved SHT \"%s\"\n", m_pShtFile );
|
||||
}
|
||||
|
||||
112
vgui2/vgui_perftest/amalg_texture.h
Normal file
112
vgui2/vgui_perftest/amalg_texture.h
Normal file
@@ -0,0 +1,112 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef AMALGAMATEDTEXTURE_H
|
||||
#define AMALGAMATEDTEXTURE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "amalg_texture_vars.h"
|
||||
#include "bitmap/floatbitmap.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include "tier1/utlstringmap.h"
|
||||
#include "tier2/tier2.h"
|
||||
|
||||
|
||||
struct Sequence;
|
||||
struct SequenceFrame
|
||||
{
|
||||
SequenceFrame() : m_mapSequences( DefLessFunc( Sequence * ) ) {}
|
||||
|
||||
FloatBitMap_t *m_pImage;
|
||||
int m_XCoord, m_YCoord; // where it ended up packed
|
||||
CUtlMap< Sequence *, int > m_mapSequences;
|
||||
};
|
||||
|
||||
struct SequenceEntry
|
||||
{
|
||||
SequenceFrame *m_pSeqFrame[MAX_IMAGES_PER_FRAME];
|
||||
float m_fDisplayTime;
|
||||
};
|
||||
|
||||
struct Sequence
|
||||
{
|
||||
int m_nSequenceNumber;
|
||||
bool m_Clamp; // as opposed to loop
|
||||
int m_eMode;
|
||||
CUtlVector<SequenceEntry> m_Frames;
|
||||
|
||||
Sequence( void )
|
||||
{
|
||||
m_Clamp = true;
|
||||
m_eMode = SQM_RGBA;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// The texture itself.
|
||||
class CAmalgamatedTexture
|
||||
{
|
||||
public:
|
||||
CAmalgamatedTexture();
|
||||
void Init( const char *pShtFileName = NULL );
|
||||
void WriteFile();
|
||||
|
||||
void DetermineBestPacking();
|
||||
bool PackImages( char const *pFilename, int nWidth );
|
||||
|
||||
int GetWidth() { return m_nWidth; }
|
||||
|
||||
void SetCurrentSequenceClamp( bool bState );
|
||||
void SetPackingMode( int mode );
|
||||
|
||||
void CreateNewSequence( int sequenceNumber, int mode );
|
||||
void ValidateSequenceType( int eMode, char *word );
|
||||
void SetSequenceType( int eMode );
|
||||
bool CurrentSequenceExists();
|
||||
|
||||
void CreateFrame( float ftime, CUtlVector<char *> &frameNames );
|
||||
void LoadFrame( SequenceEntry &newSequenceEntry, char *fnamebuf, int frameNumber );
|
||||
|
||||
private:
|
||||
|
||||
int GetPackingMode();
|
||||
int GetSequenceType();
|
||||
|
||||
void ValidateFramePacking( SequenceFrame *pBitmap, char *fileName );
|
||||
|
||||
bool PackImages_Flat( char const *pFilename, int nWidth );
|
||||
bool PackImages_Rgb_A( char const *pFilename, int nWidth );
|
||||
|
||||
|
||||
float UCoord( int u )
|
||||
{
|
||||
float uc = u + 0.5;
|
||||
return uc / (float) m_nWidth;
|
||||
}
|
||||
float VCoord( int v )
|
||||
{
|
||||
float vc = v + 0.5;
|
||||
return vc / (float) m_nHeight;
|
||||
}
|
||||
|
||||
const char *m_pShtFile;
|
||||
|
||||
CUtlStringMap<SequenceFrame *> m_ImageList;
|
||||
int m_ePackingMode;
|
||||
|
||||
CUtlVector<Sequence *> m_Sequences;
|
||||
Sequence *m_pCurSequence;
|
||||
|
||||
int m_nWidth;
|
||||
int m_nHeight;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // AMALGAMATEDTEXTURE_H
|
||||
279
vgui2/vgui_perftest/amalg_texture_parser.cpp
Normal file
279
vgui2/vgui_perftest/amalg_texture_parser.cpp
Normal file
@@ -0,0 +1,279 @@
|
||||
//===== Copyright <20> 2005-2006, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose: build a sheet data file and a large image out of multiple images
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#include "amalg_texture_parser.h"
|
||||
#include "tier0/platform.h"
|
||||
#include "tier0/progressbar.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
#include "tier2/tier2.h"
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "tier1/utlstringmap.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include "tier2/fileutils.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#include "materialobjects/dmeamalgtexture.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier2/utlstreambuffer.h"
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
|
||||
static void ApplyMacros( char * in_buf )
|
||||
{
|
||||
CUtlVector<char *> Words;
|
||||
V_SplitString( in_buf, " ", Words);
|
||||
if ( ( Words.Count() == 4 ) && (! stricmp( Words[0],"ga_frame") ) )
|
||||
{
|
||||
// ga_frame frm1 frm2 n -> frame frm1{r=a},frm1{g=a},frm1{b=a},frm2{a=a} n
|
||||
sprintf( in_buf, "frame %s{r=0},%s{g=a},%s{b=0},%s{a=a} %s",
|
||||
Words[1], Words[1], Words[1], Words[2], Words[3] );
|
||||
}
|
||||
Words.PurgeAndDeleteElements();
|
||||
}
|
||||
|
||||
static char *MoveToStart( char *pLineBuffer )
|
||||
{
|
||||
// Kill newline '\n'
|
||||
char *pChop = strchr( pLineBuffer, '\n' );
|
||||
if ( pChop )
|
||||
*pChop = 0;
|
||||
|
||||
// Kill '//' remove comment lines.
|
||||
char *comment = Q_strstr( pLineBuffer, "//" );
|
||||
if ( comment )
|
||||
*comment = 0;
|
||||
|
||||
// Move to start of non-whitespace
|
||||
char *in_str = pLineBuffer;
|
||||
while( ( in_str[0]==' ' ) || ( in_str[0]=='\t') )
|
||||
in_str++;
|
||||
|
||||
return in_str;
|
||||
}
|
||||
|
||||
|
||||
CAmalgamatedTextureParser::CAmalgamatedTextureParser()
|
||||
{
|
||||
m_pSourceFile = NULL;
|
||||
m_pShtFile = NULL;
|
||||
m_pTgaFile = NULL;
|
||||
}
|
||||
|
||||
void CAmalgamatedTextureParser::Init( const char *pSourceFileName, const char *pTgaFileName, const char *pShtFileName )
|
||||
{
|
||||
m_pSourceFile = pSourceFileName;
|
||||
m_pShtFile = pShtFileName;
|
||||
m_pTgaFile = pTgaFileName;
|
||||
}
|
||||
|
||||
int CAmalgamatedTextureParser::ParsePackingMode( char *word )
|
||||
{
|
||||
// Read in the packing mode requested.
|
||||
int eRequestedMode = PCKM_INVALID;
|
||||
|
||||
if ( !stricmp( word, "flat" ) || !stricmp( word, "rgba" ) )
|
||||
{
|
||||
eRequestedMode = PCKM_FLAT;
|
||||
}
|
||||
else if ( !stricmp( word, "rgb+a" ) )
|
||||
{
|
||||
eRequestedMode = PCKM_RGB_A;
|
||||
}
|
||||
|
||||
if ( eRequestedMode == PCKM_INVALID )
|
||||
{
|
||||
Warning( "*** line %d: invalid packmode specified, allowed values are 'rgba' or 'rgb+a'!\n", m_NumActualLinesRead );
|
||||
}
|
||||
|
||||
return eRequestedMode;
|
||||
}
|
||||
|
||||
|
||||
int CAmalgamatedTextureParser::ParseSequenceType( char *word )
|
||||
{
|
||||
int eMode;
|
||||
|
||||
// Figure out the sequence type
|
||||
char const *szSeqType = StringAfterPrefix( word, "sequence" );
|
||||
if ( !stricmp( szSeqType, "" ) || !stricmp( szSeqType, "-rgba" ) )
|
||||
{
|
||||
eMode = SQM_RGBA;
|
||||
}
|
||||
else if ( !stricmp( szSeqType, "-rgb" ) )
|
||||
{
|
||||
eMode = SQM_RGB;
|
||||
}
|
||||
else if ( !stricmp( szSeqType, "-a" ) )
|
||||
{
|
||||
eMode = SQM_ALPHA;
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "*** line %d: invalid sequence type '%s', allowed 'sequence-rgba' or 'sequence-rgb' or 'sequence-a'!\n", m_NumActualLinesRead, word ),
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
return eMode;
|
||||
}
|
||||
|
||||
|
||||
void CAmalgamatedTextureParser::ParseFrameImages( CUtlVector<char *> &words, CUtlVector<char *> &outImageNames )
|
||||
{
|
||||
for ( int i = 0; i < words.Count() - 2; i++ )
|
||||
{
|
||||
char *fnamebuf = words[i+1];
|
||||
outImageNames.AddToTail( fnamebuf );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CAmalgamatedTextureParser::ReadFile( CDmeAmalgamatedTexture &amalgTex )
|
||||
{
|
||||
// FIXME handle file not found.
|
||||
CRequiredInputTextFile f( m_pSourceFile );
|
||||
|
||||
char linebuffer[4096];
|
||||
m_NumActualLinesRead = 0;
|
||||
while ( f.ReadLine( linebuffer, sizeof(linebuffer) ) )
|
||||
{
|
||||
++m_NumActualLinesRead;
|
||||
|
||||
char *in_str = MoveToStart( linebuffer );
|
||||
if ( in_str[0] == NULL )
|
||||
continue;
|
||||
|
||||
strlwr( in_str ); // send string to lowercase.
|
||||
ApplyMacros( in_str );
|
||||
CUtlVector<char *> words;
|
||||
V_SplitString( in_str, " ", words);
|
||||
if ( ( words.Count() == 1) && (! stricmp( words[0],"loop" ) ) )
|
||||
{
|
||||
amalgTex.SetCurrentSequenceClamp( false );
|
||||
}
|
||||
else if ( ( words.Count() == 2 ) && (! stricmp( words[0], "packmode" ) ) )
|
||||
{
|
||||
// Read in the packing mode requested.
|
||||
int eRequestedMode = ParsePackingMode( words[1] );
|
||||
if ( eRequestedMode == PCKM_INVALID )
|
||||
{
|
||||
Msg( "Invalid packing mode." );
|
||||
return false;
|
||||
}
|
||||
amalgTex.SetPackingMode( eRequestedMode );
|
||||
}
|
||||
else if ( ( words.Count() == 2) && StringHasPrefix( words[0], "sequence" ) )
|
||||
{
|
||||
int seq_no = atoi( words[1] );
|
||||
if ( seq_no != amalgTex.GetSequenceCount() )
|
||||
{
|
||||
Warning( "Sequence number mismatch.\n" );
|
||||
}
|
||||
|
||||
// Figure out the sequence type
|
||||
int mode = ParseSequenceType( words[0] );
|
||||
amalgTex.CreateNewSequence( mode );
|
||||
}
|
||||
else if ( ( words.Count() >= 3) && (! stricmp( words[0],"frame" ) ) )
|
||||
{
|
||||
if ( amalgTex.CurrentSequenceExists() )
|
||||
{
|
||||
float ftime = atof( words[ words.Count() - 1 ] );
|
||||
|
||||
CUtlVector<char *> imageNames;
|
||||
ParseFrameImages( words, imageNames );
|
||||
|
||||
amalgTex.CreateFrame( imageNames, ftime );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "*** line %d: Bad command \"%s\"!\n", m_NumActualLinesRead, in_str ),
|
||||
exit( -1 );
|
||||
}
|
||||
words.PurgeAndDeleteElements();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CAmalgamatedTextureParser::ReadFileUsingBuffer( CDmeAmalgamatedTexture &amalgTex )
|
||||
{
|
||||
CUtlBuffer buf( 0, 0, CUtlBuffer::READ_ONLY | CUtlBuffer::TEXT_BUFFER );
|
||||
|
||||
if ( !g_pFullFileSystem->ReadFile( m_pSourceFile, NULL, buf ) )
|
||||
{
|
||||
Warning( "CAmalgamatedTextureParser: Unable to open file '%s'\n", m_pSourceFile );
|
||||
return false;
|
||||
}
|
||||
|
||||
char linebuffer[4096];
|
||||
m_NumActualLinesRead = 0;
|
||||
|
||||
while ( buf.IsValid() )
|
||||
{
|
||||
buf.GetLine( linebuffer, sizeof(linebuffer) );
|
||||
++m_NumActualLinesRead;
|
||||
|
||||
char *in_str = MoveToStart( linebuffer );
|
||||
if ( in_str[0] == NULL )
|
||||
continue;
|
||||
|
||||
strlwr( in_str ); // send string to lowercase.
|
||||
ApplyMacros( in_str );
|
||||
CUtlVector<char *> words;
|
||||
V_SplitString( in_str, " ", words);
|
||||
if ( ( words.Count() == 1) && (! stricmp( words[0],"loop" ) ) )
|
||||
{
|
||||
amalgTex.SetCurrentSequenceClamp( false );
|
||||
}
|
||||
else if ( ( words.Count() == 2 ) && (! stricmp( words[0], "packmode" ) ) )
|
||||
{
|
||||
// Read in the packing mode requested.
|
||||
int eRequestedMode = ParsePackingMode( words[1] );
|
||||
amalgTex.SetPackingMode( eRequestedMode );
|
||||
}
|
||||
else if ( ( words.Count() == 2) && StringHasPrefix( words[0], "sequence" ) )
|
||||
{
|
||||
int seq_no = atoi( words[1] );
|
||||
if ( seq_no != amalgTex.GetSequenceCount() )
|
||||
{
|
||||
Warning( "Sequence number mismatch.\n" );
|
||||
}
|
||||
|
||||
// Figure out the sequence type
|
||||
int mode = ParseSequenceType( words[0] );
|
||||
amalgTex.CreateNewSequence( mode );
|
||||
}
|
||||
else if ( ( words.Count() >= 3) && (! stricmp( words[0],"frame" ) ) )
|
||||
{
|
||||
if ( amalgTex.CurrentSequenceExists() )
|
||||
{
|
||||
float ftime = atof( words[ words.Count() - 1 ] );
|
||||
|
||||
CUtlVector<char *> imageNames;
|
||||
ParseFrameImages( words, imageNames );
|
||||
|
||||
amalgTex.CreateFrame( imageNames, ftime );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "*** line %d: Bad command \"%s\"!\n", m_NumActualLinesRead, in_str ),
|
||||
exit( -1 );
|
||||
}
|
||||
words.PurgeAndDeleteElements();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
46
vgui2/vgui_perftest/amalg_texture_parser.h
Normal file
46
vgui2/vgui_perftest/amalg_texture_parser.h
Normal file
@@ -0,0 +1,46 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef AMALGAMATEDTEXTUREPARSER_H
|
||||
#define AMALGAMATEDTEXTUREPARSER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/utlvector.h"
|
||||
|
||||
class CAmalgamatedTexture;
|
||||
class CDmeAmalgamatedTexture;
|
||||
|
||||
struct SequenceFrame;
|
||||
|
||||
// For parsing tool from the command line.
|
||||
class CAmalgamatedTextureParser
|
||||
{
|
||||
public:
|
||||
CAmalgamatedTextureParser();
|
||||
void Init( const char *pSourceFileName, const char *pTgaFileName, const char *pShtFileName );
|
||||
bool ReadFile( CDmeAmalgamatedTexture &amalgTex );
|
||||
bool ReadFileUsingBuffer( CDmeAmalgamatedTexture &amalgTex );
|
||||
|
||||
void ParseFrameImages( CUtlVector<char *> &words, CUtlVector<char *> &outImageNames );
|
||||
|
||||
private:
|
||||
|
||||
int ParsePackingMode( char *word );
|
||||
int ParseSequenceType( char *word );
|
||||
|
||||
void ValidateFramePacking( SequenceFrame *pBitmap, char *fileName );
|
||||
|
||||
const char *m_pSourceFile;
|
||||
const char *m_pShtFile;
|
||||
const char *m_pTgaFile;
|
||||
|
||||
int m_NumActualLinesRead;
|
||||
};
|
||||
|
||||
|
||||
#endif // AMALGAMATEDTEXTUREPARSER_H
|
||||
35
vgui2/vgui_perftest/amalg_texture_vars.h
Normal file
35
vgui2/vgui_perftest/amalg_texture_vars.h
Normal file
@@ -0,0 +1,35 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef AMALGAMATEDTEXTURE_VARS_H
|
||||
#define AMALGAMATEDTEXTURE_VARS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
|
||||
#define MAX_IMAGES_PER_FRAME 4
|
||||
|
||||
enum PackingMode_t
|
||||
{
|
||||
PCKM_INVALID = 0,
|
||||
PCKM_FLAT, // Default mode - every frame consumes entire RGBA space
|
||||
PCKM_RGB_A, // Some sequences consume RGB space and some Alpha space
|
||||
};
|
||||
|
||||
|
||||
enum SeqMode_t
|
||||
{
|
||||
SQM_RGBA = 0, // Sequence occupies entire RGBA space
|
||||
SQM_RGB = 1, // Sequence occupies only RGB space
|
||||
SQM_ALPHA = 2 // Sequence occupies only Alpha space
|
||||
};
|
||||
|
||||
|
||||
#endif // AMALGAMATEDTEXTURE_VARS_H
|
||||
99
vgui2/vgui_perftest/mksutil.cpp
Normal file
99
vgui2/vgui_perftest/mksutil.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// Material editor
|
||||
//=============================================================================
|
||||
|
||||
#include "mksutil.h"
|
||||
#include "tier2/fileutils.h"
|
||||
|
||||
|
||||
void CMksUtil::Init( const char *objectName )
|
||||
{
|
||||
m_SequenceCount = 0;
|
||||
m_Name = objectName;
|
||||
}
|
||||
|
||||
void CMksUtil::CreateNewSequenceEntry()
|
||||
{
|
||||
int index = m_MksEntries.AddToTail();
|
||||
m_MksEntries[index].entryType = ENTRYTYPE_SEQUENCE;
|
||||
m_MksEntries[index].sequenceNumber = m_SequenceCount;
|
||||
m_SequenceCount++;
|
||||
}
|
||||
|
||||
void CMksUtil::CreateNewFrameEntry( const char* pFrameName, float displayTime )
|
||||
{
|
||||
int index = m_MksEntries.AddToTail();
|
||||
m_MksEntries[index].entryType = ENTRYTYPE_FRAME;
|
||||
m_MksEntries[index].pFrameName = pFrameName;
|
||||
m_MksEntries[index].displayTime = displayTime;
|
||||
}
|
||||
|
||||
CUtlString CMksUtil::GetName()
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
void CMksUtil::WriteFile()
|
||||
{
|
||||
if ( m_Name.IsEmpty() )
|
||||
{
|
||||
Msg( "Error: No mks output filename set!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
CUtlString mksFileName = m_Name;
|
||||
mksFileName += ".mks";
|
||||
|
||||
char pMksFileFullPath[ MAX_PATH ];
|
||||
if ( !GenerateFullPath( mksFileName, NULL, pMksFileFullPath, sizeof( pMksFileFullPath ) ) )
|
||||
{
|
||||
Warning( "CDataModel: Unable to generate full path for file %s\n", mksFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
COutputTextFile Outfile( pMksFileFullPath );
|
||||
if ( !Outfile.IsOk() )
|
||||
{
|
||||
Msg( "Error: failed to write MKS \"%s\"!\n", pMksFileFullPath );
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[33];
|
||||
for ( int i = m_MksEntries.Head(); i < m_MksEntries.InvalidIndex(); i = m_MksEntries.Next( i ) )
|
||||
{
|
||||
if ( m_MksEntries[i].entryType == ENTRYTYPE_SEQUENCE )
|
||||
{
|
||||
Outfile.Write( "\n", sizeof( char ) );
|
||||
Outfile.Write( "sequence ", sizeof( char ) * Q_strlen("sequence ") );
|
||||
itoa( m_MksEntries[i].sequenceNumber, buffer, 10 );
|
||||
Outfile.Write( buffer, sizeof( char ) * Q_strlen(buffer) );
|
||||
}
|
||||
else if ( m_MksEntries[i].entryType == ENTRYTYPE_FRAME )
|
||||
{
|
||||
Outfile.Write( "frame ", sizeof( char ) * Q_strlen("frame ") );
|
||||
Outfile.Write( m_MksEntries[i].pFrameName, sizeof( char ) * Q_strlen(m_MksEntries[i].pFrameName) );
|
||||
Outfile.Write( " ", sizeof( char ) );
|
||||
sprintf( buffer, "%.1f", m_MksEntries[i].displayTime );
|
||||
Outfile.Write( buffer, sizeof( char ) * Q_strlen(buffer) );
|
||||
}
|
||||
|
||||
Outfile.Write( "\n", sizeof( char ) );
|
||||
}
|
||||
|
||||
Msg( "Ok: successfully saved MKS \"%s\"\n", pMksFileFullPath );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
61
vgui2/vgui_perftest/mksutil.h
Normal file
61
vgui2/vgui_perftest/mksutil.h
Normal file
@@ -0,0 +1,61 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// Material editor
|
||||
//=============================================================================
|
||||
|
||||
#ifndef MKSUTIL_H
|
||||
#define MKSUTIL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/utllinkedlist.h"
|
||||
#include "tier1/utlstring.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The application object
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMksUtil
|
||||
{
|
||||
public:
|
||||
|
||||
enum EntryType_t
|
||||
{
|
||||
ENTRYTYPE_SEQUENCE,
|
||||
ENTRYTYPE_FRAME,
|
||||
ENTRYTYPE_MAX
|
||||
};
|
||||
|
||||
struct sMKSInfo
|
||||
{
|
||||
int entryType;
|
||||
int sequenceNumber;
|
||||
const char *pFrameName; // array?
|
||||
float displayTime;
|
||||
};
|
||||
|
||||
void Init( const char *objectName );
|
||||
|
||||
CUtlString GetName();
|
||||
void CreateNewSequenceEntry();
|
||||
void CreateNewFrameEntry( const char* pFrameName, float displayTime = 1.0f );
|
||||
|
||||
void WriteFile();
|
||||
|
||||
private:
|
||||
|
||||
CUtlLinkedList< sMKSInfo > m_MksEntries;
|
||||
int m_SequenceCount;
|
||||
CUtlString m_Name;
|
||||
};
|
||||
|
||||
#endif // MKSUTIL_H
|
||||
|
||||
161
vgui2/vgui_perftest/mksutil.h.cpp
Normal file
161
vgui2/vgui_perftest/mksutil.h.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// Material editor
|
||||
//=============================================================================
|
||||
|
||||
#include "vstdlib/cvar.h"
|
||||
#include "appframework/vguimatsysapp.h"
|
||||
#include "nowindows.h"
|
||||
#include "FileSystem.h"
|
||||
#include "materialsystem/IMaterialSystem.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/ISystem.h"
|
||||
#include "vgui_controls/Panel.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui_controls/controls.h"
|
||||
#include "vgui/IScheme.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/IPanel.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "vgui_controls/Frame.h"
|
||||
#include "vgui_controls/AnimationController.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "materialsystem/MaterialSystem_Config.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "filesystem_init.h"
|
||||
#include "vstdlib/iprocessutils.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "matsys_controls/mdlpicker.h"
|
||||
#include "IStudioRender.h"
|
||||
#include "datacache/idatacache.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "vphysics_interface.h"
|
||||
#include "vgui_controls/frame.h"
|
||||
#include "materialsystem/IMaterialSystemHardwareConfig.h"
|
||||
#include "materialsystem/materialsystemutil.h"
|
||||
#include "tier3/tier3.h"
|
||||
#include "vgui_controls/consoledialog.h"
|
||||
#include "icvar.h"
|
||||
#include "vgui/keycode.h"
|
||||
#include "vguimaterial.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "tier0/progressbar.h"
|
||||
#include "amalg_texture_vars.h"
|
||||
#include "amalg_texture.h"
|
||||
#include "dmeamalgtexture.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmelementfactoryhelper.h"
|
||||
#include "tier2/fileutils.h"
|
||||
|
||||
#include "amalg_texture_parser.h"
|
||||
#include "dmserializers/idmserializers.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The application object
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMksUtil
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
ENTRYTYPE_SEQUENCE,
|
||||
ENTRYTYPE_FRAME,
|
||||
ENTRYTYPE_MAX
|
||||
};
|
||||
|
||||
struct sMKSInfo
|
||||
{
|
||||
int entryType;
|
||||
int sequenceNumber;
|
||||
const char *pFrameName; // array?
|
||||
float displayTime;
|
||||
};
|
||||
|
||||
void GenerateMKSEntries();
|
||||
void GenerateMKSFile( const char *pMksFileName );
|
||||
void CreateNewSequenceEntry();
|
||||
void CreateNewFrameEntry( const char* pFrameName, float displayTime = 1.0f );
|
||||
|
||||
private:
|
||||
|
||||
CUtlLinkedList< sMKSInfo > m_MksEntries;
|
||||
int m_SequenceCount;
|
||||
};
|
||||
|
||||
|
||||
void CMksUtil::CreateNewSequenceEntry()
|
||||
{
|
||||
int index = m_MksEntries.AddToTail();
|
||||
m_MksEntries[index].entryType = ENTRYTYPE_SEQUENCE;
|
||||
m_MksEntries[index].sequenceNumber = m_SequenceCount;
|
||||
m_SequenceCount++;
|
||||
}
|
||||
|
||||
void CMksUtil::CreateNewFrameEntry( const char* pFrameName, float displayTime )
|
||||
{
|
||||
int index = m_MksEntries.AddToTail();
|
||||
m_MksEntries[index].entryType = ENTRYTYPE_FRAME;
|
||||
m_MksEntries[index].pFrameName = pFrameName;
|
||||
m_MksEntries[index].displayTime = displayTime;
|
||||
}
|
||||
|
||||
void CMksUtil::GenerateMKSFile( const char *pMksFileName )
|
||||
{
|
||||
if ( pMksFileName == NULL )
|
||||
{
|
||||
Msg( "Error: No mks output filename set!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
char pMksFileFullPath[ MAX_PATH ];
|
||||
if ( !GenerateFullPath( pMksFileName, NULL, pMksFileFullPath, sizeof( pMksFileFullPath ) ) )
|
||||
{
|
||||
Warning( "CDataModel: Unable to generate full path for file %s\n", pMksFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
COutputTextFile Outfile( pMksFileFullPath );
|
||||
if ( !Outfile.IsOk() )
|
||||
{
|
||||
Msg( "Error: failed to write MKS \"%s\"!\n", pMksFileFullPath );
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[33];
|
||||
for ( int i = m_MksEntries.Head(); i < m_MksEntries.InvalidIndex(); i = m_MksEntries.Next( i ) )
|
||||
{
|
||||
if ( m_MksEntries[i].entryType == ENTRYTYPE_SEQUENCE )
|
||||
{
|
||||
Outfile.Write( "\n", sizeof( char ) );
|
||||
Outfile.Write( "sequence ", sizeof( char ) * Q_strlen("sequence ") );
|
||||
itoa( m_MksEntries[i].sequenceNumber, buffer, 10 );
|
||||
Outfile.Write( buffer, sizeof( char ) * Q_strlen(buffer) );
|
||||
}
|
||||
else if ( m_MksEntries[i].entryType == ENTRYTYPE_FRAME )
|
||||
{
|
||||
Outfile.Write( "frame ", sizeof( char ) * Q_strlen("frame ") );
|
||||
Outfile.Write( m_MksEntries[i].pFrameName, sizeof( char ) * Q_strlen(m_MksEntries[i].pFrameName) );
|
||||
Outfile.Write( " ", sizeof( char ) );
|
||||
sprintf( buffer, "%.1f", m_MksEntries[i].displayTime );
|
||||
Outfile.Write( buffer, sizeof( char ) * Q_strlen(buffer) );
|
||||
}
|
||||
|
||||
Outfile.Write( "\n", sizeof( char ) );
|
||||
}
|
||||
|
||||
Msg( "Ok: successfully saved MKS \"%s\"\n", pMksFileFullPath );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
491
vgui2/vgui_perftest/vgui_perftest.cpp
Normal file
491
vgui2/vgui_perftest/vgui_perftest.cpp
Normal file
@@ -0,0 +1,491 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// Material editor
|
||||
//=============================================================================
|
||||
|
||||
#include "vstdlib/cvar.h"
|
||||
#include "appframework/vguimatsysapp.h"
|
||||
#include "soundsystem/isoundsystem.h"
|
||||
#include "nowindows.h"
|
||||
#include "FileSystem.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/ISystem.h"
|
||||
//#include "vgui/IScheme.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "tier0/dbg.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "materialsystem/MaterialSystem_Config.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "vstdlib/iprocessutils.h"
|
||||
#include "matsys_controls/matsyscontrols.h"
|
||||
#include "datacache/idatacache.h"
|
||||
#include "vgui_controls/frame.h"
|
||||
#include "materialsystem/IMaterialSystemHardwareConfig.h"
|
||||
#include "materialsystem/materialsystemutil.h"
|
||||
#include "vgui/keycode.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
#include "game_controls/igameuisystemmgr.h"
|
||||
#include "console_logging.h"
|
||||
#include "vscript/ivscript.h"
|
||||
#include "materialsystem/imaterialproxyfactory.h"
|
||||
#include "tier1/interface.h"
|
||||
#include "materialsystem/IMaterialProxy.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
|
||||
LINK_GAME_CONTROLS_LIB();
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
const MaterialSystem_Config_t *g_pMaterialSystemConfig;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A material proxy that resets the base texture to use the dynamic texture
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPerftestGameControlsProxy : public IMaterialProxy
|
||||
{
|
||||
public:
|
||||
CPerftestGameControlsProxy();
|
||||
virtual ~CPerftestGameControlsProxy(){};
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( void *pProxyData );
|
||||
virtual void Release( void ) { delete this; }
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
IMaterialVar* m_BaseTextureVar;
|
||||
};
|
||||
|
||||
CPerftestGameControlsProxy::CPerftestGameControlsProxy(): m_BaseTextureVar( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
bool CPerftestGameControlsProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
bool bFoundVar;
|
||||
m_BaseTextureVar = pMaterial->FindVar( "$basetexture", &bFoundVar, false );
|
||||
return bFoundVar;
|
||||
}
|
||||
|
||||
void CPerftestGameControlsProxy::OnBind( void *pProxyData )
|
||||
{
|
||||
const char *pBaseTextureName = ( const char * )pProxyData;
|
||||
ITexture *pTexture = g_pMaterialSystem->FindTexture( pBaseTextureName, TEXTURE_GROUP_OTHER, true );
|
||||
m_BaseTextureVar->SetTextureValue( pTexture );
|
||||
}
|
||||
|
||||
IMaterial *CPerftestGameControlsProxy::GetMaterial()
|
||||
{
|
||||
return m_BaseTextureVar->GetOwningMaterial();
|
||||
}
|
||||
|
||||
static CPerftestGameControlsProxy s_CPerftestGameControlsProxy;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Factory to create dynamic material. ( Return in this case. )
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPerftestMaterialProxyFactory : public IMaterialProxyFactory
|
||||
{
|
||||
public:
|
||||
IMaterialProxy *CreateProxy( const char *proxyName );
|
||||
void DeleteProxy( IMaterialProxy *pProxy );
|
||||
CreateInterfaceFn GetFactory();
|
||||
};
|
||||
static CPerftestMaterialProxyFactory s_DynamicMaterialProxyFactory;
|
||||
|
||||
IMaterialProxy *CPerftestMaterialProxyFactory::CreateProxy( const char *proxyName )
|
||||
{
|
||||
if ( Q_strcmp( proxyName, "GameControlsProxy" ) == NULL )
|
||||
{
|
||||
return static_cast< IMaterialProxy * >( &s_CPerftestGameControlsProxy );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CPerftestMaterialProxyFactory::DeleteProxy( IMaterialProxy *pProxy )
|
||||
{
|
||||
}
|
||||
|
||||
CreateInterfaceFn CPerftestMaterialProxyFactory::GetFactory()
|
||||
{
|
||||
return Sys_GetFactoryThis();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The application object
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVguiPerfTestApp : public CVguiMatSysApp
|
||||
{
|
||||
typedef CVguiMatSysApp BaseClass;
|
||||
|
||||
public:
|
||||
// Methods of IApplication
|
||||
virtual bool Create();
|
||||
virtual bool PreInit();
|
||||
virtual int Main();
|
||||
virtual bool AppUsesReadPixels() { return true; }
|
||||
|
||||
private:
|
||||
bool SetupSearchPaths();
|
||||
|
||||
virtual const char *GetAppName() { return "VguiPerfTest"; }
|
||||
|
||||
bool RunPerfTest( CMatRenderContextPtr &pRenderContext, const char *pMenuName );
|
||||
void CVguiPerfTestApp::PlayMenuSound( const char *pSoundFileName );
|
||||
|
||||
};
|
||||
|
||||
DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT( CVguiPerfTestApp );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create all singleton systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiPerfTestApp::Create()
|
||||
{
|
||||
if ( !BaseClass::Create() )
|
||||
return false;
|
||||
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "vstdlib.dll", PROCESS_UTILS_INTERFACE_VERSION },
|
||||
{ "vstdlib.dll", EVENTSYSTEM_INTERFACE_VERSION }, // input event support
|
||||
// { "studiorender.dll", STUDIO_RENDER_INTERFACE_VERSION },
|
||||
// { "vphysics.dll", VPHYSICS_INTERFACE_VERSION },
|
||||
{ "datacache.dll", DATACACHE_INTERFACE_VERSION }, // needed for sound system.
|
||||
// { "datacache.dll", MDLCACHE_INTERFACE_VERSION },
|
||||
{ "vscript.dll", VSCRIPT_INTERFACE_VERSION }, // scripting support
|
||||
{ "soundsystem.dll", SOUNDSYSTEM_INTERFACE_VERSION }, // sound support
|
||||
|
||||
{ "", "" } // Required to terminate the list
|
||||
};
|
||||
|
||||
AddSystem( g_pGameUISystemMgr, GAMEUISYSTEMMGR_INTERFACE_VERSION );
|
||||
|
||||
return AddSystems( appSystems );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init, shutdown
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiPerfTestApp::PreInit( )
|
||||
{
|
||||
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
|
||||
|
||||
if ( !BaseClass::PreInit() )
|
||||
return false;
|
||||
|
||||
// initialize interfaces
|
||||
CreateInterfaceFn appFactory = GetFactory();
|
||||
if (!vgui::VGui_InitMatSysInterfacesList( "VguiPerfTest", &appFactory, 1 ))
|
||||
return false;
|
||||
|
||||
if ( !g_pFullFileSystem || !g_pMaterialSystem || !g_pVGui || !g_pVGuiSurface || !g_pMatSystemSurface || !g_pEventSystem )
|
||||
{
|
||||
Warning( "Perf Test App is missing a required interface!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add paths...
|
||||
if ( !SetupSearchPaths() )
|
||||
return false;
|
||||
|
||||
|
||||
materials->SetMaterialProxyFactory( &s_DynamicMaterialProxyFactory );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets up the game path
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiPerfTestApp::SetupSearchPaths()
|
||||
{
|
||||
if ( !BaseClass::SetupSearchPaths( NULL, false, true ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Replace first underscore (if any) with \0 and return
|
||||
// This handles special mods like tf_movies, l4d_movies, tf_comics
|
||||
// As a result, such mods will use the gpu_level settings etc from the base mod
|
||||
void StripModSuffix2( char *pModName )
|
||||
{
|
||||
int i = 0;
|
||||
while ( pModName[i] != '\0' ) // Walk to the end of the string
|
||||
{
|
||||
if ( pModName[i] == '_') // If we hit an underscore
|
||||
{
|
||||
pModName[i] = '\0'; // Terminate the string here and bail out
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// main application
|
||||
//-----------------------------------------------------------------------------
|
||||
int CVguiPerfTestApp::Main()
|
||||
{
|
||||
CConsoleLoggingListener consoleLoggingListener;
|
||||
LoggingSystem_PushLoggingState();
|
||||
LoggingSystem_RegisterLoggingListener( &consoleLoggingListener );
|
||||
LoggingSystem_SetChannelSpewLevelByTag( "Console", LS_MESSAGE );
|
||||
LoggingSystem_SetChannelSpewLevelByTag( "Developer", LS_ERROR );
|
||||
LoggingSystem_SetChannelSpewLevelByTag( "DeveloperVerbose", LS_ERROR );
|
||||
|
||||
CSimpleLoggingListener simpleLoggingListner( false );
|
||||
LoggingSystem_RegisterLoggingListener( &simpleLoggingListner );
|
||||
|
||||
g_pMaterialSystem->ModInit();
|
||||
if (!SetVideoMode())
|
||||
return 0;
|
||||
|
||||
g_pDataCache->SetSize( 64 * 1024 * 1024 );
|
||||
|
||||
g_pMaterialSystemConfig = &g_pMaterialSystem->GetCurrentConfigForVideoCard();
|
||||
|
||||
// configuration settings
|
||||
vgui::system()->SetUserConfigFile( "VguiPerfTest.vdf", "EXECUTABLE_PATH");
|
||||
|
||||
// If you load a vgui panel you must load up a scheme.
|
||||
|
||||
// load scheme
|
||||
if (!vgui::scheme()->LoadSchemeFromFile( "resource/BoxRocket.res", "VguiPerfTest" ))
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
|
||||
// load the boxrocket localization file
|
||||
g_pVGuiLocalize->AddFile( "resource/boxrocket_%language%.txt" );
|
||||
|
||||
// load the mod localization file
|
||||
// Construct the mod name so we can use the mod-specific encrypted config files
|
||||
char pModPath[MAX_PATH];
|
||||
V_snprintf( pModPath, sizeof(pModPath), "" );
|
||||
g_pFullFileSystem->GetSearchPath( "MOD", false, pModPath, sizeof( pModPath ) );
|
||||
|
||||
char pModName[32];
|
||||
V_StripTrailingSlash( pModPath );
|
||||
V_FileBase( pModPath, pModName, sizeof( pModName ) );
|
||||
StripModSuffix2( pModName );
|
||||
|
||||
// Language file is a file of the form "resource/nimbus_%language%.txt"
|
||||
CUtlString pModLanguageFile;
|
||||
pModLanguageFile += "resource/";
|
||||
pModLanguageFile += pModName;
|
||||
pModLanguageFile += "_%language%.txt";
|
||||
|
||||
g_pVGuiLocalize->AddFile( pModLanguageFile.Get() );
|
||||
|
||||
|
||||
|
||||
// start vgui
|
||||
g_pVGui->Start();
|
||||
|
||||
// add our main window
|
||||
//vgui::PHandle hMainPanel;
|
||||
|
||||
// load the base localization file
|
||||
g_pVGuiLocalize->AddFile( "Resource/valve_%language%.txt" );
|
||||
g_pFullFileSystem->AddSearchPath( "platform", "PLATFORM" );
|
||||
g_pVGuiLocalize->AddFile( "Resource/vgui_%language%.txt");
|
||||
|
||||
|
||||
// run app frame loop
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
const char *pGuiFileName = CommandLine()->ParmValue( "-gui" );
|
||||
|
||||
bool bReload = true;
|
||||
while ( bReload )
|
||||
{
|
||||
bReload = RunPerfTest( pRenderContext, pGuiFileName );
|
||||
}
|
||||
|
||||
g_pMaterialSystem->ModShutdown();
|
||||
|
||||
LoggingSystem_PopLoggingState();
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns true if ui should reload
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVguiPerfTestApp::RunPerfTest( CMatRenderContextPtr &pRenderContext, const char *pMenuName )
|
||||
{
|
||||
g_pGameUISystemMgr->Shutdown();
|
||||
g_pGameUISystemMgr->Init();
|
||||
g_pMaterialSystem->BeginRenderTargetAllocation();
|
||||
g_pGameUISystemMgr->InitRenderTargets();
|
||||
g_pMaterialSystem->EndRenderTargetAllocation();
|
||||
|
||||
if ( !pMenuName )
|
||||
{
|
||||
pMenuName = "menu_1";
|
||||
}
|
||||
|
||||
g_pGameUISystemMgr->LoadGameUIScreen( KeyValues::AutoDeleteInline(
|
||||
new KeyValues( pMenuName ) ) );
|
||||
|
||||
|
||||
g_VProfCurrentProfile.Reset();
|
||||
g_VProfCurrentProfile.ResetPeaks();
|
||||
g_VProfCurrentProfile.Start();
|
||||
|
||||
float m_flTotalTime = 0;
|
||||
float flStartTime = Plat_FloatTime();
|
||||
{
|
||||
KeyValues *kvEvent = new KeyValues( "StartPlaying" );
|
||||
kvEvent->SetFloat( "time", 0 );
|
||||
g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
|
||||
}
|
||||
int frameCount = 0;
|
||||
bool bReload = false;
|
||||
bool bAbleToAdvance = true;
|
||||
|
||||
vgui::VPANEL root = g_pVGuiSurface->GetEmbeddedPanel();
|
||||
g_pVGuiSurface->Invalidate( root );
|
||||
|
||||
|
||||
while ( g_pVGui->IsRunning() )
|
||||
{
|
||||
AppPumpMessages();
|
||||
|
||||
|
||||
g_pSoundSystem->Update( Plat_FloatTime() );
|
||||
|
||||
g_pMaterialSystem->BeginFrame( 0 );
|
||||
|
||||
pRenderContext->ClearColor4ub( 0, 0, 0, 255 );
|
||||
//pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
|
||||
pRenderContext->ClearBuffers( true, true );
|
||||
|
||||
// Handle all input to game ui.
|
||||
g_pGameUISystemMgr->RunFrame();
|
||||
|
||||
// Must call run frame for close button to work.
|
||||
g_pVGui->RunFrame(); // need to load a default scheme for this to work.
|
||||
//g_pVGuiSurface->PaintTraverseEx( root, true );
|
||||
|
||||
Rect_t viewport;
|
||||
pRenderContext->GetViewport( viewport.x, viewport.y, viewport.width, viewport.height );
|
||||
|
||||
float flCurrentRenderTime = Plat_FloatTime() - flStartTime;
|
||||
g_pGameUISystemMgr->Render( viewport, DmeTime_t( flCurrentRenderTime ) );
|
||||
|
||||
g_pMaterialSystem->EndFrame();
|
||||
g_pMaterialSystem->SwapBuffers();
|
||||
|
||||
g_VProfCurrentProfile.MarkFrame();
|
||||
|
||||
frameCount++;
|
||||
//if ( frameCount >= 5000 )
|
||||
// break;
|
||||
|
||||
if ( g_pInputSystem->IsButtonDown( KEY_ESCAPE ) )
|
||||
{
|
||||
bReload = true;
|
||||
break;
|
||||
}
|
||||
else if ( g_pInputSystem->IsButtonDown( KEY_PAD_PLUS ) )
|
||||
{
|
||||
m_flTotalTime = 0;
|
||||
{
|
||||
KeyValues *kvEvent = new KeyValues( "StartPlaying" );
|
||||
kvEvent->SetFloat( "time", m_flTotalTime );
|
||||
g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
|
||||
}
|
||||
}
|
||||
else if ( g_pInputSystem->IsButtonDown( KEY_PAD_MINUS ) )
|
||||
{
|
||||
KeyValues *kvEvent = new KeyValues( "StopPlaying" );
|
||||
g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
|
||||
}
|
||||
else if ( g_pInputSystem->IsButtonDown( KEY_PAD_DIVIDE ) )
|
||||
{
|
||||
KeyValues *kvEvent = new KeyValues( "ShowCursorCoords" );
|
||||
g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
|
||||
}
|
||||
else if ( g_pInputSystem->IsButtonDown( KEY_PAD_9 ) )
|
||||
{
|
||||
KeyValues *kvEvent = new KeyValues( "ShowGraphicName" );
|
||||
g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
|
||||
}
|
||||
else if ( g_pInputSystem->IsButtonDown( KEY_PAD_MULTIPLY ) )
|
||||
{
|
||||
if ( bAbleToAdvance )
|
||||
{
|
||||
KeyValues *kvEvent = new KeyValues( "AdvanceState" );
|
||||
g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
|
||||
}
|
||||
bAbleToAdvance = false;
|
||||
}
|
||||
else if ( !g_pInputSystem->IsButtonDown( KEY_PAD_MULTIPLY ) )
|
||||
{
|
||||
bAbleToAdvance = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
g_VProfCurrentProfile.Stop();
|
||||
g_VProfCurrentProfile.OutputReport( VPRT_FULL & ~VPRT_HIERARCHY, NULL );
|
||||
|
||||
return bReload;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVguiPerfTestApp::PlayMenuSound( const char *pSoundFileName )
|
||||
{
|
||||
if ( pSoundFileName == NULL || pSoundFileName[ 0 ] == '\0' )
|
||||
return;
|
||||
|
||||
if ( !Q_stristr( pSoundFileName, ".wav" ) )
|
||||
return;
|
||||
|
||||
char filename[ 256 ];
|
||||
sprintf( filename, "sound/%s", pSoundFileName );
|
||||
CAudioSource *pAudioSource = g_pSoundSystem->FindOrAddSound( filename );
|
||||
if ( pAudioSource == NULL )
|
||||
return;
|
||||
|
||||
g_pSoundSystem->PlaySound( pAudioSource, 1.0f, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
||||
74
vgui2/vgui_perftest/vgui_perftest.vpc
Normal file
74
vgui2/vgui_perftest/vgui_perftest.vpc
Normal file
@@ -0,0 +1,74 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// VGUI_PERFTEST.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,$SRCDIR\vgui2\include,$SRCDIR\vgui2\controls,..\common"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE comctl32.lib odbc32.lib odbccp32.lib Rpcrt4.lib Imm32.lib"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "vguiPerfTest"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "amalg_texture_parser.cpp"
|
||||
$File "$SRCDIR\public\interpolatortypes.cpp"
|
||||
$File "$SRCDIR\public\interpolatortypes.h"
|
||||
$File "vgui_perftest.cpp"
|
||||
$File "vguimaterial.cpp"
|
||||
$File "$SRCDIR\public\vgui_controls\vgui_controls.cpp"
|
||||
$File "$SRCDIR\public\studio.cpp"
|
||||
$File "$SRCDIR\public\collisionutils.cpp"
|
||||
$File "$SRCDIR\public\materialobjects\materialobjects.cpp"
|
||||
$File "mksutil.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "amalg_texture_parser.h"
|
||||
$File "$SRCDIR\utils\common\cmdlib.h"
|
||||
$File "$SRCDIR\common\console_logging.h"
|
||||
$File "$SRCDIR\public\FileSystem.h"
|
||||
$File "$SRCDIR\public\tier1\interface.h"
|
||||
$File "vguimaterial.h"
|
||||
$File "$SRCDIR\public\pixelwriter.h"
|
||||
$File "mksutil.h"
|
||||
$File "$SRCDIR\vgui2\game_controls\GameUISystem.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib "$LIBPUBLIC\bitmap"
|
||||
$Lib "$LIBPUBLIC\datamodel"
|
||||
$Lib "$LIBPUBLIC\dmserializers"
|
||||
$Lib "$LIBPUBLIC\raytrace"
|
||||
$Lib "$LIBPUBLIC\appframework"
|
||||
$Lib "$LIBPUBLIC\dmxloader"
|
||||
$Lib "$LIBPUBLIC\game_controls"
|
||||
$Lib "$LIBPUBLIC\materialobjects"
|
||||
$Lib "$LIBPUBLIC\mathlib"
|
||||
$Lib "$LIBPUBLIC\matsys_controls"
|
||||
$Lib "$LIBPUBLIC\resourcefile"
|
||||
$Lib "$LIBPUBLIC\tier2"
|
||||
$Lib "$LIBPUBLIC\tier3"
|
||||
$Lib "$LIBPUBLIC\vtf"
|
||||
$Lib "$LIBPUBLIC\vgui_controls"
|
||||
$Lib "$LIBPUBLIC\vgui_surfacelib"
|
||||
$Lib "$LIBPUBLIC\videocfg"
|
||||
}
|
||||
}
|
||||
605
vgui2/vgui_perftest/vguimaterial.cpp
Normal file
605
vgui2/vgui_perftest/vguimaterial.cpp
Normal file
@@ -0,0 +1,605 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
// tier 1
|
||||
#include "tier1/strtools.h"
|
||||
#include "utlvector.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
#include "bitmap/tgaloader.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "pixelwriter.h"
|
||||
|
||||
#include "vguimaterial.h"
|
||||
#include "materialsystem/itexture.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/materialsystemutil.h"
|
||||
#include "toolutils/enginetools_int.h"
|
||||
#include "bitmap/imageformat.h"
|
||||
#include "vtf/vtf.h"
|
||||
#include "tier1/keyvalues.h"
|
||||
#include "tier1/utllinkedlist.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include <vstdlib/random.h>
|
||||
#include "tier0/vprof.h"
|
||||
|
||||
#include "bitmap/psheet.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <vfw.h>
|
||||
|
||||
#define MAX_LAYERS 10
|
||||
|
||||
enum
|
||||
{
|
||||
SUBLAYER_STATIC,
|
||||
SUBLAYER_DYNAMIC,
|
||||
SUBLAYER_FONT,
|
||||
SUBLAYER_MAX,
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Class to render a zillion boxes with a tga material.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTGARenderer : public ITGARenderer
|
||||
{
|
||||
public:
|
||||
void Init( int screenWidth, int screenHeight, int numTiles );
|
||||
void Render();
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
|
||||
struct UIQuadInfo
|
||||
{
|
||||
public:
|
||||
UIQuadInfo()
|
||||
{
|
||||
sublayer = -1;
|
||||
sheetSequenceNumber = -1;
|
||||
color.r = 255;
|
||||
color.g = 255;
|
||||
color.b = 255;
|
||||
color.a = 255;
|
||||
|
||||
textureName = "";
|
||||
}
|
||||
|
||||
UIQuadInfo( int inXPos, int inYPos, int inWidth, int inHeight, int inSublayer, int inSheetSeqNo )
|
||||
{
|
||||
Assign( inXPos, inYPos, inWidth, inHeight, inSublayer, inSheetSeqNo, color );
|
||||
}
|
||||
|
||||
UIQuadInfo( int inXPos, int inYPos, int inWidth, int inHeight, int inSublayer, int inSheetSeqNo, color32 inColor )
|
||||
{
|
||||
Assign( inXPos, inYPos, inWidth, inHeight, inSublayer, inSheetSeqNo, inColor );
|
||||
}
|
||||
|
||||
void Assign( int inXPos, int inYPos, int inWidth, int inHeight, int inSublayer, int inSheetSeqNo, color32 inColor )
|
||||
{
|
||||
x1Pos = inXPos;
|
||||
y1Pos = inYPos;
|
||||
width = inWidth;
|
||||
height = inHeight;
|
||||
x2Pos = x1Pos + width;
|
||||
y2Pos = y1Pos + height;
|
||||
Assert( inSheetSeqNo != -1 );
|
||||
sublayer = inSublayer;
|
||||
sheetSequenceNumber = inSheetSeqNo;
|
||||
color = inColor;
|
||||
}
|
||||
|
||||
int x1Pos;
|
||||
int y1Pos;
|
||||
int x2Pos;
|
||||
int y2Pos;
|
||||
int width;
|
||||
int height;
|
||||
CUtlString textureName; // name if the texture that is inside the sheet
|
||||
int sheetSequenceNumber;
|
||||
color32 color;
|
||||
int sublayer;
|
||||
|
||||
};
|
||||
|
||||
struct SheetInfo
|
||||
{
|
||||
CUtlVector< CUtlString > m_SheetTexEntry;
|
||||
};
|
||||
|
||||
SheetInfo m_sheetDict[SUBLAYER_MAX];
|
||||
|
||||
void AddSheetTextureEntry( int sublayer, const char *pTextureName );
|
||||
int FindSheetTextureEntry( int sublayer, const char *pTextureName );
|
||||
|
||||
bool InitSheetTexture( int sublayer, const char *pBaseTextureName );
|
||||
CSheet *CTGARenderer::LoadSheet( IMaterial *pMaterial );
|
||||
CSheet *CTGARenderer::LoadSheet( char const *pszFname, ITexture *pTexture );
|
||||
void GenerateUIMesh( CMatRenderContextPtr &pRenderContext, IMesh* pMesh, CUtlLinkedList< UIQuadInfo > &quads, CSheet *pSheet );
|
||||
|
||||
void InitTiles( int screenWidth, int screenHeight, int &xPos, int &yPos, int width, int height, int count, int layer, int sublayer, color32 color, const char *pTextureName = NULL );
|
||||
void InitTiles( int screenWidth, int screenHeight, int &xPos, int &yPos, int width, int height, int count, int layer, int sublayer, const char *pTextureName );
|
||||
void InitTiles( int screenWidth, int screenHeight, int &xPos, int &yPos, int width, int height, int count, int layer, int sublayer, int sheetSeqNo, color32 color );
|
||||
void InitTiles( int screenWidth, int screenHeight, int &xPos, int &yPos, int width, int height, int count, int layer, int sublayer, int sheetSeqNo );
|
||||
UIQuadInfo CreateQuad( int xPos, int yPos, int width, int height, int sublayer, const char *pTextureName = NULL );
|
||||
UIQuadInfo CreateQuad( int xPos, int yPos, int width, int height, int sublayer, color32 color, const char *pTextureName = NULL );
|
||||
void AddQuad( UIQuadInfo &quadInfo, int layer );
|
||||
|
||||
struct LayerTextureInfo
|
||||
{
|
||||
CMaterialReference m_SublayerMaterial;
|
||||
CUtlReference< CSheet > m_Sheet;
|
||||
};
|
||||
|
||||
LayerTextureInfo m_LayerTextureInfo[SUBLAYER_MAX];
|
||||
|
||||
|
||||
struct LayerInfo
|
||||
{
|
||||
CUtlLinkedList< UIQuadInfo > *pQuads;
|
||||
};
|
||||
|
||||
// For 3 draw call per layer test.
|
||||
struct Layer
|
||||
{
|
||||
public:
|
||||
// Layer 0 is static
|
||||
// Layer 1 is dynamic
|
||||
// Layer 2 is font
|
||||
LayerInfo layerInfo[SUBLAYER_MAX];
|
||||
};
|
||||
|
||||
// Test with 10 layers, 3 draw calls per layer.
|
||||
CUtlVector< Layer > m_Layers;
|
||||
|
||||
bool m_bInitialized;
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton
|
||||
//-----------------------------------------------------------------------------
|
||||
static CTGARenderer s_TGARenderer;
|
||||
extern ITGARenderer *g_pTGARenderer = &s_TGARenderer;
|
||||
|
||||
// 3 drawcall one texture test.
|
||||
void CTGARenderer::Init( int screenWidth, int screenHeight, int numTiles )
|
||||
{
|
||||
m_bInitialized = false;
|
||||
|
||||
// Build texture dictionary
|
||||
AddSheetTextureEntry( SUBLAYER_STATIC, "pixel.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_STATIC, "decalposter003a.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_STATIC, "decalgraffiti037a.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_STATIC, "Climb_node.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_STATIC, "gibshooter.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_STATIC, "ErrorIcon.tga" );;
|
||||
|
||||
AddSheetTextureEntry( SUBLAYER_DYNAMIC, "glassclock001a.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_DYNAMIC, "decalgraffiti038a.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_DYNAMIC, "Air_node_hint.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_DYNAMIC, "info_lighting.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_DYNAMIC, "SelfIllumIcon.tga" );
|
||||
|
||||
AddSheetTextureEntry( SUBLAYER_FONT, "glasswindow006a.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_FONT, "decalgraffiti043a.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_FONT, "Ground_node.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_FONT, "info_target.tga" );
|
||||
AddSheetTextureEntry( SUBLAYER_FONT, "translucenticon.tga" );
|
||||
|
||||
// Load the sheet textures.
|
||||
bool bSuccess = InitSheetTexture( SUBLAYER_STATIC, "debug/sheettest/debug_meta1" );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
Warning( "CDataModel: Unable to load sheet for %s\n", "debug/sheettest/debug_meta1" );
|
||||
return;
|
||||
}
|
||||
bSuccess = InitSheetTexture( SUBLAYER_DYNAMIC, "debug/sheettest/debug_meta2" );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
Warning( "CDataModel: Unable to load sheet for %s\n", "debug/sheettest/debug_meta2" );
|
||||
return;
|
||||
}
|
||||
bSuccess = InitSheetTexture( SUBLAYER_FONT, "debug/sheettest/debug_meta3" );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
Warning( "CDataModel: Unable to load sheet for %s\n", "debug/sheettest/debug_meta3" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Create an array of quads for each sublayer on each layer.
|
||||
m_Layers.RemoveAll();
|
||||
for ( int i = 0; i < MAX_LAYERS; ++i )
|
||||
{
|
||||
m_Layers.AddToTail();
|
||||
for ( int j = 0; j < SUBLAYER_MAX; ++j )
|
||||
{
|
||||
m_Layers[i].layerInfo[j].pQuads = new CUtlLinkedList< UIQuadInfo >;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UIQuadInfo testQuad;
|
||||
testQuad = CreateQuad( 0, 0, 64, 64, SUBLAYER_STATIC, "gibshooter.tga" );
|
||||
AddQuad( testQuad, 0 );
|
||||
|
||||
|
||||
testQuad = CreateQuad( 0, 128, 128, 128, SUBLAYER_DYNAMIC, "Air_node_hint.tga" );
|
||||
AddQuad( testQuad, 0 );
|
||||
|
||||
|
||||
m_bInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool CTGARenderer::InitSheetTexture( int sublayer, const char *pBaseTextureName )
|
||||
{
|
||||
CUtlString materialName;
|
||||
switch (sublayer)
|
||||
{
|
||||
case SUBLAYER_STATIC:
|
||||
materialName = "statictx";
|
||||
break;
|
||||
case SUBLAYER_DYNAMIC:
|
||||
materialName = "dynamictx";
|
||||
break;
|
||||
case SUBLAYER_FONT:
|
||||
materialName = "fonttx";
|
||||
break;
|
||||
default:
|
||||
Warning( "CTGARenderer: Invalid sublayer for %s\n", pBaseTextureName );
|
||||
Assert(0);
|
||||
break;
|
||||
};
|
||||
|
||||
KeyValues *pVMTKeyValues = new KeyValues( "GameControls" );
|
||||
pVMTKeyValues->SetString( "$basetexture", pBaseTextureName );
|
||||
m_LayerTextureInfo[sublayer].m_SublayerMaterial.Init( materialName, TEXTURE_GROUP_OTHER, pVMTKeyValues );
|
||||
m_LayerTextureInfo[sublayer].m_SublayerMaterial->Refresh();
|
||||
CSheet *pSheet = LoadSheet( m_LayerTextureInfo[sublayer].m_SublayerMaterial );
|
||||
if ( pSheet == NULL )
|
||||
{
|
||||
Warning( "CTGARenderer: Unable to load sheet for %s %s\n", materialName.Get(), pBaseTextureName );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LayerTextureInfo[sublayer].m_Sheet.Set( pSheet );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::InitTiles( int screenWidth, int screenHeight, int &xPos, int &yPos, int width, int height, int count, int layer, int sublayer, int sheetSeqNo, color32 color )
|
||||
{
|
||||
|
||||
CUtlLinkedList< UIQuadInfo > *pQuads = m_Layers[layer].layerInfo[sublayer].pQuads;
|
||||
|
||||
for ( int i = 0; i < count; ++i )
|
||||
{
|
||||
UIQuadInfo quadInfo( xPos, yPos, width, height, sublayer, sheetSeqNo, color );
|
||||
pQuads->AddToTail( quadInfo );
|
||||
|
||||
xPos += width;
|
||||
if ( xPos >= screenWidth )
|
||||
{
|
||||
xPos = 0;
|
||||
yPos += height;
|
||||
}
|
||||
|
||||
if ( yPos >= screenHeight )
|
||||
{
|
||||
// just wrap.
|
||||
yPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::InitTiles( int screenWidth, int screenHeight, int &xPos, int &yPos, int width, int height, int count, int layer, int sublayer, int sheetSeqNo )
|
||||
{
|
||||
for ( int i = 0; i < count; ++i )
|
||||
{
|
||||
UIQuadInfo quadInfo( xPos, yPos, width, height, sublayer, sheetSeqNo );
|
||||
AddQuad( quadInfo, layer );
|
||||
|
||||
xPos += width;
|
||||
if ( xPos >= screenWidth )
|
||||
{
|
||||
xPos = 0;
|
||||
yPos += height;
|
||||
}
|
||||
|
||||
if ( yPos >= screenHeight )
|
||||
{
|
||||
// just wrap.
|
||||
yPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::InitTiles( int screenWidth, int screenHeight, int &xPos, int &yPos, int width, int height, int count,
|
||||
int layer, int sublayer, color32 color, const char *pTextureName )
|
||||
{
|
||||
int sheetSeqNo = FindSheetTextureEntry( sublayer, pTextureName );
|
||||
Assert( sheetSeqNo != -1 );
|
||||
InitTiles( screenWidth, screenHeight, xPos, yPos, width, height, count, layer, sublayer, sheetSeqNo, color );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::InitTiles( int screenWidth, int screenHeight, int &xPos, int &yPos, int width, int height, int count,
|
||||
int layer, int sublayer, const char *pTextureName )
|
||||
{
|
||||
int sheetSeqNo = FindSheetTextureEntry( sublayer, pTextureName );
|
||||
InitTiles( screenWidth, screenHeight, xPos, yPos, width, height, count, layer, sublayer, sheetSeqNo );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create a quad on a sublayer
|
||||
// Texture name is optional.
|
||||
//-----------------------------------------------------------------------------
|
||||
CTGARenderer::UIQuadInfo CTGARenderer::CreateQuad( int xPos, int yPos, int width, int height, int sublayer, const char *pTextureName )
|
||||
{
|
||||
int sheetSeqNo = FindSheetTextureEntry( sublayer, pTextureName );
|
||||
UIQuadInfo quadInfo( xPos, yPos, width, height, sublayer, sheetSeqNo );
|
||||
|
||||
return quadInfo;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create a quad on a sublayer
|
||||
// Texture name is optional.
|
||||
//-----------------------------------------------------------------------------
|
||||
CTGARenderer::UIQuadInfo CTGARenderer::CreateQuad( int xPos, int yPos, int width, int height, int sublayer, color32 color, const char *pTextureName )
|
||||
{
|
||||
int sheetSeqNo = FindSheetTextureEntry( sublayer, pTextureName );
|
||||
UIQuadInfo quadInfo( xPos, yPos, width, height, sublayer, sheetSeqNo, color );
|
||||
|
||||
return quadInfo;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::AddQuad( UIQuadInfo &quadInfo, int layer )
|
||||
{
|
||||
CUtlLinkedList< UIQuadInfo > *pQuads = m_Layers[layer].layerInfo[quadInfo.sublayer].pQuads;
|
||||
pQuads->AddToTail( quadInfo );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::AddSheetTextureEntry( int sublayer, const char *pTextureName )
|
||||
{
|
||||
m_sheetDict[sublayer].m_SheetTexEntry.AddToTail( pTextureName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTGARenderer::FindSheetTextureEntry( int sublayer, const char *pTextureName )
|
||||
{
|
||||
if ( pTextureName == NULL )
|
||||
return 0;
|
||||
|
||||
for ( int i = 0; i < m_sheetDict[sublayer].m_SheetTexEntry.Count(); ++i )
|
||||
{
|
||||
if ( !Q_strcmp( m_sheetDict[sublayer].m_SheetTexEntry[i], pTextureName ) )
|
||||
return i;
|
||||
}
|
||||
|
||||
Assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vguimatsurface/imatsystemsurface.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 3 draw calls per layer.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::Render()
|
||||
{
|
||||
VPROF_BUDGET( "Render", "Render" );
|
||||
if ( !m_bInitialized )
|
||||
{
|
||||
Warning( "CTGARenderer: Unable to render.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y, width, height;
|
||||
|
||||
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
||||
pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
|
||||
pRenderContext->ClearBuffers( true, true );
|
||||
|
||||
pRenderContext->GetViewport( x, y, width, height);
|
||||
|
||||
float flPixelOffsetX = 0.5f;
|
||||
float flPixelOffsetY = 0.5f;
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->PushMatrix();
|
||||
pRenderContext->LoadIdentity();
|
||||
pRenderContext->Scale( 1, -1, 1 );
|
||||
pRenderContext->Ortho( flPixelOffsetX, flPixelOffsetY, width + flPixelOffsetX, height + flPixelOffsetY, -1.0f, 1.0f );
|
||||
|
||||
// make sure there is no translation and rotation laying around
|
||||
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
||||
pRenderContext->PushMatrix();
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->PushMatrix();
|
||||
pRenderContext->LoadIdentity();
|
||||
|
||||
|
||||
// each sublayer should correspond to one meta texture binding.
|
||||
for ( int i = 0; i < MAX_LAYERS; ++i )
|
||||
{
|
||||
for ( int j = 0; j < SUBLAYER_MAX; ++j )
|
||||
{
|
||||
if ( m_Layers[i].layerInfo[j].pQuads->Count() == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
pRenderContext->Bind( m_LayerTextureInfo[j].m_SublayerMaterial, NULL );
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
|
||||
GenerateUIMesh( pRenderContext, pMesh, *(m_Layers[i].layerInfo[j].pQuads), m_LayerTextureInfo[j].m_Sheet );
|
||||
pMesh->Draw();
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the matrices
|
||||
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
|
||||
pRenderContext->PopMatrix();
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_MODEL );
|
||||
pRenderContext->PopMatrix();
|
||||
|
||||
pRenderContext->MatrixMode( MATERIAL_VIEW );
|
||||
pRenderContext->PopMatrix();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::Shutdown()
|
||||
{
|
||||
int count = 0;
|
||||
for ( int i = 0; i < MAX_LAYERS; ++i )
|
||||
{
|
||||
for ( int j = 0; j < SUBLAYER_MAX; j++ )
|
||||
{
|
||||
count += m_Layers[i].layerInfo[j].pQuads->Count();
|
||||
}
|
||||
}
|
||||
|
||||
Warning( "Total generated quads = %d\n", count );
|
||||
m_Layers.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// UI sheets
|
||||
//--------------------------------------------------------------------------------
|
||||
CSheet *CTGARenderer::LoadSheet( char const *pszFname, ITexture *pTexture )
|
||||
{
|
||||
CSheet *pNewSheet = NULL;
|
||||
|
||||
// get compact sheet representation held by texture
|
||||
size_t numBytes;
|
||||
void const *pSheet = pTexture->GetResourceData( VTF_RSRC_SHEET, &numBytes );
|
||||
if ( pSheet )
|
||||
{
|
||||
// expand compact sheet into fatter runtime form
|
||||
CUtlBuffer bufLoad( pSheet, numBytes, CUtlBuffer::READ_ONLY );
|
||||
pNewSheet = new CSheet( bufLoad );
|
||||
}
|
||||
|
||||
//m_SheetList[ pszFname ] = pNewSheet;
|
||||
return pNewSheet;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
CSheet *CTGARenderer::LoadSheet( IMaterial *pMaterial )
|
||||
{
|
||||
if ( !pMaterial )
|
||||
return NULL;
|
||||
|
||||
bool bFoundVar = false;
|
||||
IMaterialVar *pVar = pMaterial->FindVar( "$basetexture", &bFoundVar, true );
|
||||
|
||||
if ( bFoundVar && pVar && pVar->IsDefined() )
|
||||
{
|
||||
ITexture *pTex = pVar->GetTextureValue();
|
||||
if ( pTex && !pTex->IsError() )
|
||||
return LoadSheet( pTex->GetName(), pTex );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTGARenderer::GenerateUIMesh( CMatRenderContextPtr &pRenderContext, IMesh* pMesh, CUtlLinkedList< UIQuadInfo > &quads, CSheet *pSheet )
|
||||
{
|
||||
VPROF_BUDGET( "GenerateUIMesh", "GenerateUIMesh" );
|
||||
|
||||
if ( quads.Count() == 0 )
|
||||
return;
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, quads.Count() );
|
||||
|
||||
int x, y, width, height;
|
||||
pRenderContext->GetViewport( x, y, width, height);
|
||||
|
||||
{
|
||||
VPROF_BUDGET( "meshBuilder", "meshBuilder" );
|
||||
for( int i = quads.Head(); i != quads.InvalidIndex(); i = quads.Next( i ) )
|
||||
{
|
||||
Assert( pSheet );
|
||||
Assert( pSheet->m_SheetInfo[quads[i].sheetSequenceNumber].m_pSamples );
|
||||
SheetSequenceSample_t *pSample = pSheet->m_SheetInfo[quads[i].sheetSequenceNumber].m_pSamples;
|
||||
Assert( pSample );
|
||||
const SequenceSampleTextureCoords_t *pSample0 = &(pSample->m_TextureCoordData[0]);
|
||||
Assert( pSample0 );
|
||||
color32 c = quads[i].color;
|
||||
|
||||
// Top left
|
||||
meshBuilder.Position3f( quads[i].x1Pos, quads[i].y1Pos, 0.0f );
|
||||
meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
|
||||
meshBuilder.TexCoord3f( 0, pSample0->m_fLeft_U0, pSample0->m_fTop_V0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
// Top right
|
||||
meshBuilder.Position3f( quads[i].x2Pos, quads[i].y1Pos, 0.0f );
|
||||
meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
|
||||
meshBuilder.TexCoord3f( 0, pSample0->m_fRight_U0, pSample0->m_fTop_V0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
// Bottom right
|
||||
meshBuilder.Position3f( quads[i].x2Pos, quads[i].y2Pos, 0.0f );
|
||||
meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
|
||||
meshBuilder.TexCoord3f( 0, pSample0->m_fRight_U0, pSample0->m_fBottom_V0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
// Bottom left
|
||||
meshBuilder.Position3f( quads[i].x1Pos, quads[i].y2Pos, 0.0f );
|
||||
meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
|
||||
meshBuilder.TexCoord3f( 0, pSample0->m_fLeft_U0, pSample0->m_fBottom_V0, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
24
vgui2/vgui_perftest/vguimaterial.h
Normal file
24
vgui2/vgui_perftest/vguimaterial.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VGUIMATERIALS_H
|
||||
#define VGUIMATERIALS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class ITGARenderer
|
||||
{
|
||||
public:
|
||||
virtual void Init( int screenWidth, int screenHeight, int numTiles ) = 0;
|
||||
virtual void Render() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
};
|
||||
|
||||
extern ITGARenderer *g_pTGARenderer;
|
||||
|
||||
#endif // VGUIMATERIALS_H
|
||||
Reference in New Issue
Block a user