You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1023 lines
30 KiB
1023 lines
30 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//===========================================================================// |
|
|
|
#define PROTECTED_THINGS_DISABLE |
|
#define WIN32_LEAN_AND_MEAN |
|
#include <windows.h> |
|
#include "materialsystem/imaterialsystem.h" |
|
#include "materialsystem/IMaterialSystemHardwareConfig.h" |
|
#include "materialsystem/imaterialproxyfactory.h" |
|
#include "filesystem.h" |
|
#include "bitmap/imageformat.h" |
|
#include "materialsystem/MaterialSystem_Config.h" |
|
#include "tier0/icommandline.h" |
|
#include "tier1/strtools.h" |
|
#include "mathlib/mathlib.h" |
|
#include "materialsystem/imesh.h" |
|
#include "materialsystem/imaterial.h" |
|
#include "materialsystem/imaterialvar.h" |
|
#include "bitmap/tgawriter.h" |
|
#include <sys/types.h> |
|
#include <sys/stat.h> |
|
#include <direct.h> |
|
#include "vstdlib/cvar.h" |
|
#include "KeyValues.h" |
|
#include "tier1/utlbuffer.h" |
|
#include "tier2/tier2.h" |
|
|
|
#define CHECKERBOARD_DIMS 16 |
|
|
|
IMaterial *g_pProceduralMaterial = NULL; |
|
|
|
static char g_pCommandLine[1024]; |
|
static int g_ArgC = 0; |
|
static char* g_ppArgV[32]; |
|
static HWND g_HWnd = 0; |
|
static CreateInterfaceFn g_MaterialsFactory; |
|
|
|
static CSysModule *g_MaterialsDLL = NULL; |
|
|
|
static int g_RenderWidth = 640; |
|
static int g_RenderHeight = 480; |
|
static int g_RefreshRate = 60; |
|
|
|
static bool g_Exiting = false; |
|
|
|
void CreateLightmapPages( void ); |
|
void RenderFrame( void ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Command-line... |
|
//----------------------------------------------------------------------------- |
|
|
|
int FindCommand( const char *pCommand ) |
|
{ |
|
for ( int i = 0; i < g_ArgC; i++ ) |
|
{ |
|
if ( !stricmp( pCommand, g_ppArgV[i] ) ) |
|
return i; |
|
} |
|
return -1; |
|
} |
|
|
|
const char* CommandArgument( const char *pCommand ) |
|
{ |
|
int cmd = FindCommand( pCommand ); |
|
if ((cmd != -1) && (cmd < g_ArgC - 1)) |
|
{ |
|
return g_ppArgV[cmd+1]; |
|
} |
|
return 0; |
|
} |
|
|
|
void SetupCommandLine( const char* pCommandLine ) |
|
{ |
|
Q_strncpy( g_pCommandLine, pCommandLine, sizeof( g_pCommandLine ) ); |
|
|
|
g_ArgC = 0; |
|
|
|
char* pStr = g_pCommandLine; |
|
while ( *pStr ) |
|
{ |
|
pStr = strtok( pStr, " " ); |
|
if( !pStr ) |
|
{ |
|
break; |
|
} |
|
g_ppArgV[g_ArgC++] = pStr; |
|
pStr += strlen(pStr) + 1; |
|
} |
|
} |
|
//----------------------------------------------------------------------------- |
|
// DummyMaterialProxyFactory... |
|
//----------------------------------------------------------------------------- |
|
|
|
class DummyMaterialProxyFactory : public IMaterialProxyFactory |
|
{ |
|
public: |
|
virtual IMaterialProxy *CreateProxy( const char *proxyName ) {return NULL;} |
|
virtual void DeleteProxy( IMaterialProxy *pProxy ) {} |
|
}; |
|
static DummyMaterialProxyFactory g_DummyMaterialProxyFactory; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Spew function! |
|
//----------------------------------------------------------------------------- |
|
SpewRetval_t SpewFunc( SpewType_t spewType, char const *pMsg ) |
|
{ |
|
OutputDebugString( pMsg ); |
|
switch( spewType ) |
|
{ |
|
case SPEW_MESSAGE: |
|
case SPEW_WARNING: |
|
case SPEW_LOG: |
|
OutputDebugString( pMsg ); |
|
return SPEW_CONTINUE; |
|
|
|
case SPEW_ASSERT: |
|
case SPEW_ERROR: |
|
default: |
|
::MessageBox( NULL, pMsg, "Error!", MB_OK ); |
|
return SPEW_DEBUGGER; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Error... |
|
//----------------------------------------------------------------------------- |
|
|
|
void DisplayError( const char* pError, ... ) |
|
{ |
|
va_list argptr; |
|
char msg[1024]; |
|
|
|
va_start( argptr, pError ); |
|
Q_vsnprintf( msg, sizeof( msg ), pError, argptr ); |
|
va_end( argptr ); |
|
|
|
MessageBox( 0, msg, 0, MB_OK ); |
|
} |
|
|
|
|
|
|
|
IFileSystem *g_pFileSystem; |
|
static CSysModule *g_pFileSystemModule = NULL; |
|
static CreateInterfaceFn g_pFileSystemFactory = NULL; |
|
static bool FileSystem_LoadDLL( void ) |
|
{ |
|
g_pFileSystemModule = Sys_LoadModule( "filesystem_stdio.dll" ); |
|
Assert( g_pFileSystemModule ); |
|
if( !g_pFileSystemModule ) |
|
{ |
|
return false; |
|
} |
|
|
|
g_pFileSystemFactory = Sys_GetFactory( g_pFileSystemModule ); |
|
if( !g_pFileSystemFactory ) |
|
{ |
|
return false; |
|
} |
|
g_pFileSystem = ( IFileSystem * )g_pFileSystemFactory( FILESYSTEM_INTERFACE_VERSION, NULL ); |
|
Assert( g_pFileSystem ); |
|
if( !g_pFileSystem ) |
|
{ |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
void FileSystem_UnloadDLL( void ) |
|
{ |
|
if ( !g_pFileSystemModule ) |
|
return; |
|
|
|
Sys_UnloadModule( g_pFileSystemModule ); |
|
g_pFileSystemModule = 0; |
|
} |
|
|
|
void FileSystem_Init( ) |
|
{ |
|
if( !FileSystem_LoadDLL() ) |
|
{ |
|
return; |
|
} |
|
|
|
g_pFileSystem->RemoveSearchPath( NULL, "GAME" ); |
|
g_pFileSystem->AddSearchPath( "hl2", "GAME", PATH_ADD_TO_HEAD ); |
|
} |
|
|
|
void FileSystem_Shutdown( void ) |
|
{ |
|
g_pFileSystem->Shutdown(); |
|
|
|
FileSystem_UnloadDLL(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Unloads the material system .dll |
|
//----------------------------------------------------------------------------- |
|
void UnloadMaterialSystem( void ) |
|
{ |
|
if ( !g_MaterialsFactory ) |
|
return; |
|
|
|
Sys_UnloadModule( g_MaterialsDLL ); |
|
g_MaterialsDLL = NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Loads the material system dll |
|
//----------------------------------------------------------------------------- |
|
void LoadMaterialSystem( void ) |
|
{ |
|
if( g_MaterialsFactory ) |
|
{ |
|
return; |
|
} |
|
|
|
Assert( !g_MaterialsDLL ); |
|
|
|
g_MaterialsDLL = Sys_LoadModule( "MaterialSystem.dll" ); |
|
|
|
g_MaterialsFactory = Sys_GetFactory( g_MaterialsDLL ); |
|
if ( !g_MaterialsFactory ) |
|
{ |
|
DisplayError( "LoadMaterialSystem: Failed to load MaterialSystem.DLL\n" ); |
|
return; |
|
} |
|
|
|
if ( g_MaterialsFactory ) |
|
{ |
|
g_pMaterialSystem = (IMaterialSystem *)g_MaterialsFactory( MATERIAL_SYSTEM_INTERFACE_VERSION, NULL ); |
|
if ( !g_pMaterialSystem ) |
|
{ |
|
DisplayError( "Could not get the material system interface from materialsystem.dll (a)" ); |
|
} |
|
} |
|
else |
|
{ |
|
DisplayError( "Could not find factory interface in library MaterialSystem.dll" ); |
|
} |
|
} |
|
|
|
void InitMaterialSystemConfig(MaterialSystem_Config_t *pConfig) |
|
{ |
|
} |
|
|
|
CreateInterfaceFn g_MaterialSystemClientFactory; |
|
void Shader_Init( HWND mainWindow ) |
|
{ |
|
LoadMaterialSystem(); |
|
Assert( g_pMaterialSystem ); |
|
|
|
// FIXME: Where do we put this? |
|
const char* pDLLName; |
|
pDLLName = "shaderapidx9"; |
|
|
|
// assume that IFileSystem paths have already been set via g_pFileSystem |
|
g_MaterialSystemClientFactory = g_pMaterialSystem->Init( |
|
pDLLName, &g_DummyMaterialProxyFactory, g_pFileSystemFactory, VStdLib_GetICVarFactory() ); |
|
if (!g_MaterialSystemClientFactory) |
|
{ |
|
DisplayError( "Unable to init shader system\n" ); |
|
} |
|
|
|
// Get the adapter from the command line.... |
|
MaterialVideoMode_t mode; |
|
memset( &mode, 0, sizeof( mode ) ); |
|
mode.m_Width = g_RenderWidth; |
|
mode.m_Height = g_RenderHeight; |
|
mode.m_Format = IMAGE_FORMAT_BGRX8888; |
|
mode.m_RefreshRate = g_RefreshRate; |
|
// bool modeSet = g_pMaterialSystem->SetMode( (void*)mainWindow, mode, modeFlags ); |
|
// if (!modeSet) |
|
// { |
|
// DisplayError( "Unable to set mode\n" ); |
|
// } |
|
|
|
g_pMaterialSystemHardwareConfig = (IMaterialSystemHardwareConfig*) |
|
g_MaterialSystemClientFactory( MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION, 0 ); |
|
if ( !g_pMaterialSystemHardwareConfig ) |
|
{ |
|
DisplayError( "Could not get the material system hardware config interface!" ); |
|
} |
|
|
|
MaterialSystem_Config_t config; |
|
InitMaterialSystemConfig(&config); |
|
g_pMaterialSystem->OverrideConfig( config, false ); |
|
if( FindCommand( "-stub" ) != -1 ) |
|
{ |
|
g_pMaterialSystem->SetInStubMode( true ); |
|
} |
|
} |
|
|
|
void Shader_Shutdown( HWND hwnd ) |
|
{ |
|
// Recursive shutdown |
|
if ( !g_pMaterialSystem ) |
|
return; |
|
|
|
g_pMaterialSystem->Shutdown( ); |
|
g_pMaterialSystem = NULL; |
|
UnloadMaterialSystem(); |
|
} |
|
|
|
static void CalcWindowSize( int desiredRenderingWidth, int desiredRenderingHeight, |
|
int *windowWidth, int *windowHeight ) |
|
{ |
|
int borderX, borderY; |
|
borderX = (GetSystemMetrics(SM_CXFIXEDFRAME) + 1) * 2; |
|
borderY = (GetSystemMetrics(SM_CYFIXEDFRAME) + 1) * 2 + GetSystemMetrics(SM_CYSIZE) + 1; |
|
*windowWidth = desiredRenderingWidth + borderX; |
|
*windowHeight = desiredRenderingHeight + borderY; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Window create, destroy... |
|
//----------------------------------------------------------------------------- |
|
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) |
|
{ |
|
switch( msg ) |
|
{ |
|
case WM_PAINT: |
|
RenderFrame(); |
|
break; |
|
// abort when ESC is hit |
|
case WM_CHAR: |
|
switch(wParam) |
|
{ |
|
case VK_ESCAPE: |
|
SendMessage( g_HWnd, WM_CLOSE, 0, 0 ); |
|
break; |
|
} |
|
break; |
|
|
|
case WM_DESTROY: |
|
g_Exiting = true; |
|
PostQuitMessage( 0 ); |
|
return 0; |
|
} |
|
|
|
return DefWindowProc( hWnd, msg, wParam, lParam ); |
|
} |
|
|
|
bool CreateAppWindow( const char* pAppName, int width, int height ) |
|
{ |
|
// Register the window class |
|
WNDCLASSEX windowClass = |
|
{ |
|
sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, |
|
GetModuleHandle(NULL), NULL, NULL, NULL, NULL, |
|
pAppName, NULL |
|
}; |
|
|
|
RegisterClassEx( &windowClass ); |
|
|
|
// Create the application's window |
|
g_HWnd = CreateWindow( pAppName, pAppName, |
|
WS_OVERLAPPEDWINDOW, |
|
0, 0, width, height, |
|
GetDesktopWindow(), NULL, windowClass.hInstance, NULL ); |
|
|
|
ShowWindow (g_HWnd, SW_SHOWDEFAULT); |
|
|
|
return (g_HWnd != 0); |
|
} |
|
|
|
void DestroyAppWindow() |
|
{ |
|
if (g_HWnd) |
|
DestroyWindow( g_HWnd ); |
|
} |
|
bool Init( const char* pCommands) |
|
{ |
|
// Store off the command line... |
|
SetupCommandLine( pCommands ); |
|
FileSystem_Init( ); |
|
|
|
/* figure out g_Renderwidth and g_RenderHeight */ |
|
g_RenderWidth = -1; |
|
g_RenderHeight = -1; |
|
|
|
g_RenderWidth = 640; |
|
g_RenderHeight = 480; |
|
|
|
int windowWidth, windowHeight; |
|
CalcWindowSize( g_RenderWidth, g_RenderHeight, &windowWidth, &windowHeight ); |
|
|
|
if( !CreateAppWindow( "matsys_regressiontest", windowWidth, windowHeight ) ) |
|
{ |
|
return false; |
|
} |
|
|
|
Shader_Init( g_HWnd ); |
|
g_pMaterialSystem->CacheUsedMaterials(); |
|
CreateLightmapPages(); |
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Return the directory where this .exe is running from |
|
// Output : char |
|
//----------------------------------------------------------------------------- |
|
|
|
static char *GetBaseDir( const char *pszBuffer ) |
|
{ |
|
static char basedir[ MAX_PATH ]; |
|
char szBuffer[ MAX_PATH ]; |
|
int j; |
|
char *pBuffer = NULL; |
|
|
|
Q_strncpy( szBuffer, pszBuffer, sizeof( szBuffer ) ); |
|
|
|
pBuffer = strrchr( szBuffer,'\\' ); |
|
if ( pBuffer ) |
|
{ |
|
*(pBuffer+1) = '\0'; |
|
} |
|
|
|
Q_strncpy( basedir, szBuffer, sizeof( basedir ) ); |
|
|
|
j = strlen( basedir ); |
|
if (j > 0) |
|
{ |
|
if ( ( basedir[ j-1 ] == '\\' ) || |
|
( basedir[ j-1 ] == '/' ) ) |
|
{ |
|
basedir[ j-1 ] = 0; |
|
} |
|
} |
|
|
|
return basedir; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Shutdown |
|
//----------------------------------------------------------------------------- |
|
|
|
void Shutdown() |
|
{ |
|
// Close the window |
|
DestroyAppWindow(); |
|
|
|
Shader_Shutdown( g_HWnd ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Pump windows messages |
|
//----------------------------------------------------------------------------- |
|
|
|
void PumpWindowsMessages () |
|
{ |
|
MSG msg; |
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == TRUE) |
|
{ |
|
TranslateMessage(&msg); |
|
DispatchMessage(&msg); |
|
} |
|
|
|
InvalidateRect(g_HWnd, NULL, false); |
|
UpdateWindow(g_HWnd); |
|
} |
|
|
|
MaterialSystem_SortInfo_t *g_pMaterialSortInfo = NULL; |
|
struct LightmapInfo_t |
|
{ |
|
int m_LightmapDims[2]; |
|
int m_LightmapPageDims[2]; |
|
int m_OffsetIntoLightmapPage[2]; |
|
int m_SortID; |
|
}; |
|
|
|
LightmapInfo_t g_CheckerboardLightmapInfo; |
|
|
|
void AllocateLightmap( LightmapInfo_t& lightmapInfo, int width, int height ) |
|
{ |
|
lightmapInfo.m_LightmapDims[0] = width; |
|
lightmapInfo.m_LightmapDims[1] = height; |
|
// HACK! We don't ever use this material for anything. . just need it for allocating lightmaps. |
|
CMatRenderContextPtr pRenderContext( materials ); |
|
IMaterial *pHackMaterial = g_pMaterialSystem->FindMaterial( "shadertest/lightmappedgeneric", TEXTURE_GROUP_OTHER ); |
|
pRenderContext->Bind( pHackMaterial ); |
|
lightmapInfo.m_SortID = |
|
g_pMaterialSystem->AllocateLightmap( 16, 16, lightmapInfo.m_OffsetIntoLightmapPage, pHackMaterial ); |
|
} |
|
|
|
void Lightmap_PostAllocation( LightmapInfo_t& lightmapInfo ) |
|
{ |
|
g_pMaterialSystem->GetLightmapPageSize( lightmapInfo.m_SortID, |
|
&lightmapInfo.m_LightmapPageDims[0], &lightmapInfo.m_LightmapPageDims[1] ); |
|
} |
|
|
|
void UpdateLightmap( LightmapInfo_t& lightmapInfo, float *data ) |
|
{ |
|
g_pMaterialSystem->UpdateLightmap( g_pMaterialSortInfo[lightmapInfo.m_SortID].lightmapPageID, |
|
lightmapInfo.m_LightmapDims, lightmapInfo.m_OffsetIntoLightmapPage, data, NULL, NULL, NULL ); |
|
} |
|
|
|
void CreateLightmapPages( void ) |
|
{ |
|
g_pMaterialSystem->BeginLightmapAllocation(); |
|
|
|
AllocateLightmap( g_CheckerboardLightmapInfo, CHECKERBOARD_DIMS, CHECKERBOARD_DIMS ); |
|
|
|
g_pMaterialSystem->EndLightmapAllocation(); |
|
int numSortIDs = g_pMaterialSystem->GetNumSortIDs(); |
|
g_pMaterialSortInfo = new MaterialSystem_SortInfo_t[numSortIDs]; |
|
g_pMaterialSystem->GetSortInfo( g_pMaterialSortInfo ); |
|
|
|
Lightmap_PostAllocation( g_CheckerboardLightmapInfo ); |
|
|
|
float checkerboardImage[CHECKERBOARD_DIMS*CHECKERBOARD_DIMS*4]; |
|
int x, y; |
|
for( y = 0; y < CHECKERBOARD_DIMS; y++ ) |
|
{ |
|
for( x = 0; x < CHECKERBOARD_DIMS; x++ ) |
|
{ |
|
if( ( x + y ) & 1 ) |
|
{ |
|
checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+0] = 1.0f; |
|
checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+1] = 1.0f; |
|
checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+2] = 1.0f; |
|
checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+3] = 1.0f; |
|
} |
|
else |
|
{ |
|
checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+0] = 0.0f; |
|
checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+1] = 0.0f; |
|
checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+2] = 0.0f; |
|
checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+3] = 1.0f; |
|
} |
|
} |
|
} |
|
|
|
UpdateLightmap( g_CheckerboardLightmapInfo, checkerboardImage ); |
|
} |
|
|
|
void LightmapTexCoord( CMeshBuilder& meshBuilder, LightmapInfo_t lightmapInfo, float s, float t ) |
|
{ |
|
// add a one texel border. |
|
float newS = ( s * ( lightmapInfo.m_LightmapDims[0] - 2 ) ) + 1; |
|
float newT = ( t * ( lightmapInfo.m_LightmapDims[1] - 2 ) ) + 1; |
|
newS += lightmapInfo.m_OffsetIntoLightmapPage[0]; |
|
newT += lightmapInfo.m_OffsetIntoLightmapPage[1]; |
|
newS *= 1.0f / lightmapInfo.m_LightmapPageDims[0]; |
|
newT *= 1.0f / lightmapInfo.m_LightmapPageDims[1]; |
|
meshBuilder.TexCoord2f( 1, newS, newT ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Update |
|
//----------------------------------------------------------------------------- |
|
bool Update() |
|
{ |
|
PumpWindowsMessages(); |
|
return g_Exiting; |
|
} |
|
|
|
void ScreenShot( const char *pFilename ) |
|
{ |
|
// bitmap bits |
|
unsigned char *pImage = ( unsigned char * )malloc( g_RenderWidth * 3 * g_RenderHeight ); |
|
|
|
// Get Bits from the material system |
|
CMatRenderContextPtr pRenderContext( materials ); |
|
pRenderContext->ReadPixels( 0, 0, g_RenderWidth, g_RenderHeight, pImage, IMAGE_FORMAT_RGB888 ); |
|
|
|
CUtlBuffer outBuf; |
|
if( !TGAWriter::WriteToBuffer( pImage, outBuf, g_RenderWidth, g_RenderHeight, IMAGE_FORMAT_RGB888, |
|
IMAGE_FORMAT_RGB888 ) ) |
|
{ |
|
Error( "Couldn't write %s\n", pFilename ); |
|
} |
|
if ( !g_pFullFileSystem->WriteFile( pFilename, NULL, outBuf ) ) |
|
{ |
|
Error( "Couldn't write %s\n", pFilename ); |
|
} |
|
|
|
free( pImage ); |
|
} |
|
|
|
void SetVar( const char *pVarName, const char *pStringValue ) |
|
{ |
|
IMaterialVar *pVar = g_pProceduralMaterial->FindVar( pVarName, NULL ); |
|
if( pStringValue ) |
|
{ |
|
pVar->SetStringValue( pStringValue ); |
|
} |
|
else |
|
{ |
|
pVar->SetUndefined(); |
|
} |
|
} |
|
|
|
void SetVar( const char *pVarName, int val ) |
|
{ |
|
IMaterialVar *pVar = g_pProceduralMaterial->FindVar( pVarName, NULL ); |
|
pVar->SetIntValue( val ); |
|
} |
|
|
|
void SetFlag( MaterialVarFlags_t flag, int val ) |
|
{ |
|
g_pProceduralMaterial->SetMaterialVarFlag( flag, val ? true : false ); |
|
} |
|
|
|
void DrawBackground( void ) |
|
{ |
|
CMatRenderContextPtr pRenderContext( materials ); |
|
IMaterial *pMaterial = g_pMaterialSystem->FindMaterial( "matsys_regressiontest/background", TEXTURE_GROUP_OTHER ); |
|
pRenderContext->Bind( pMaterial ); |
|
|
|
IMesh *pMesh = pRenderContext->GetDynamicMesh(); |
|
CMeshBuilder meshBuilder; |
|
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); |
|
|
|
#define X 500.0f |
|
#define Y 500.0f |
|
#define Z -500.0f |
|
|
|
meshBuilder.Position3f( -X, Y, Z ); |
|
meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( X, Y, Z ); |
|
meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( X, -Y, Z ); |
|
meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( -X, -Y, Z ); |
|
meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.End(); |
|
pMesh->Draw(); |
|
|
|
#undef X |
|
#undef Y |
|
#undef Z |
|
} |
|
|
|
void BeginFrame( void ) |
|
{ |
|
g_pMaterialSystem->BeginFrame( 0 ); |
|
|
|
CMatRenderContextPtr pRenderContext( materials ); |
|
pRenderContext->ClearColor3ub( 255, 0, 0 ); |
|
pRenderContext->ClearBuffers( true, true ); |
|
pRenderContext->Viewport( 0, 0, g_RenderWidth, g_RenderHeight ); |
|
|
|
pRenderContext->MatrixMode( MATERIAL_PROJECTION ); |
|
pRenderContext->LoadIdentity(); |
|
pRenderContext->PerspectiveX( 90.0f, ( g_RenderWidth / g_RenderHeight), 1.0f, 500000.0f ); |
|
|
|
pRenderContext->MatrixMode( MATERIAL_VIEW ); |
|
pRenderContext->LoadIdentity(); |
|
|
|
pRenderContext->MatrixMode( MATERIAL_MODEL ); |
|
pRenderContext->LoadIdentity(); |
|
} |
|
|
|
void EndFrame( void ) |
|
{ |
|
g_pMaterialSystem->EndFrame(); |
|
g_pMaterialSystem->SwapBuffers(); |
|
} |
|
|
|
void DrawQuad( const LightmapInfo_t& lightmapInfo ) |
|
{ |
|
CMatRenderContextPtr pRenderContext( materials ); |
|
pRenderContext->BindLightmapPage( g_pMaterialSortInfo[lightmapInfo.m_SortID].lightmapPageID ); |
|
|
|
pRenderContext->Bind( g_pProceduralMaterial ); |
|
|
|
IMesh *pMesh = pRenderContext->GetDynamicMesh(); |
|
CMeshBuilder meshBuilder; |
|
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); |
|
|
|
#define X 350.0f |
|
#define Y (X*(4.0f/3.0f)) |
|
#define Z -500.0f |
|
|
|
meshBuilder.Position3f( -X, Y, Z ); |
|
meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); |
|
LightmapTexCoord( meshBuilder, lightmapInfo, 0.0f, 0.0f ); |
|
meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f ); |
|
meshBuilder.Color4f( 1.0f, 0.0f, 0.0f, 1.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( X, Y, Z ); |
|
meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); |
|
LightmapTexCoord( meshBuilder, lightmapInfo, 1.0f, 0.0f ); |
|
meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f ); |
|
meshBuilder.Color4f( 1.0f, 1.0f, 0.0f, 1.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( X, -Y, Z ); |
|
meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); |
|
LightmapTexCoord( meshBuilder, lightmapInfo, 1.0f, 1.0f ); |
|
meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f ); |
|
meshBuilder.Color4f( 1.0f, 1.0f, 1.0f, 0.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( -X, -Y, Z ); |
|
meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); |
|
LightmapTexCoord( meshBuilder, lightmapInfo, 0.0f, 1.0f ); |
|
meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f ); |
|
meshBuilder.Color4f( 0.0f, 1.0f, 1.0f, 1.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.End(); |
|
pMesh->Draw(); |
|
|
|
#undef X |
|
#undef Y |
|
#undef Z |
|
} |
|
|
|
void TestLightmappedGeneric_dx80( void ) |
|
{ |
|
/* |
|
based on lightmappedgeneric_vs11.fxc: |
|
// STATIC: "DETAIL" "0..1" |
|
// STATIC: "ENVMAP" "0..1" |
|
// STATIC: "ENVMAPCAMERASPACE" "0..1" |
|
// STATIC: "ENVMAPSPHERE" "0..1" |
|
// STATIC: "VERTEXCOLOR" "0..1" |
|
// DYNAMIC: "FOGTYPE" "0..1" |
|
|
|
// SKIP: $ENVMAPCAMERASPACE && $ENVMAPSPHERE |
|
// SKIP: !$ENVMAP && ( $ENVMAPCAMERASPACE || $ENVMAPSPHERE ) |
|
|
|
based on lightmappedgeneric_ps11.fxc: |
|
// STATIC: "BASETEXTURE" "0..1" |
|
// STATIC: "ENVMAP" "0..1" |
|
// STATIC: "ENVMAPMASK" "0..1" |
|
// STATIC: "SELFILLUM" "0..1" |
|
// STATIC: "BASEALPHAENVMAPMASK" "0..1" |
|
|
|
// SKIP: !$ENVMAP && ( $BASEALPHAENVMAPMASK || $ENVMAPMASK ) |
|
// SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK |
|
// SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK |
|
// SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK |
|
// SKIP: $SELFILLUM && $BASEALPHAENVMAPMASK |
|
// SKIP: !$BASETEXTURE && $SELFILLUM |
|
|
|
|
|
Versions with DETAIL aren't implemented yet in HLSL, but we'll go ahead and test those. |
|
*/ |
|
// The following are shader combos from lightmappedgeneric_ps20 |
|
for( int BUMPMAP = 0; BUMPMAP <= 1; BUMPMAP++ ) |
|
{ |
|
for( int NORMALMAPALPHAENVMAPMASK = 0; NORMALMAPALPHAENVMAPMASK <= 1; NORMALMAPALPHAENVMAPMASK++ ) |
|
{ |
|
// The following are shader combos from lightmappedgeneric_ps11 (that aren't in lightmappedgenerc_vs11) |
|
for( int BASETEXTURE = 0; BASETEXTURE <= 1; BASETEXTURE++ ) |
|
{ |
|
for( int ENVMAPMASK = 0; ENVMAPMASK <= 1; ENVMAPMASK++ ) |
|
{ |
|
for( int SELFILLUM = 0; SELFILLUM <= 1; SELFILLUM++ ) |
|
{ |
|
for( int BASEALPHAENVMAPMASK = 0; BASEALPHAENVMAPMASK <= 1; BASEALPHAENVMAPMASK++ ) |
|
{ |
|
// The following are shader combos from lightmappedgeneric_vs11 |
|
for( int DETAIL = 0; DETAIL <= 1; DETAIL++ ) |
|
{ |
|
for( int ENVMAP = 0; ENVMAP <= 1; ENVMAP++ ) |
|
{ |
|
for( int ENVMAPCAMERASPACE = 0; ENVMAPCAMERASPACE <= 1; ENVMAPCAMERASPACE++ ) |
|
{ |
|
for( int ENVMAPSPHERE = 0; ENVMAPSPHERE <= 1; ENVMAPSPHERE++ ) |
|
{ |
|
for( int VERTEXCOLOR = 0; VERTEXCOLOR <= 1; VERTEXCOLOR++ ) |
|
{ |
|
// for( int FOGTYPE = 0; FOGTYPE <= 1; FOGTYPE++ ) |
|
{ |
|
// conditional beneath here are flags, not shader combos |
|
for( int ALPHATEST = 0; ALPHATEST <= 1; ALPHATEST++ ) |
|
{ |
|
for( int TRANSLUCENT = 0; TRANSLUCENT <= 1; TRANSLUCENT++ ) |
|
{ |
|
for( int COLORMODULATE = 0; COLORMODULATE <= 1; COLORMODULATE++ ) |
|
{ |
|
for( int ALPHAMODULATE = 0; ALPHAMODULATE <= 1; ALPHAMODULATE++ ) |
|
{ |
|
#if 0 |
|
BUMPMAP = 0; |
|
NORMALMAPALPHAENVMAPMASK = 0; |
|
BASETEXTURE = 1; |
|
ENVMAPMASK = 0; |
|
SELFILLUM = 0; |
|
BASEALPHAENVMAPMASK = 1; |
|
DETAIL = 0; |
|
ENVMAP = 1; |
|
ENVMAPCAMERASPACE = 0; |
|
ENVMAPSPHERE = 0; |
|
VERTEXCOLOR = 0; |
|
ALPHATEST = 0; |
|
TRANSLUCENT = 0; |
|
COLORMODULATE = 0; |
|
ALPHAMODULATE = 0; |
|
#endif |
|
// skip commands from shader lightmappedgeneric_vs11 |
|
if( ENVMAPCAMERASPACE && ENVMAPSPHERE ) continue; |
|
if( !ENVMAP && ( ENVMAPCAMERASPACE || ENVMAPSPHERE ) ) continue; |
|
|
|
// skip commands from shader lihgtmappedgeneric_ps11 |
|
if( !ENVMAP && ( BASEALPHAENVMAPMASK || ENVMAPMASK ) ) continue; |
|
if( !BASETEXTURE && BASEALPHAENVMAPMASK ) continue; |
|
if( BASEALPHAENVMAPMASK && ENVMAPMASK ) continue; |
|
if( !BASETEXTURE && BASEALPHAENVMAPMASK ) continue; |
|
if( SELFILLUM && BASEALPHAENVMAPMASK ) continue; |
|
if( !BASETEXTURE && SELFILLUM ) continue; |
|
|
|
// skip commands from shader lightmappedgeneric_ps20 |
|
if( DETAIL && BUMPMAP ) continue; |
|
if( ENVMAPMASK && BUMPMAP ) continue; |
|
if( NORMALMAPALPHAENVMAPMASK && BASEALPHAENVMAPMASK ) continue; |
|
if( NORMALMAPALPHAENVMAPMASK && ENVMAPMASK ) continue; |
|
if( BASEALPHAENVMAPMASK && ENVMAPMASK ) continue; |
|
if( BASEALPHAENVMAPMASK && SELFILLUM ) continue; |
|
|
|
// skip commands from flags that don't make sense (or we don't want to test) |
|
if( !BASETEXTURE && ( ALPHATEST || TRANSLUCENT ) ) continue; |
|
if( TRANSLUCENT && ALPHATEST ) continue; |
|
|
|
KeyValues *pKeyValues = new KeyValues( "lightmappedgeneric" ); |
|
if ( BASETEXTURE ) |
|
{ |
|
pKeyValues->SetString( "$basetexture", "matsys_regressiontest/basetexture" ); |
|
} |
|
if ( ENVMAPMASK ) |
|
{ |
|
pKeyValues->SetString( "$envmapmask", "matsys_regressiontest/specularmask" ); |
|
} |
|
if ( SELFILLUM ) |
|
{ |
|
pKeyValues->SetInt( "$selfillum", 1 ); |
|
} |
|
if ( BASEALPHAENVMAPMASK ) |
|
{ |
|
pKeyValues->SetInt( "$basealphaenvmapmask", 1 ); |
|
} |
|
if ( BUMPMAP ) |
|
{ |
|
pKeyValues->SetString( "$bumpmap", "matsys_regressiontest/normalmap_normal" ); |
|
} |
|
if ( DETAIL ) |
|
{ |
|
pKeyValues->SetString( "$detail", "matsys_regressiontest/detail" ); |
|
pKeyValues->SetFloat( "$detailscale", 0.5f ); |
|
} |
|
if ( ENVMAP ) |
|
{ |
|
pKeyValues->SetString( "$envmap", "matsys_regressiontest/cubemap" ); |
|
} |
|
if ( BASEALPHAENVMAPMASK ) |
|
{ |
|
pKeyValues->SetInt( "$basealphaenvmapmask", 1 ); |
|
} |
|
if ( NORMALMAPALPHAENVMAPMASK ) |
|
{ |
|
pKeyValues->SetInt( "$normalmapalphaenvmapmask", 1 ); |
|
} |
|
if ( TRANSLUCENT ) |
|
{ |
|
pKeyValues->SetInt( "$translucent", 1 ); |
|
} |
|
if ( ENVMAPCAMERASPACE ) |
|
{ |
|
pKeyValues->SetInt( "$envmapcameraspace", 1 ); |
|
} |
|
if ( ENVMAPSPHERE ) |
|
{ |
|
pKeyValues->SetInt( "$envmapsphere", 1 ); |
|
} |
|
if ( VERTEXCOLOR ) |
|
{ |
|
pKeyValues->SetInt( "$vertexcolor", 1 ); |
|
} |
|
if ( ALPHATEST ) |
|
{ |
|
pKeyValues->SetInt( "$alphatest", 1 ); |
|
} |
|
if ( COLORMODULATE ) |
|
{ |
|
pKeyValues->SetString( "$color", "[1.0 0.8 0.5]" ); |
|
} |
|
if ( ALPHAMODULATE ) |
|
{ |
|
pKeyValues->SetFloat( "$alpha", 0.6f ); |
|
} |
|
|
|
// FIXME: ignoring fogtype for now. |
|
// hack hack - LEAK - need to figure out how to clear a material out. |
|
g_pProceduralMaterial = g_pMaterialSystem->CreateMaterial( "test", pKeyValues ); |
|
g_pProceduralMaterial->Refresh(); |
|
|
|
BeginFrame(); |
|
DrawBackground(); |
|
DrawQuad( g_CheckerboardLightmapInfo ); |
|
EndFrame(); |
|
char filename[MAX_PATH]; |
|
sprintf( filename, "%s\\lightmappedgeneric_dx80", CommandLine()->ParmValue( "-targetdir" ) ); |
|
|
|
if( BUMPMAP ) Q_strcat( filename, "_BUMPMAP", sizeof(filename) ); |
|
if( NORMALMAPALPHAENVMAPMASK ) Q_strcat( filename, "_NORMALMAPALPHAENVMAPMASK", sizeof(filename) ); |
|
|
|
if( BASETEXTURE ) Q_strcat( filename, "_BASE", sizeof(filename) ); |
|
if( ENVMAPMASK ) Q_strcat( filename, "_ENVMAPMASK", sizeof(filename) ); |
|
if( SELFILLUM ) Q_strcat( filename, "_SELFILLUM", sizeof(filename) ); |
|
if( BASEALPHAENVMAPMASK ) Q_strcat( filename, "_BASEALPHAENVMAPMASK", sizeof(filename) ); |
|
|
|
if( DETAIL ) Q_strcat( filename, "_DETAIL", sizeof(filename) ); |
|
if( ENVMAP ) Q_strcat( filename, "_ENVMAP", sizeof(filename) ); |
|
if( ENVMAPCAMERASPACE ) Q_strcat( filename, "_ENVMAPCAMERASPACE", sizeof(filename) ); |
|
if( ENVMAPSPHERE ) Q_strcat( filename, "_ENVMAPSPHERE", sizeof(filename) ); |
|
if( VERTEXCOLOR ) Q_strcat( filename, "_VERTEXCOLOR", sizeof(filename) ); |
|
// if( FOGTYPE ) Q_strcat( filename, "_FOGTYPE", sizeof(filename) ); |
|
if( ALPHATEST ) Q_strcat( filename, "_ALPHATEST", sizeof(filename) ); |
|
if( TRANSLUCENT ) Q_strcat( filename, "_TRANSLUCENT", sizeof(filename) ); |
|
if( COLORMODULATE ) Q_strcat( filename, "_COLORMODULATE", sizeof(filename) ); |
|
if( ALPHAMODULATE ) Q_strcat( filename, "_ALPHAMODULATE", sizeof(filename) ); |
|
|
|
if( BUMPMAP ) Q_strcat( filename, "_BUMPMAP", sizeof(filename) ); |
|
Q_strcat( filename, ".tga", sizeof(filename) ); |
|
ScreenShot( filename ); |
|
|
|
g_pProceduralMaterial->DecrementReferenceCount(); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Render a frame |
|
//----------------------------------------------------------------------------- |
|
|
|
void RenderFrame( void ) |
|
{ |
|
TestLightmappedGeneric_dx80(); |
|
} |
|
|
|
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hInstance, LPSTR pCommands, INT ) |
|
{ |
|
SpewOutputFunc( SpewFunc ); |
|
CommandLine()->CreateCmdLine( ::GetCommandLine() ); |
|
InitDefaultFileSystem(); |
|
|
|
if( !CommandLine()->ParmValue( "-targetdir" ) ) |
|
{ |
|
Error( "Must specify -targetdir on command line!\n" ); |
|
} |
|
|
|
struct _stat statbuf; |
|
if( 0 != _stat( CommandLine()->ParmValue( "-targetdir" ), &statbuf ) ) |
|
{ |
|
if( 0 != _mkdir( CommandLine()->ParmValue( "-targetdir" ) ) ) |
|
{ |
|
Error( "Couldn't create path %s\n", CommandLine()->ParmValue( "-targetdir" ) ); |
|
} |
|
} |
|
|
|
// Must add 'bin' to the path.... |
|
char* pPath = getenv("PATH"); |
|
|
|
// Use the .EXE name to determine the root directory |
|
char moduleName[ MAX_PATH ]; |
|
char szBuffer[ 4096 ]; |
|
if ( !GetModuleFileName( hInstance, moduleName, MAX_PATH ) ) |
|
{ |
|
MessageBox( 0, "Failed calling GetModuleFileName", "Launcher Error", MB_OK ); |
|
return 0; |
|
} |
|
|
|
// Get the root directory the .exe is in |
|
char* pRootDir = GetBaseDir( moduleName ); |
|
|
|
#ifdef DBGFLAG_ASSERT |
|
int len = |
|
#endif |
|
|
|
Q_snprintf( szBuffer, sizeof( szBuffer ), "PATH=%s;%s", pRootDir, pPath ); |
|
Assert( len < 4096 ); |
|
_putenv( szBuffer ); |
|
|
|
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); |
|
|
|
if (!Init( pCommands ) ) |
|
return false; |
|
|
|
/* |
|
bool done = false; |
|
while( !done ) |
|
{ |
|
done = Update(); |
|
} |
|
*/ |
|
RenderFrame(); |
|
Shutdown(); |
|
|
|
return 0; |
|
} |
|
|
|
|