📄 cgconverter.cpp
字号:
else if (TryVersion(CG_PROFILE_PS_2_X, acFilename, acEntry, aacArgs))
{
m_pkShader->AddProgram (Shader::DIRECTX,
cgGetProgramString(m_kProgram, CG_COMPILED_PROGRAM),
Shader::PS_2_X );
DbgPrintf( "\t***Warning: PS 2.X profiles may not work with "\
"every graphics card.\n" );
DbgPrintf( "\tDX-PS 2.X profile created\n");
}
else
{
DbgPrintf( "\t***Warning!!! Program will not work under DX.\n" );
}
cgDestroyProgram( m_kProgram );
}
DbgPrintf( "\n");
}
//----------------------------------------------------------------------------
CgConverter::~CgConverter ()
{
if ( cgIsContext(m_kContext) )
{
cgDestroyContext(m_kContext);
}
if ( cgIsProgram(m_kProgram) )
{
cgDestroyProgram(m_kProgram);
}
if ( m_pkShader )
delete m_pkShader;
if ( m_pkConsts )
delete m_pkConsts;
}
//----------------------------------------------------------------------------
void CgConverter::CreateShaderConstants ()
{
if ( m_pkConsts )
delete m_pkConsts;
m_pkConsts = new ShaderConstants();
RecurseProgramParameters(cgGetFirstParameter(m_kProgram, CG_PROGRAM));
DbgPrintf( "Total User/State Constants: %i\n",
m_pkConsts->GetNumConstants() );
}
//----------------------------------------------------------------------------
void CgConverter::RecurseProgramParameters(CGparameter kParam)
{
if (kParam == 0)
return;
int i, arraySize;
do
{
switch(cgGetParameterType(kParam))
{
case CG_STRUCT:
RecurseProgramParameters(cgGetFirstStructParameter(kParam));
break;
case CG_ARRAY:
arraySize = cgGetArraySize(kParam, 0);
for (i = 0; i < arraySize; ++i)
{
RecurseProgramParameters(cgGetArrayParameter(kParam, i));
}
break;
default:
// handle the single parameter
// sanity check
if (!cgIsParameter(kParam))
{
FatalError("Not a parameter.");
}
// make sure it is actually used in the program
if ( cgIsParameterReferenced(kParam) )
{
AddParam( kParam );
}
break;
}
} while((kParam = cgGetNextParameter(kParam))!= 0);
}
//----------------------------------------------------------------------------
void CgConverter::AddParam (CGparameter kParam)
{
CGresource kResource;
const char* acName = cgGetParameterName(kParam);
int iTemp, iTemp2, iRegister, iSize, iTypeOption;
StateConstantType iConstType = USER_DEFINED;
// We don't need to handle out parameters (at this point)
// DX and GL handle both of these automatically
if ( cgGetParameterDirection(kParam) == CG_OUT )
{
DbgPrintf( "\tOutput (%s), ignored\n", acName );
return;
}
switch (cgGetParameterVariability(kParam))
{
case CG_VARYING:
// update the
DbgPrintf( "\tVarying (%s), ", acName );
kResource = cgGetParameterBaseResource(kParam);
if ( kResource == CG_TEXCOORD0 )
{
iTemp = cgGetParameterResourceIndex(kParam);
iRegister = GetRegister(kParam);
m_aiTexCoordRegHint[iTemp] = iRegister;
DbgPrintf( "TEXCOORD%i (v%i)\n", iTemp, iRegister );
}
else if ( kResource == CG_POSITION0 )
{
iTemp = cgGetParameterResourceIndex(kParam);
// only position 0 is accepted in WML
if (iTemp)
{
FatalError( "May only use Position0 or Position.");
}
iRegister = GetRegister(kParam);
m_iVertexRegHint = iRegister;
DbgPrintf( "POSITION (v%i)\n", iRegister );
}
else if ( kResource == CG_NORMAL0 )
{
iTemp = cgGetParameterResourceIndex(kParam);
// only normal 0 is accepted in WML
if (iTemp)
{
FatalError( "May only use Normal0 or Normal.");
}
iRegister = GetRegister(kParam);
m_iNormalRegHint = iRegister;
DbgPrintf( "NORMAL (v%i)\n", iRegister );
}
else if ( kResource == CG_COLOR0 )
{
iTemp = cgGetParameterResourceIndex(kParam);
// only color 0 is accepted in WML
if (iTemp)
{
FatalError( "May only use Color0 or Color.");
}
iRegister = GetRegister(kParam);
m_iColorRegHint = iRegister;
DbgPrintf( "COLOR (v%i)\n", iRegister );
}
else
{
DbgPrintf( "ignored\n" );
}
break;
case CG_UNIFORM:
DbgPrintf( "\tUniform (%s), ", acName );
iRegister = cgGetParameterResourceIndex(kParam);
iSize = GetSize( kParam );
if (!iSize)
return;
if (!strncmp(acName, "Wml", 3))
{
MatchConstantName (acName, iConstType, iTypeOption);
// you must pick the correct type (float4 or float4x4) for
// state constants
if ( StateConstant::Size(iConstType) != iSize )
{
FatalError( "Wrong size for state constant." );
}
m_pkConsts->AddConstant( acName, iRegister,
StateConstant::Size(iConstType), iConstType,
iTypeOption);
DbgPrintf( "state constant (c%i)\n", iRegister );
}
else
{
iConstType = USER_DEFINED;
m_pkConsts->AddConstant( acName, iRegister,
iSize, iConstType, 0);
DbgPrintf( "user constant (c%i)\n", iRegister );
}
break;
case CG_CONSTANT:
DbgPrintf( "\tUniform (%s), ", acName );
iRegister = cgGetParameterResourceIndex(kParam);
iSize = GetSize( kParam );
if (!iSize)
return;
iConstType = NUMERICAL_CONSTANT;
m_pkConsts->AddConstant( acName, iRegister,
iSize, iConstType, 0, cgGetParameterValues(kParam,
CG_CONSTANT, &iTemp2));
DbgPrintf( "numerical constant (c%i) [", iRegister );
for( iTemp = 0; iTemp < 4*iSize-1; iTemp++ )
{
DbgPrintf( "%.2f, ", (float)(cgGetParameterValues(kParam,
CG_CONSTANT, &iTemp2)[iTemp]) );
}
DbgPrintf( "%.2f", (float)(cgGetParameterValues(kParam,
CG_CONSTANT, &iTemp2)[iTemp]) );
DbgPrintf( "]\n");
break;
default:
FatalError( "Unknown parameter type!\n" );
}
}
//----------------------------------------------------------------------------
void CgConverter::MatchConstantName (const char* acName,
StateConstantType& riType, int& riTypeOption)
{
int iTemp;
for (int i = 0; i < StateConstant::NumTypes(); i++)
{
if ( !strncmp(acName, StateConstant::Name(i),
strlen(StateConstant::Name(i))) )
{
riType = (StateConstantType)i;
switch( riType )
{
case RENDERER_MODVIEW:
case RENDERER_PROJ:
case RENDERER_MODVIEWPROJ:
case RENDERER_MOD:
iTemp = (int)strlen(StateConstant::Name(i));
if ( strlen(acName) == iTemp )
{
riTypeOption = (int)SC_NORMAL;
}
else if (!strcmp(&acName[iTemp], "InvTrans"))
{
riTypeOption = (int)SC_INVERSETRANSPOSE;
}
else if (!strcmp(&acName[iTemp], "Inv"))
{
riTypeOption = (int)SC_INVERSE;
}
else if (!strcmp(&acName[iTemp], "Trans"))
{
riTypeOption = (int)SC_TRANSPOSE;
}
else
{
FatalError( "Invalid Suffix on Matrix type.\n" );
}
break;
case LIGHT_POSITION:
case LIGHT_DIRECTION:
case LIGHT_AMBIENT:
case LIGHT_DIFFUSE:
case LIGHT_SPECULAR:
case LIGHT_SPOTCUTOFF:
case LIGHT_ATTENPARAMS:
if ( strlen(acName) == strlen(StateConstant::Name(i))+1 )
{
// lights have a single digit after them
// e.g. LIGHT_POSITION0 or LIGHT_AMBIENT7
riTypeOption = (int)acName[strlen(acName)-1]-(int)'0';
if ( ( riTypeOption < 0 ) || ( riTypeOption >=8 ) )
{
FatalError( "Illegal light num." );
}
}
else
{
FatalError( "Lights must have one digit"\
" in their name.\n" );
}
break;
default:
if ( strlen(acName) == strlen(StateConstant::Name(i)) )
{
riTypeOption = 0;
}
else
{
FatalError( "Invalid trailing characters "\
"on constant." );
}
break;
}
// if found one, don't check anymore
break;
}
}
// if none found
if ( i == StateConstant::NumTypes() )
{
// See list in StateConstant.{h, cpp} for valid constant names
FatalError( "Invalid state constant name." );
}
}
//----------------------------------------------------------------------------
int CgConverter::GetRegister (CGparameter kParam)
{
return cgD3D9ResourceToDeclUsage(cgGetParameterResource(kParam));
}
//----------------------------------------------------------------------------
bool CgConverter::TryVersion (CGprofile kProfile, const char* acFilename,
const char* acEntry, const char** aacArgs)
{
if ( cgIsProgram(m_kProgram) )
cgDestroyProgram(m_kProgram);
m_kProgram = cgCreateProgramFromFile(m_kContext, CG_SOURCE,
acFilename, kProfile, acEntry, aacArgs );
if (cgIsProgram(m_kProgram))
{
// Probably need to look for "// %i instructions" line
return true;
}
else
return false;
}
//----------------------------------------------------------------------------
void CgConverter::WriteObjectToFile (char* acFilename)
{
m_pkShader->Write( acFilename );
}
//----------------------------------------------------------------------------
void CgConverter::DbgPrintf (char* acFormat, ...)
{
if ( m_bQuiet )
return;
va_list kArgs;
va_start(kArgs, acFormat);
vprintf(acFormat,kArgs);
va_end(kArgs);
}
//----------------------------------------------------------------------------
void CgConverter::FatalError (const char* acMessage)
{
printf( "\n***ERROR: " );
printf( acMessage );
printf( "\n" );
exit(-1);
}
//----------------------------------------------------------------------------
int CgConverter::GetSize (CGparameter kParam)
{
CGtype kType = cgGetParameterType(kParam);
switch( kType )
{
case CG_FLOAT:
case CG_FLOAT2:
case CG_FLOAT3:
case CG_FLOAT4:
return 1;
case CG_FLOAT3x3:
return 3;
case CG_FLOAT4x4:
return 4;
case CG_SAMPLER1D:
case CG_SAMPLER2D:
case CG_SAMPLER3D:
case CG_SAMPLERRECT:
case CG_SAMPLERCUBE:
// types not handled by the converter, should be ignored
return 0;
break;
default:
FatalError( "Type not handled by WML (sorry)!\n" );
return 0;
break;
}
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -