deargui-vpl/ref/virtools/Samples/Behaviors/Shader/Sources/ShaderDescriptorCG.cpp

6529 lines
233 KiB
C++

/////////////////////////////////////////////////////
// ShaderDescriptorCG
/////////////////////////////////////////////////////
#include "stdafx.h"
#include "CKGL15Rasterizer.h"
#include "ShaderDescriptorCG.h"
#include "RCKShaderCG.h"
#include "CKGL15RasterizerContext.h"
#include "XNHashTable.h"
#include "ShaderManagerCG.h"
bool ParamMeaningCaching = true;
bool ParamMeaningLightCaching = true;
static volatile bool ForceCGSetParameter = false;
extern BOOL gRestoreConstantMode;
#define FourCC2String(a) (a)
#define SemanticEnumToFourCC(a) (a)
#define CKTEXTUREDESC VCKGL15Rasterizer::CKGLTextureDesc
#define DXDEVICE int
#define DXBASETEXTURE int
#define DXTEXTURE int
#ifdef _DEBUG
#ifndef GLCHECK
#define GLCHECK() { int Error; \
XASSERT( (Error = glGetError()) == GL_NO_ERROR); }
#endif
#else
#define GLCHECK()
#endif
#ifdef macintosh
static void *aglGetProcAddress(const char* pszProc)
{
OSStatus err = noErr;
const Str255 frameworkName = "\pOpenGL.framework";
FSRefParam fileRefParam;
FSRef fileRef;
CFURLRef bundleURLOpenGL;
memset(&fileRefParam, 0, sizeof(fileRefParam));
memset(&fileRef, 0, sizeof(fileRef));
fileRefParam.ioNamePtr = frameworkName;
fileRefParam.newRef = &fileRef;
// Frameworks directory/folder
err = FindFolder (kSystemDomain, kFrameworksFolderType, false,
&fileRefParam.ioVRefNum, &fileRefParam.ioDirID);
if (noErr != err) {
DebugStr ("\pCould not find frameworks folder");
return NULL;
}
err = PBMakeFSRefSync (&fileRefParam); // make FSRef for folder
if (noErr != err) {
DebugStr ("\pCould make FSref to frameworks folder");
return NULL;
}
// create URL to folder
bundleURLOpenGL = CFURLCreateFromFSRef (kCFAllocatorDefault,
&fileRef);
if (!bundleURLOpenGL) {
DebugStr ("\pCould create OpenGL Framework bundle URL");
return NULL;
}
// create ref to GL's bundle
CFBundleRef BundleRefOpenGL = CFBundleCreate (kCFAllocatorDefault,
bundleURLOpenGL);
if (!BundleRefOpenGL) {
DebugStr ("\pCould not create OpenGL Framework bundle");
return NULL;
}
CFRelease (bundleURLOpenGL); // release created bundle
// if the code was successfully loaded, look for our function.
if (!CFBundleLoadExecutable (BundleRefOpenGL))
{
DebugStr ("\pCould not load MachO executable");
return NULL;
}
return (void*)CFBundleGetFunctionPointerForName (BundleRefOpenGL,
CFStringCreateWithCStringNoCopy (NULL,
pszProc, CFStringGetSystemEncoding (), NULL));
}
#define TEXT(a) a
#define UINT unsigned int
#endif
namespace ShaderDescriptorCG {
// replicate from gl driver
static GLenum GLCmpFunc[9]= {GL_EQUAL, GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS};
// Utility function to get dimension of a matrix type in cg (for maya exporter : it links with an older version of cg that
// doesn't support cgGetTypeSizes)
void GetCGTypeSize(CGtype type, int *numRows, int *numCols)
{
*numRows = 1;
*numCols = 0; // for types that are not numeric
switch(type)
{
case CG_FLOAT: *numRows = 1; *numCols = 1; break;
case CG_FLOAT2: *numRows = 1; *numCols = 2; break;
case CG_FLOAT3: *numRows = 1; *numCols = 3; break;
case CG_FLOAT4: *numRows = 1; *numCols = 4; break;
case CG_FLOAT1x1: *numRows = 1; *numCols = 1; break;
case CG_FLOAT2x1: *numRows = 2; *numCols = 1; break;
case CG_FLOAT3x1: *numRows = 3; *numCols = 1; break;
case CG_FLOAT4x1: *numRows = 4; *numCols = 1; break;
//
case CG_FLOAT1x2: *numRows = 1; *numCols = 2; break;
case CG_FLOAT2x2: *numRows = 2; *numCols = 2; break;
case CG_FLOAT3x2: *numRows = 3; *numCols = 2; break;
case CG_FLOAT4x2: *numRows = 4; *numCols = 2; break;
//
case CG_FLOAT1x3: *numRows = 1; *numCols = 3; break;
case CG_FLOAT2x3: *numRows = 2; *numCols = 3; break;
case CG_FLOAT3x3: *numRows = 3; *numCols = 3; break;
case CG_FLOAT4x3: *numRows = 4; *numCols = 3; break;
//
case CG_FLOAT1x4: *numRows = 1; *numCols = 4; break;
case CG_FLOAT2x4: *numRows = 2; *numCols = 4; break;
case CG_FLOAT3x4: *numRows = 3; *numCols = 4; break;
case CG_FLOAT4x4: *numRows = 4; *numCols = 4; break;
//
case CG_INT: *numRows = 1; *numCols = 1; break;
case CG_INT2: *numRows = 1; *numCols = 2; break;
case CG_INT3: *numRows = 1; *numCols = 3; break;
case CG_INT4: *numRows = 1; *numCols = 4; break;
case CG_INT1x1: *numRows = 1; *numCols = 1; break;
case CG_INT2x1: *numRows = 2; *numCols = 1; break;
case CG_INT3x1: *numRows = 3; *numCols = 1; break;
case CG_INT4x1: *numRows = 4; *numCols = 1; break;
//
case CG_INT1x2: *numRows = 1; *numCols = 2; break;
case CG_INT2x2: *numRows = 2; *numCols = 2; break;
case CG_INT3x2: *numRows = 3; *numCols = 2; break;
case CG_INT4x2: *numRows = 4; *numCols = 2; break;
//
case CG_INT1x3: *numRows = 1; *numCols = 3; break;
case CG_INT2x3: *numRows = 2; *numCols = 3; break;
case CG_INT3x3: *numRows = 3; *numCols = 3; break;
case CG_INT4x3: *numRows = 4; *numCols = 3; break;
//
case CG_INT1x4: *numRows = 1; *numCols = 4; break;
case CG_INT2x4: *numRows = 2; *numCols = 4; break;
case CG_INT3x4: *numRows = 3; *numCols = 4; break;
case CG_INT4x4: *numRows = 4; *numCols = 4; break;
//
case CG_BOOL: *numRows = 1; *numCols = 1; break;
case CG_BOOL2: *numRows = 1; *numCols = 2; break;
case CG_BOOL3: *numRows = 1; *numCols = 3; break;
case CG_BOOL4: *numRows = 1; *numCols = 4; break;
case CG_BOOL1x1: *numRows = 1; *numCols = 1; break;
case CG_BOOL2x1: *numRows = 2; *numCols = 1; break;
case CG_BOOL3x1: *numRows = 3; *numCols = 1; break;
case CG_BOOL4x1: *numRows = 4; *numCols = 1; break;
//
case CG_BOOL1x2: *numRows = 1; *numCols = 2; break;
case CG_BOOL2x2: *numRows = 2; *numCols = 2; break;
case CG_BOOL3x2: *numRows = 3; *numCols = 2; break;
case CG_BOOL4x2: *numRows = 4; *numCols = 2; break;
//
case CG_BOOL1x3: *numRows = 1; *numCols = 3; break;
case CG_BOOL2x3: *numRows = 2; *numCols = 3; break;
case CG_BOOL3x3: *numRows = 3; *numCols = 3; break;
case CG_BOOL4x3: *numRows = 4; *numCols = 3; break;
//
case CG_BOOL1x4: *numRows = 1; *numCols = 4; break;
case CG_BOOL2x4: *numRows = 2; *numCols = 4; break;
case CG_BOOL3x4: *numRows = 3; *numCols = 4; break;
case CG_BOOL4x4: *numRows = 4; *numCols = 4; break;
//
case CG_HALF: *numRows = 1; *numCols = 1; break;
case CG_HALF2: *numRows = 1; *numCols = 2; break;
case CG_HALF3: *numRows = 1; *numCols = 3; break;
case CG_HALF4: *numRows = 1; *numCols = 4; break;
case CG_HALF1x1: *numRows = 1; *numCols = 1; break;
case CG_HALF2x1: *numRows = 2; *numCols = 1; break;
case CG_HALF3x1: *numRows = 3; *numCols = 1; break;
case CG_HALF4x1: *numRows = 4; *numCols = 1; break;
//
case CG_HALF1x2: *numRows = 1; *numCols = 2; break;
case CG_HALF2x2: *numRows = 2; *numCols = 2; break;
case CG_HALF3x2: *numRows = 3; *numCols = 2; break;
case CG_HALF4x2: *numRows = 4; *numCols = 2; break;
//
case CG_HALF1x3: *numRows = 1; *numCols = 3; break;
case CG_HALF2x3: *numRows = 2; *numCols = 3; break;
case CG_HALF3x3: *numRows = 3; *numCols = 3; break;
case CG_HALF4x3: *numRows = 4; *numCols = 3; break;
//
case CG_HALF1x4: *numRows = 1; *numCols = 4; break;
case CG_HALF2x4: *numRows = 2; *numCols = 4; break;
case CG_HALF3x4: *numRows = 3; *numCols = 4; break;
case CG_HALF4x4: *numRows = 4; *numCols = 4; break;
//
case CG_FIXED: *numRows = 1; *numCols = 1; break;
case CG_FIXED2: *numRows = 1; *numCols = 2; break;
case CG_FIXED3: *numRows = 1; *numCols = 3; break;
case CG_FIXED4: *numRows = 1; *numCols = 4; break;
case CG_FIXED1x1: *numRows = 1; *numCols = 1; break;
case CG_FIXED2x1: *numRows = 2; *numCols = 1; break;
case CG_FIXED3x1: *numRows = 3; *numCols = 1; break;
case CG_FIXED4x1: *numRows = 4; *numCols = 1; break;
//
case CG_FIXED1x2: *numRows = 1; *numCols = 2; break;
case CG_FIXED2x2: *numRows = 2; *numCols = 2; break;
case CG_FIXED3x2: *numRows = 3; *numCols = 2; break;
case CG_FIXED4x2: *numRows = 4; *numCols = 2; break;
//
case CG_FIXED1x3: *numRows = 1; *numCols = 3; break;
case CG_FIXED2x3: *numRows = 2; *numCols = 3; break;
case CG_FIXED3x3: *numRows = 3; *numCols = 3; break;
case CG_FIXED4x3: *numRows = 4; *numCols = 3; break;
//
case CG_FIXED1x4: *numRows = 1; *numCols = 4; break;
case CG_FIXED2x4: *numRows = 2; *numCols = 4; break;
case CG_FIXED3x4: *numRows = 3; *numCols = 4; break;
case CG_FIXED4x4: *numRows = 4; *numCols = 4; break;
}
}
/**************************************************************************/
/************************* Pre-Declarations *******************************/
/**************************************************************************/
void
Meaning::PostIntantiationCallBack( const MeaningInstantiatorInfo& iMII )
{
m_D3DHandle = iMII.h;
}
/***************************************************************************
_____ _ _
| ___| _ _ __ ___| |_(_) ___ _ __
| |_ | | | | '_ \ / __| __| |/ _ \| '_ \
| _|| |_| | | | | (__| |_| | (_) | | | |
|_| \__,_|_| |_|\___|\__|_|\___/|_| |_|
__ __ _
| \/ | ___ __ _ _ __ (_)_ __ __ _ ___
| |\/| |/ _ \/ _` | '_ \| | '_ \ / _` / __|
| | | | __/ (_| | | | | | | | | (_| \__ \
|_| |_|\___|\__,_|_| |_|_|_| |_|\__, |___/
|___/
***************************************************************************/
//--------------------------------------------------------------------------------
// Standard FctMeaning
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
Meaning*
FctMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
//--- Selectect the Appropriate FctMeaning
//... if annot something then inst = (FctMeaning*)Instantiate_MeaningCG( FctMeaningToExecute );
//--- Or return this basic fct meaning
FctMeaning* inst = new FctMeaning;
return inst;
}
//--------------------------------------------------------------------------
void
FctMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
}
//--------------------------------------------------------------------------
void
FctMeaning::PostIntantiationCallBack( const MeaningInstantiatorInfo& iMII )
{
Meaning::PostIntantiationCallBack( iMII );
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
m_FunctionDesc = iMII.functionDesc;
#endif
}
/***************************************************************************
____ __ __ _
| _ \ __ _ ___ ___ | \/ | ___ __ _ _ __ (_)_ __ __ _ ___
| |_) / _` / __/ __| | |\/| |/ _ \/ _` | '_ \| | '_ \ / _` / __|
| __/ (_| \__ \__ \ | | | | __/ (_| | | | | | | | | (_| \__ \
|_| \__,_|___/___/ |_| |_|\___|\__,_|_| |_|_|_| |_|\__, |___/
|___/
***************************************************************************/
//--------------------------------------------------------------------------------
// Standard PassMeaning
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
Meaning*
PassMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
//--- Selectect the Appropriate PassMeaning
//... if annot something then inst = (PassMeaning*)Instantiate_MeaningCG( PassMeaningToExecute );
//--- Or return this basic tech meaning
PassMeaning* inst = new PassMeaning;
return inst;
}
//--------------------------------------------------------------------------
void
PassMeaning::PostIntantiationCallBack( const MeaningInstantiatorInfo& iMII )
{
Meaning::PostIntantiationCallBack( iMII );
//--- Store Description
m_PassDesc = iMII.passDesc;
// //--- Retrieve the version of shader used
// XString desc;
//
////#ifdef XBOX1
//// DWORD VSVersion = 0x0101;
//// DWORD PSVersion = 0x0101;
////#else
// DWORD VSVersion = m_PassDesc.pVertexShaderFunction ? *(DWORD*)(m_PassDesc.pVertexShaderFunction) : 0;
// DWORD PSVersion = m_PassDesc.pPixelShaderFunction ? *(DWORD*)(m_PassDesc.pPixelShaderFunction) : 0;
////#endif
// if( VSVersion ){
//
// m_DescStr.Format("vs%d.%d", (VSVersion >> 8) & 0xFF, VSVersion & 0xFF);
//
//#if DIRECT3D_VERSION >= 0x0900
//
// //--- Retrieve needed shader input stream format
// D3DXSEMANTIC pVSSemantics[MAXD3DDECLLENGTH];
// UINT inSemanticsCount;
// HRESULT res = D3DXGetShaderInputSemantics( m_PassDesc.pVertexShaderFunction, pVSSemantics, &inSemanticsCount );
// for( UINT a=0 ; a<inSemanticsCount ; ++a ){
//
// D3DXSEMANTIC& inSemantic = pVSSemantics[a];
//
// CKShader* ckShader = iMII.shader->GetCKShader();
// XArray<CKShader::StreamParam>& inputStreamFormats = ckShader->GetInputStreamFormat();
// int b;
// const int biggerParamsCount = inputStreamFormats.Size();
// for( b=0 ; b<biggerParamsCount ; ++b ){
//
// CKShader::StreamParam& sp = inputStreamFormats[b];
// if( sp.usage == inSemantic.Usage &&
// sp.usageIndex == inSemantic.UsageIndex ){
// //... should check the size for Dx8 (if size bigger...)
// //... for Dx9 size does not matter
// break;
// }
// }
// //--- If input semantic wasn't used then add it
// if( b == biggerParamsCount ){
// CKShader::StreamParam sp = { inSemantic.Usage, inSemantic.UsageIndex, 0 };
// inputStreamFormats.PushBack( sp );
// }
// }
//#endif // DIRECT3D_VERSION>0x0900
// }
// if (PSVersion)
// {
// desc.Format("ps%d.%d", (PSVersion >> 8) & 0xFF, PSVersion & 0xFF);
// if( m_DescStr.Length() ) m_DescStr += ", ";
// m_DescStr += desc;
// }
}
//--------------------------------------------------------------------------
void
PassMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
}
/***************************************************************************
_____ _ __ __ _
|_ _|__ ___| |__ | \/ | ___ __ _ _ __ (_)_ __ __ _ ___
| |/ _ \/ __| '_ \ | |\/| |/ _ \/ _` | '_ \| | '_ \ / _` / __|
| | __/ (__| | | | | | | | __/ (_| | | | | | | | | (_| \__ \
|_|\___|\___|_| |_| |_| |_|\___|\__,_|_| |_|_|_| |_|\__, |___/
|___/
***************************************************************************/
//--------------------------------------------------------------------------------
// Standard TechMeaning
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
TechMeaning::TechMeaning() : m_MeshOps( MeshOp_None )
{
}
//--------------------------------------------------------------------------
TechMeaning::~TechMeaning()
{
//--- Parse all Pass Meanings
const int passCount = m_Passes.Size();
for( int passIndex=0 ; passIndex<passCount ; ++passIndex ){
delete m_Passes[passIndex];
}
m_Passes.Resize(0);
//--- Clear Hash Table
m_PassIndexFromName.Clear();
}
//--------------------------------------------------------------------------
Meaning*
TechMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
//--- Selectect the Appropriate TechMeaning
//... if annot something then inst = (TechMeaning*)Instantiate_MeaningCG( TechMeaningToExecute );
//--- Or return this basic tech meaning
TechMeaning* inst = new TechMeaning;
//--- Here are the Annotations we are interested in
bool annotNeedTangentSpace = false;
bool isAnnotNeedTangentSpaceUsed = false;
iMII.sdm->ExpectingAnnotation( Annot_NeedTangentSpace, AnnotType_Bool, &annotNeedTangentSpace,
&isAnnotNeedTangentSpaceUsed );
bool annotNeedColorAndNormals = false;
bool isAnnotNeedColorAndNormalsUsed = false;
iMII.sdm->ExpectingAnnotation( Annot_NeedColorAndNormal, AnnotType_Bool, &annotNeedColorAndNormals,
&isAnnotNeedColorAndNormalsUsed );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstTechniqueAnnotation(iMII.techDesc) );
//--- Be sure the user explicitly asked to set or remove TANGENT SPACE
if( isAnnotNeedTangentSpaceUsed ){
//--- User asked to build tangent
if( annotNeedTangentSpace == true ){
inst->m_MeshOps |= MeshOp_BuildTangentSpace;
}
//--- Otherwise user asked to build tangent
else {
//inst->m_MeshOps |= MeshOp_RemoveTangentSpace;
}
}
//--- Be sure the user explicitly asked to set or remove USE COLOR AND NORMAL
if( isAnnotNeedColorAndNormalsUsed ){
//--- User asked to build tangent
if( annotNeedColorAndNormals == true ){
inst->m_MeshOps |= MeshOp_SetUseColorAndNormal;
}
//--- Otherwise user asked to build tangent
else {
inst->m_MeshOps |= MeshOp_RemoveUseColorAndNormal;
}
}
return inst;
}
//--------------------------------------------------------------------------
void
TechMeaning::PostIntantiationCallBack( const MeaningInstantiatorInfo& iMII )
{
Meaning::PostIntantiationCallBack( iMII );
//--- Store Description
m_TechDesc = iMII.techDesc;
//--- Validate Technique
m_Validated = (cgIsTechniqueValidated(m_TechDesc) == CG_TRUE) ? true : false;
m_DescStr = m_Validated ? "Valid":"Invalid";
//--- Parse all Passes
MeaningInstantiatorInfo mii = iMII;
#pragma todo ("Check for technique validity before building the pass meanings")
CGpass pass = m_Validated ? cgGetFirstPass(m_TechDesc) : NULL;
unsigned int passIndex = 0;
while(pass)
{
mii.passDesc = pass;
//--- Generate Pass Meanings
PassMeaning* passMeaning = iMII.shader->BuildPassMeaning( mii );
if( passMeaning ){
//--- Pass Meaning
m_Passes.PushBack( passMeaning );
//--- Store meaning also in a hash to get it by name
m_PassIndexFromName.Insert(cgGetPassName(passMeaning->m_PassDesc), passIndex++ );
} else {
//... TODO: Print Message "Can't find meaning for pass"
}
pass = cgGetNextPass(pass);
}
}
//--------------------------------------------------------------------------
void
TechMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
//--- If user asked to build tangent space then set the BuildTangentSpace Flag to the mesh
if( m_MeshOps != MeshOp_None ){
CK3dEntity* ent = iMPI.ent;
if( ent ){
CKMesh* mesh = ent->GetCurrentMesh();
if( mesh ){
if( m_MeshOps & MeshOp_BuildTangentSpace ){
mesh->SetFlags( mesh->GetFlags() | VXMESH_GENTANSPACE );
} else if( m_MeshOps & MeshOp_RemoveTangentSpace ){
mesh->SetFlags( mesh->GetFlags() & ~VXMESH_GENTANSPACE );
}
if( m_MeshOps & MeshOp_SetUseColorAndNormal ){
mesh->SetFlags( mesh->GetFlags() | VXMESH_USECOLORANDNORMAL );
} else if( m_MeshOps & MeshOp_RemoveUseColorAndNormal ){
mesh->SetFlags( mesh->GetFlags() & ~VXMESH_USECOLORANDNORMAL );
}
}
}
}
//--- Parse all Pass Meanings
const int passCount = m_Passes.Size();
for( int passIndex=0 ; passIndex<passCount ; ++passIndex ){
m_Passes[passIndex]->ProcessCallBack( iMPI );
}
}
/***************************************************************************
____ __ __ _
| _ \ __ _ _ __ __ _ _ __ ___ | \/ | ___ __ _ _ __ (_)_ __ __ _ ___
| |_) / _` | '__/ _` | '_ ` _ \ | |\/| |/ _ \/ _` | '_ \| | '_ \ / _` / __|
| __/ (_| | | | (_| | | | | | | | | | | __/ (_| | | | | | | | | (_| \__ \
|_| \__,_|_| \__,_|_| |_| |_| |_| |_|\___|\__,_|_| |_|_|_| |_|\__, |___/
|___/
***************************************************************************/
//--------------------------------------------------------------------------
void
ParamMeaning::PostIntantiationCallBack( const MeaningInstantiatorInfo& iMII )
{
Meaning::PostIntantiationCallBack( iMII );
m_ParamDesc = iMII.paramDesc;
m_ExpositionType = ExpositionType_Automatic;
// size for matrixs
CGtype type = cgGetParameterType(m_ParamDesc);
if (type == CG_ARRAY)
{
type = cgGetArrayType(m_ParamDesc);
// count the number of element in the array
int dimCount = cgGetArrayDimension(m_ParamDesc);
m_ArrayElementCount = 1;
for (int d = 0; d < dimCount; ++d)
{
m_ArrayElementCount *= cgGetArraySize(m_ParamDesc, d);
}
}
#ifdef _DEBUG
m_ParameterName = cgGetParameterName(m_ParamDesc);
#endif
GetCGTypeSize(type, &m_NumRows, &m_NumCols);
XASSERT(m_NumRows >= 0 && m_NumRows <= 4);
XASSERT(m_NumCols >= 0 && m_NumCols <= 4);
VxVector4 defaultValue(0.f, 0.f, 0.f, 1.f);
if (m_ArrayElementCount == 1 && m_NumRows == 1) // vectors & scalars ...
{
// precache for SetValueByCastingVectorParam
#ifndef STATIC_FOR_MAYA
CGtype baseType = cgGetTypeBase(type);
#else
CGtype baseType;
XASSERT(0);
#endif
switch(baseType)
{
case CG_FLOAT:
case CG_INT:
case CG_FIXED:
case CG_BOOL:
//numCopiedValues = cgGetParameterValuefr(m_ParamDesc, XMax(1, m_NumCols), &defaultValue.x);
cgGetParameterValuefr(m_ParamDesc, m_NumCols, &defaultValue.x);
break;
}
}
m_ValueCache.Resize(ShaderManagerCG::GetCGEffectTechniqueCount(iMII.fx));
for (int k = 0; k < m_ValueCache.Size(); ++k)
{
m_ValueCache[k] = defaultValue;
}
}
//--------------------------------------------------------------------------
void
ParamMeaning::SetValueByCastingVectorParam(
const MeaningProcessingInfo& iMPI, int iInputSize, const void* value )
{
//#if DIRECT3D_VERSION<0x0900
// if( g_D3DTypesSizes[m_ParamDesc.Type] <= (UINT)iInputSize )
// {
// iMPI.fx->SetVector( m_D3DHandle, (D3DXVECTOR4*) value);
// } else {
// VxVector4 tmpVect(0,0,0,1);
// memcpy( &tmpVect, value, iInputSize );
//
// iMPI.fx->SetVector( m_D3DHandle, (D3DXVECTOR4*)&tmpVect);
// }
//#else
// if( m_ParamDesc.Bytes <= iInputSize )
// {
// iMPI.fx->SetVector( m_D3DHandle, (D3DXVECTOR4*) value);
// } else {
// VxVector4 tmpVect(0,0,0,1);
// memcpy( &tmpVect, value, iInputSize );
//
// iMPI.fx->SetValue( m_D3DHandle, value, m_ParamDesc.Bytes );
//
// // Note: we don't use the line beneath, because the following example
// // wouldn't work as expected ( emi[0] should receive EMISSIVE )
// // iMPI.fx->SetVector( m_D3DHandle, (D3DXVECTOR4*)&tmpVect);
// //
// // float4 emi[5] : EMISSIVE;
// }
#pragma todo("SetValueByCastingVectorParam : verifier le type de l'inputValue")
int size = cgGetParameterColumns( m_ParamDesc ) * sizeof(float);
VxVector4 tmpVect(0,0,0,1);
if(size > iInputSize) {
memcpy( &tmpVect, value, iInputSize );
value = &tmpVect.x;
}
if ((!ParamMeaningCaching) ||
m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter ||
memcmp(value, &m_ValueCache[iMPI.techniqueIndex], iInputSize) != 0) // value different than cache ?
{
memcpy(&m_ValueCache[iMPI.techniqueIndex], value, iInputSize); // update cache value and call cg
WrapCGSetParameter4fv(iMPI, (const float*)value);
TouchDependentRenderStates(iMPI);
}
//#endif
}
//--------------------------------------------------------------------------
void ParamMeaning::DisableProgramConstantsWrapping(int techIndex)
{
TechniqueConstantSetupInfo &tech = m_PerTechniquePerPassConstantSetup[techIndex];
tech.m_ForceUseCGSetParameter = true;
tech.m_PerPassConstantSetup.Clear();
}
//--------------------------------------------------------------------------
const char *ParamMeaning::ParseCGConstantDeclarationLine(const char *currPos,
int arrayElementIndex,
EConstantParseResult &constantParseResult,
int &firstConstantIndex,
int &matrixRowCount)
{
const char* parameterName = cgGetParameterName(m_ParamDesc);
XASSERT(parameterName);
currPos = strstr(currPos, "#var");
if (!currPos)
{
constantParseResult = ConstantParseResult_NotFound;
return NULL;
}
// Here we got something like
// #var float4x4 worldViewProj : WORLDVIEWPROJECTION : c[91], 4 : -1 : 1
// Look for next line
const char* endLine = strstr(currPos, "\n");
if (!endLine)
{
constantParseResult = ConstantParseResult_NotFound;
return NULL;
}
const char* nextLine = endLine + 1;
const char* firstColon = strstr(currPos, ":");
if (!firstColon)
{
constantParseResult = ConstantParseResult_NotFound;
return nextLine;
}
// Look for the variable name in that line
const char *varName = strstr(currPos, parameterName);
if (!varName || varName > firstColon)
{
constantParseResult = ConstantParseResult_NotFound;
return nextLine;
}
// match whole word ?
if (*(varName - 1) != ' ')
{
constantParseResult = ConstantParseResult_NotFound;
return nextLine;
}
// If it is an array, parse the indices
CGtype type = cgGetParameterType(m_ParamDesc);
if (type == CG_ARRAY)
{
currPos = varName + strlen(parameterName);
int dimCount = cgGetArrayDimension(m_ParamDesc);
char subscriptLookup[128];
int tmpArrayElem = arrayElementIndex;
XArray<int> subscript;
for (int dimIndex = 0; dimIndex < dimCount; ++dimIndex)
{
int dimSize = cgGetArraySize(m_ParamDesc, dimCount - 1 - dimIndex);
int subIndex = tmpArrayElem % dimSize;
tmpArrayElem /= dimSize;
subscript.PushFront(subIndex);
}
for (int dimIndex = 0; dimIndex < dimCount; ++dimIndex)
{
sprintf(subscriptLookup, "[%u]", subscript[dimIndex]);
if (strstr(currPos, subscriptLookup) != currPos)
{
constantParseResult = ConstantParseResult_NotFound;
return nextLine;
}
currPos += strlen(subscriptLookup);
}
}
else
{
XASSERT(arrayElementIndex == 0); // not an array
// match whole word ?
const char *nextSpace = strstr(varName, " ");
if (!nextSpace || (nextSpace - varName) != strlen(parameterName))
{
constantParseResult = ConstantParseResult_NotFound;
return nextLine;
}
}
// Is this parameter used ? must be 1 at the end of line
while (endLine != currPos && !isdigit(*endLine))
{
-- endLine;
}
if (*endLine != '1')
{
constantParseResult = ConstantParseResult_NotUsed;
return nextLine;
}
int colonLeft = 3;
// skip last 3 ':'
while (endLine != currPos && colonLeft)
{
-- endLine;
if (*endLine == ':')
{
-- colonLeft;
}
}
if (colonLeft)
{
XASSERT(0);
constantParseResult = ConstantParseResult_NotFound;
return nextLine;
}
//
int colIndex, rowCount;
if (sscanf(endLine, ": c[%d], %d", &colIndex, &rowCount) == 2)
{
// got it !!
firstConstantIndex = colIndex;
matrixRowCount = rowCount <= 0 ? 1 : rowCount;
constantParseResult = ConstantParseResult_Used;
return nextLine;
}
else if (sscanf(endLine, ": c[%d] : %d", &colIndex, &rowCount) == 2)
{
// got it !!
firstConstantIndex = colIndex;
matrixRowCount = rowCount <= 0 ? 1 : rowCount;
constantParseResult = ConstantParseResult_Used;
return nextLine;
}
constantParseResult = ConstantParseResult_NotFound;
return nextLine;
}
//--------------------------------------------------------------------------
void ParamMeaning::InitConstantSetupInfo(int techniqueIndex,
int passIndex,
const char* programString[NUMBER_OF_CG_DOMAIN],
ShaderConstantStore* cstStore[NUMBER_OF_CG_DOMAIN]
)
{
XASSERT(techniqueIndex >= 0);
XASSERT(passIndex >= 0);
//
PerPassConstantSetup &techniqueCstSetup = m_PerTechniquePerPassConstantSetup[techniqueIndex].m_PerPassConstantSetup;
if (passIndex >= techniqueCstSetup.Size())
{
techniqueCstSetup.Resize(passIndex + 1);
}
const char* parameterName = cgGetParameterName(m_ParamDesc);
XASSERT(parameterName);
ConstantSetupInfo &cstSetup = techniqueCstSetup[passIndex];
for (int domain = 0; domain < NUMBER_OF_CG_DOMAIN; ++domain)
{
cstSetup.m_ConstantIndex[domain] = -1;
cstSetup.m_RowCount[domain] = 0;
if (!programString[domain]) continue; // domain not used
if (!cstStore[domain])
{
// We don't have code to set constants for that profile ... must fallback on cgSetParameter ...
m_PerTechniquePerPassConstantSetup[techniqueIndex].m_PerPassConstantSetup.Clear();
m_PerTechniquePerPassConstantSetup[techniqueIndex].m_ForceUseCGSetParameter = true;
return;
}
CGtype type = cgGetParameterType(m_ParamDesc);
// special case for FP30 : constant are set by their name
if (strstr(programString[domain], "#profile fp30\n"))
{
// These profiles directly work with the name
// Is this constant used in that program ?
XString searchString0;
XString searchString1;
XString searchString2;
searchString0.Format("DECLARE %s;", parameterName);
searchString1.Format("DECLARE %s$", parameterName);
searchString2.Format("DECLARE %s ", parameterName);
if (strstr(programString[domain], searchString0.CStr()) ||
strstr(programString[domain], searchString1.CStr()) ||
strstr(programString[domain], searchString2.CStr())
)
{
// Exists in current program
int dimCount = 0;
if (type == CG_ARRAY)
{
type = cgGetArrayType(m_ParamDesc);
dimCount = cgGetArrayDimension(m_ParamDesc);
}
int colCount;
int rowCount;
GetCGTypeSize(type, &rowCount, &colCount);
int firstConstantIndex;
// NB : for array, it seems that all entries are created in the FP30 profiles, even for unused ones
for (int arrayElem = 0; arrayElem < m_ArrayElementCount; ++ arrayElem)
{
for (int row = 0; row < rowCount; ++row)
{
XString name;
//else scalar ...
int tmpArrayElem = arrayElem;
for (int dimIndex = 0; dimIndex < dimCount; ++ dimIndex)
{
int dimSize = cgGetArraySize(m_ParamDesc, dimCount - 1 - dimIndex);
int subIndex = tmpArrayElem % dimSize;
tmpArrayElem /= dimSize;
char subscript[128];
sprintf(subscript, "$%u", subIndex);
name = subscript + name;
}
#ifndef STATIC_FOR_MAYA
if (cgGetTypeClass(type) == CG_PARAMETERCLASS_MATRIX) // is it an array ?
{
char buf[128];
sprintf(buf, "$%u", row);
name += buf;
}
#else
XASSERT(0);
#endif
name = parameterName + name;
int index = cstStore[domain]->AddNamedConstant(name.CStr());
if (row == 0 && arrayElem == 0)
{
firstConstantIndex = index;
}
}
}
cstSetup.m_ConstantIndex[domain] = firstConstantIndex;
if (cgGetParameterType(m_ParamDesc) == CG_ARRAY)
{
XArray<int> &arrayCellToCst = cstSetup.m_ArrayCellToProgramConstant[domain];
arrayCellToCst.Resize(m_ArrayElementCount);
for (int k = 0; k < m_ArrayElementCount; ++k)
{
arrayCellToCst[k] = firstConstantIndex + k * rowCount;
}
}
cstSetup.m_RowCount[domain] = rowCount;
}
}
else
{
EConstantParseResult constantParseResult = ConstantParseResult_Unknown;
const char *currPos = programString[domain];
int cstIndex = -1;
int rowCount = -1;
// Search the first line containing the constant declaration
while (currPos)
{
currPos = ParseCGConstantDeclarationLine(currPos,
0,
constantParseResult,
cstIndex,
rowCount);
XASSERT((CKDWORD) constantParseResult < ConstantParseResult_Count);
if (constantParseResult != ConstantParseResult_NotFound)
{
break;
}
}
if (type == CG_ARRAY && (constantParseResult != ConstantParseResult_NotFound))
{
int arrayElemCount = cgGetArrayTotalSize(m_ParamDesc);
cstSetup.m_RowCount[domain] = rowCount;
cstSetup.m_ArrayCellToProgramConstant[domain].Resize(arrayElemCount);
int arrayElemIndex = 0;
for (;;)
{
if (cstIndex != -1 && cstSetup.m_ConstantIndex[domain] == -1)
{
// Put first index for info (may not be that of the first array element if
// it is unused in the shader.
cstSetup.m_ConstantIndex[domain] = cstIndex;
cstSetup.m_RowCount[domain] = rowCount;
}
if (cstIndex == -1)
{
XASSERT(constantParseResult == ConstantParseResult_NotUsed);
}
cstSetup.m_ArrayCellToProgramConstant[domain][arrayElemIndex] = cstIndex;
++ arrayElemIndex;
if (!currPos || arrayElemIndex == arrayElemCount) break;
// Parse next line
cstIndex = -1;
currPos = ParseCGConstantDeclarationLine(currPos,
arrayElemIndex,
constantParseResult,
cstIndex,
rowCount);
if (cstSetup.m_RowCount[domain] != -1 && rowCount != -1)
{
XASSERT(cstSetup.m_RowCount[domain] == rowCount); // expect constant row count (cg do not skip unused
// parts of matrixs), only unused array entries
}
XASSERT((CKDWORD) constantParseResult < ConstantParseResult_Count);
}
XASSERT(arrayElemIndex == arrayElemCount);
if (cstSetup.m_ConstantIndex[domain] == -1)
{
cstSetup.m_ArrayCellToProgramConstant[domain].Clear();
}
else
{
XASSERT(cstSetup.m_RowCount[domain] >= 1); // we found entry in the array -> row count should be at least 1
}
}
else
{
if (cstIndex != -1)
{
cstSetup.m_ConstantIndex[domain] = cstIndex;
XASSERT(rowCount != -1);
cstSetup.m_RowCount[domain] = rowCount;
}
}
}
}
}
//--------------------------------------------------------------------------
int ParamMeaning::GetMaxCstIndex(int techIndex, int passIndex, CGdomain domain) const
{
XASSERT(domain < CG_FIRST_DOMAIN + NUMBER_OF_CG_DOMAIN);
if (m_PerTechniquePerPassConstantSetup[techIndex].m_ForceUseCGSetParameter)
{
return -1;
}
const ConstantSetupInfo &csi = m_PerTechniquePerPassConstantSetup[techIndex].m_PerPassConstantSetup[passIndex];
int arrayElemCount = XMax(1, csi.m_ArrayCellToProgramConstant[domain - CG_FIRST_DOMAIN].Size());
return csi.m_ConstantIndex[domain - CG_FIRST_DOMAIN] == -1 ? -1 : (csi.m_ConstantIndex[domain - CG_FIRST_DOMAIN] + arrayElemCount * csi.m_RowCount[domain - CG_FIRST_DOMAIN]);
}
//--------------------------------------------------------------------------
bool ParamMeaning::HasDependentStates(int techIndex) const
{
const TechniqueConstantSetupInfo &tech = m_PerTechniquePerPassConstantSetup[techIndex];
return tech.m_HasDependentSamplerStates || (tech.m_DependentRenderStates.Size() != 0);
}
//--------------------------------------------------------------------------
bool ParamMeaning::HasDependentProgramConstants(int techIndex) const
{
const TechniqueConstantSetupInfo &tech = m_PerTechniquePerPassConstantSetup[techIndex];
int passCount = tech.m_PerPassConstantSetup.Size();
for (int pass = 0; pass < passCount; ++pass)
{
const ConstantSetupInfo &pcs = tech.m_PerPassConstantSetup[pass];
for (int domain = 0; domain < NUMBER_OF_CG_DOMAIN; ++domain)
{
if (pcs.m_ConstantIndex[domain] != -1) return true;
}
}
return false;
}
//--------------------------------------------------------------------------
inline void ParamMeaning::SetConstants(const ConstantSetupInfo &cstSetupInf, RCKShaderCG::PassStateCache &pass, const float *srcFloats, int rowCount, int colCount, int numElement)
{
XASSERT(numElement > 0);
if (cstSetupInf.m_ConstantIndex < 0) return;
XASSERT(colCount > 0 && colCount <= 4);
XASSERT(rowCount > 0 && rowCount <= 4);
for (int domain = 0; domain < NUMBER_OF_CG_DOMAIN; ++domain)
{
if (cstSetupInf.m_ConstantIndex[domain] != -1)
{
int destRowCount = cstSetupInf.m_RowCount[domain];
int srcRowCount = XMin(rowCount, destRowCount);
ShaderConstantStore *ccs = pass.m_ConstantStore[domain];
XASSERT(pass.m_ConstantStore[domain]);
int baseIndex = cstSetupInf.m_ConstantIndex[domain];
float expandedValue[4] = { 0.f, 0.f, 0.f, 0.f };
static const float defaultValue[] = { 0.f, 0.f, 0.f, 0.f };
const XArray<int> &arrayCellToCst = cstSetupInf.m_ArrayCellToProgramConstant[domain];
if (arrayCellToCst.Size() != 0)
{
XASSERT(arrayCellToCst.Size() == m_ArrayElementCount);
int destNumElem = XMin(numElement, m_ArrayElementCount);
for (int elemIndex = 0; elemIndex < destNumElem; ++elemIndex)
{
if (arrayCellToCst[elemIndex] != -1)
{
const float *currRow = srcFloats;
int row;
for (row = 0; row < srcRowCount; ++row)
{
for (int col = 0; col < colCount; ++col)
{
expandedValue[col] = currRow[col];
}
ccs->SetConstant(arrayCellToCst[elemIndex] + row, expandedValue);
currRow += rowCount;
}
// clear remaining rows
for (; row < destRowCount; ++row)
{
ccs->SetConstant(arrayCellToCst[elemIndex] + row, defaultValue);
}
}
srcFloats += rowCount * colCount;
}
}
else
{
// Not an array
int row;
for (row = 0; row < srcRowCount; ++row)
{
for (int col = 0; col < colCount; ++col)
{
expandedValue[col] = *srcFloats++;
}
ccs->SetConstant(baseIndex + row, expandedValue);
}
// clear remaining rows
for (; row < destRowCount; ++row)
{
ccs->SetConstant(baseIndex + row, defaultValue);
}
}
}
}
}
//--------------------------------------------------------------------------
void ParamMeaning::SetConstants(const MeaningProcessingInfo& iMPI,
const float *srcFloats,
int rowCount,
int colCount,
int numElement)
{
int techIndex = iMPI.techniqueIndex;
XASSERT(techIndex < m_PerTechniquePerPassConstantSetup.Size());
PerPassConstantSetup &perPassCstSetup = m_PerTechniquePerPassConstantSetup[techIndex].m_PerPassConstantSetup;
RCKShaderCG* parentShader = (RCKShaderCG*) iMPI.shader->GetCKShader();
if (iMPI.isPerPassMeanings)
{
// Set only for current pass
int currentPassIndex = parentShader->GetCurrentPassIndex();
XASSERT(currentPassIndex < perPassCstSetup.Size());
RCKShaderCG::PassStateCache &psc = *iMPI.techStateCache->m_Passes[currentPassIndex];
const ConstantSetupInfo &cstSetupInf = m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_PerPassConstantSetup[currentPassIndex];
SetConstants(cstSetupInf, psc, srcFloats, rowCount, colCount, numElement);
}
else
{
// set the constant for all passes at once
int passCount = iMPI.techStateCache->m_Passes.Size();
for (int passIndex = 0; passIndex < passCount; ++passIndex)
{
RCKShaderCG::PassStateCache &psc = *iMPI.techStateCache->m_Passes[passIndex];
const ConstantSetupInfo &cstSetupInf = m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_PerPassConstantSetup[passIndex];
SetConstants(cstSetupInf, psc, srcFloats, rowCount, colCount, numElement);
}
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameter1i(const MeaningProcessingInfo& iMPI, int value)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgSetParameter1i(m_ParamDesc, value); // immediate mode : setup both the value into cg and the program constants
}
else
{
float fValue = (float) value;
SetConstants(iMPI, &fValue, 1, 1, 1);
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameter1f(const MeaningProcessingInfo& iMPI, float value)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgGLSetParameter1f(m_ParamDesc, value); // immediate mode : setup both the value into cg and the program constants
}
else
{
SetConstants(iMPI, &value, 1, 1, 1);
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameter2fv(const MeaningProcessingInfo& iMPI, const float *value)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgGLSetParameter2fv(m_ParamDesc, value); // immediate mode : setup both the value into cg and the program constants
}
else
{
SetConstants(iMPI, value, 1, 2, 1);
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameter3fv(const MeaningProcessingInfo& iMPI, const float *value)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgGLSetParameter3fv(m_ParamDesc, value); // immediate mode : setup both the value into cg and the program constants
}
else
{
SetConstants(iMPI, value, 1, 3, 1);
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameter4fv(const MeaningProcessingInfo& iMPI, const float *value)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgGLSetParameter4fv(m_ParamDesc, value); // immediate mode : setup both the value into cg and the program constants
}
else
{
SetConstants(iMPI, value, 1, 4, 1);
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameterArray1f(const MeaningProcessingInfo& iMPI, const float *values, int elemCount)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgGLSetParameterArray1f(m_ParamDesc, 0, elemCount, values); // immediate mode : setup both the value into cg and the program constants
}
else
{
SetConstants(iMPI, values, 1, 1, elemCount);
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameterArray2f(const MeaningProcessingInfo& iMPI, const float *values, int elemCount)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgGLSetParameterArray2f(m_ParamDesc, 0, elemCount, values); // immediate mode : setup both the value into cg and the program constants
}
else
{
SetConstants(iMPI, values, 1, 2, elemCount);
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameterArray3f(const MeaningProcessingInfo& iMPI, const float *values, int elemCount)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgGLSetParameterArray3f(m_ParamDesc, 0, elemCount, values); // immediate mode : setup both the value into cg and the program constants
}
else
{
SetConstants(iMPI, values, 1, 3, elemCount);
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetParameterArray4f(const MeaningProcessingInfo& iMPI, const float *values, int elemCount)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
cgGLSetParameterArray4f(m_ParamDesc, 0, elemCount, values); // immediate mode : setup both the value into cg and the program constants
}
else
{
SetConstants(iMPI, values, 1, 4, elemCount);
}
}
static volatile void DumpProgConstants(const MeaningProcessingInfo& iMPI, GLuint prog)
{
/*
VCKGL15Rasterizer::CKGLRasterizerContext *ogRC = (VCKGL15Rasterizer::CKGLRasterizerContext *) iMPI.rc->GetRasterizerContext();
ogRC->m_glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog);
OutputDebugString("===================================\n");
for (int k = 0; k < 10; ++k)
{
float cst[4] = { 0.f, 0.f, 0.f, 0.f };
ogRC->m_glGetProgramLocalParameterfvARB(GL_VERTEX_PROGRAM_ARB, k, cst);
//
char buf[512];
sprintf(buf, "(%f, %f, %f, %f) \n", cst[0], cst[1], cst[2], cst[3]);
OutputDebugString(buf);
}
*/
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetStateMatrixParameter(const MeaningProcessingInfo& iMPI, CGGLenum matrix, CGGLenum transform)
{
//static volatile bool dumpCst = false;
XASSERT(matrix != CG_GL_TEXTURE_MATRIX); // not implemented ! (and not used anyway ...)
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
/*if (dumpCst)
{
DumpProgConstants(iMPI, iMPI.techStateCache->m_Passes[0]->m_ConstantStore[0]->GetGLProgramID());
}*/
cgGLSetStateMatrixParameter(m_ParamDesc, matrix, transform);
/*if (dumpCst)
{
DumpProgConstants(iMPI, iMPI.techStateCache->m_Passes[0]->m_ConstantStore[0]->GetGLProgramID());
}*/
}
else
{
VxMatrix mat;
VxMatrix mat2;
VxMatrix tmp;
VxMatrix *finalMat;
VCKGL15Rasterizer::CKGLRasterizerContext *rst = (VCKGL15Rasterizer::CKGLRasterizerContext *) iMPI.rc->GetRasterizerContext();
switch(matrix)
{
case CG_GL_MODELVIEW_MATRIX:
mat = rst->m_GLModelViewMatrix;
break;
case CG_GL_PROJECTION_MATRIX:
mat = rst->m_GLProjectionMatrix;
break;
case CG_GL_TEXTURE_MATRIX:
XASSERT(0);
break;
case CG_GL_MODELVIEW_PROJECTION_MATRIX:
Vx3DMultiplyMatrix4(mat, rst->m_GLProjectionMatrix, rst->m_GLModelViewMatrix);
break;
default:
XASSERT(0);
break;
}
switch(transform)
{
case CG_GL_MATRIX_IDENTITY:
{
Vx3DTransposeMatrix(mat2, mat);
finalMat = &mat2;
}
break;
case CG_GL_MATRIX_TRANSPOSE:
finalMat = &mat;
break;
case CG_GL_MATRIX_INVERSE:
if (matrix == CG_GL_PROJECTION_MATRIX || matrix == CG_GL_MODELVIEW_PROJECTION_MATRIX)
{
Vx3DInverseMatrix44(mat2, mat);
}
else
{
Vx3DInverseMatrix(mat2, mat);
}
Vx3DTransposeMatrix(mat, mat2);
finalMat = &mat;
break;
case CG_GL_MATRIX_INVERSE_TRANSPOSE:
if (matrix == CG_GL_PROJECTION_MATRIX || matrix == CG_GL_MODELVIEW_PROJECTION_MATRIX)
{
Vx3DInverseMatrix44(mat2, mat);
}
else
{
Vx3DInverseMatrix(mat2, mat);
}
//Vx3DTransposeMatrix(mat, mat2);
finalMat = &mat2;
break;
default:
XASSERT(0);
break;
}
SetConstants(iMPI, (const float *) finalMat, 4, 4, 1);
/*if (dumpCst)
{
iMPI.techStateCache->m_Passes[0]->m_ConstantStore[0]->Flush(iMPI.rc->GetRasterizerContext());
DumpProgConstants(iMPI, iMPI.techStateCache->m_Passes[0]->m_ConstantStore[0]->GetGLProgramID());
}*/
}
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetMatrixParameter(const MeaningProcessingInfo& iMPI, const VxMatrix &value)
{
if (m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter || ForceCGSetParameter)
{
// Nicov : When addressing Mantis bug [0001143]: the commented code below should be the way to go.
// Unfortunately, most of our CG shaders have been written to work with column-major for some 'meanings' matrix
// instead of row-major (1 float4 constant per row) matrix as requested by cg (as a workaround to bad oriented matrix set by the meanings code)...
// In CG, matrix are transposed compared to the D3D HLSL matrix.
// This is why in CG we do mul(wvp, pos) instead of mul(pos, wvp)
// All the previous matrix setting code that relied on cgSetMatrixParameterfr ('r' for row major, now WrapCGSetMatrixParameter)
// has inverse transposition (as opposed to code that uses (now WrapCGSetMatrixParameterArray)...)
//
// As such, this patch only fix the case when one tries to set a 4x4 matrix into something smaller
// into cg, such as a 3x3 matrix, because else we should rewrote most existing shader, so for safety
// let as it is now ... (fixing the bug *breaks* most existing cg shaders :( )
//
// As a result, the following 'meanings' have correct transposition (reversed with D3D order) :
// ============================================================================================
// Bones
// TBones
// WorldViewProjection
// WorldViewProjectionInverse
// WorldViewProjectionTranspose
// WorldViewProjectionInverseTranspose
// Projection
// ProjectionTranspose
// ProjectionInverse
// ProjectionInverseTranspose
// WorldView
// WorldViewTranspose
// WorldViewInverse
// WorldViewInverseTranspose
//
// The following 'meanings' have bad transposition (same than D3D order) :
// =======================================================================
//
// World
// WorldTranspose
// WorldInverse
// WorldInverseTranspose
// View
// ViewTranspose
// ViewInverse
// ViewInverseTranspose
// ViewProjection
// ViewProjectionInverse
// ViewProjectionTranspose
// ViewProjectionInverseTranspose
// ObjectMatrix
// Exposed Matrixs
/*
if (m_NumRows == 4 && m_NumCols == 4)
{
// transpose for column-major
VxMatrix transposedMat;
Vx3DTransposeMatrix(transposedMat, srcMatrix);
cgSetMatrixParameterfr(m_ParamDesc,(const float*) &transposedMat);
}
else
{
if (m_NumRows > 0 && m_NumCols > 0)
{
float croppedMatrix[16];
float* dest = croppedMatrix;
const float* src = (const float*) &srcMatrix;
for (int row = 0; row < m_NumRows; ++row)
{
for (int col = 0; col < m_NumCols; ++col)
{
*dest++ = *(src + row + 4 * col); // transpose for column-major
}
}
cgSetMatrixParameterfr(m_ParamDesc, croppedMatrix);
}
}
*/
if (m_NumRows == 4 && m_NumCols == 4)
{
// no cropping is necessary
cgSetMatrixParameterfr(m_ParamDesc,(const float*) &value);
}
else
{
// must crop to dest
float croppedMatrix[16];
float* dest = croppedMatrix;
const float* src = (const float*) &value;
for (int row = 0; row < m_NumRows; ++row)
{
for (int col = 0; col < m_NumCols; ++col)
{
*dest++ = src[col];
}
src += 4;
}
cgSetMatrixParameterfr(m_ParamDesc, croppedMatrix);
}
TouchDependentRenderStates(iMPI);
}
else
{
#ifdef _DEBUG
TechniqueConstantSetupInfo &tech = m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex];
XASSERT(tech.m_DependentRenderStates.Size() == 0);
#endif
// expect row major ordering in memory
SetConstants(iMPI, (const float *) &value, 4, 4, 1);
}
GLCHECK();
}
//--------------------------------------------------------------------------
void ParamMeaning::WrapCGSetMatrixParameterArray(const MeaningProcessingInfo& iMPI, const VxMatrix *srcMatrix, int matrixCount, bool transpose)
{
// Can we set the constant ourselves ?
if (!m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter)
{
if (transpose)
{
// TODO : alloc space on the stack ...
VxScratch scratch;
scratch.Check(sizeof(VxMatrix) * matrixCount);
VxMatrix* dest = (VxMatrix*) scratch.Mem();
const VxMatrix* src = srcMatrix;
const VxMatrix* end = srcMatrix + matrixCount;
while (src != end)
{
Vx3DTransposeMatrix(*dest, *src);
++ src;
++ dest;
}
SetConstants(iMPI, (const float *) scratch.Mem(), 4, 4, matrixCount);
}
else
{
SetConstants(iMPI, (const float *) srcMatrix, 4, 4, matrixCount);
}
}
else
{
// Fallback path using cgGLSetMatrixParameter (with possible cropping)
const VxMatrix *endMatrix = srcMatrix + matrixCount;
//
const CKDWORD MaxFloatCount = 256 * 4 * 4;
float boneMatrixs[MaxFloatCount];
VxScratch scratch;
//
float *cgMatrixs;
CKDWORD floatCount = m_NumRows * m_NumCols * matrixCount;
if (floatCount <= MaxFloatCount)
{
cgMatrixs = boneMatrixs;
}
else
{
scratch.Check(sizeof(float) * floatCount);
cgMatrixs = (float *) scratch.Mem();
}
//
float *dest = cgMatrixs;
if (transpose)
{
VxMatrix transposedMatrix;
while (srcMatrix < endMatrix)
{
Vx3DTransposeMatrix(transposedMatrix, *srcMatrix);
for (int rowIndex = 0; rowIndex < m_NumRows; ++rowIndex)
{
// TODO : get rid of the memcpy ...
memcpy(dest, &transposedMatrix[rowIndex], sizeof(float) * m_NumCols);
dest += m_NumCols;
}
++ srcMatrix;
}
}
else
{
while (srcMatrix < endMatrix)
{
for (int rowIndex = 0; rowIndex < m_NumRows; ++rowIndex)
{
// TODO : get rid of the memcpy ...
memcpy(dest, &(*srcMatrix)[rowIndex], sizeof(float) * m_NumCols);
dest += m_NumCols;
}
++ srcMatrix;
}
}
//
cgGLSetMatrixParameterArrayfr(m_ParamDesc, 0, matrixCount, cgMatrixs);
}
GLCHECK();
}
//--------------------------------------------------------------------------
void
ParamMeaning::SetValueByMatrix( const MeaningProcessingInfo& iMPI, const VxMatrix& iMatrix )
{
//#if DIRECT3D_VERSION<0x0900
// D3DXMATRIX tmp;
// D3DXMatrixTranspose(&tmp,(D3DXMATRIX*) (const void*) iMatrix);
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &tmp);
//#else
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) (const void*) iMatrix);
//#endif
#ifdef _DEBUG
CGtype pBaseType = cgGetParameterBaseType( m_ParamDesc );
XASSERT(pBaseType == CG_FLOAT);
#endif
WrapCGSetMatrixParameter(iMPI, iMatrix);
}
void
ParamMeaning::SetValueByTranposingMatrix( const MeaningProcessingInfo& iMPI, const VxMatrix& iMatrix )
{
//#if DIRECT3D_VERSION<0x0900
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) (const void*) iMatrix);
//#else
VxMatrix transposeMatrix;
Vx3DTransposeMatrix( transposeMatrix, iMatrix );
#ifdef _DEBUG
CGtype pBaseType = cgGetParameterBaseType( m_ParamDesc );
XASSERT(pBaseType == CG_FLOAT);
#endif
WrapCGSetMatrixParameter(iMPI, transposeMatrix);
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &transposeMatrix);
//#endif
}
//--------------------------------------------------------------------------
void
ParamMeaning::SetValueByInversingMatrix( const MeaningProcessingInfo& iMPI, const VxMatrix& iMatrix )
{
VxMatrix inverseMatrix;
Vx3DInverseMatrix( inverseMatrix, iMatrix );
//#if DIRECT3D_VERSION<0x0900
// D3DXMATRIX tmp;
// D3DXMatrixTranspose(&tmp,(D3DXMATRIX*) (const void*) iMPI.rc->GetWorldTransformationMatrix());
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &tmp);
//#else
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &inverseMatrix);
//#endif
#ifdef _DEBUG
CGtype pBaseType = cgGetParameterBaseType( m_ParamDesc );
XASSERT(pBaseType == CG_FLOAT);
#endif
WrapCGSetMatrixParameter(iMPI, inverseMatrix);
}
//--------------------------------------------------------------------------
void
ParamMeaning::SetValueByInversingMatrix44( const MeaningProcessingInfo& iMPI, const VxMatrix& iMatrix )
{
VxMatrix inverseMatrix;
Vx3DInverseMatrix44( inverseMatrix, iMatrix );
//#if DIRECT3D_VERSION<0x0900
// D3DXMATRIX tmp;
// D3DXMatrixTranspose(&tmp,(D3DXMATRIX*) (const void*) iMPI.rc->GetWorldTransformationMatrix());
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &tmp);
//#else
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &inverseMatrix);
//#endif
#ifdef _DEBUG
CGtype pBaseType = cgGetParameterBaseType( m_ParamDesc );
XASSERT(pBaseType == CG_FLOAT);
#endif
WrapCGSetMatrixParameter(iMPI, inverseMatrix);
}
//--------------------------------------------------------------------------
void
ParamMeaning::SetValueByInverseTransposingMatrix( const MeaningProcessingInfo& iMPI, const VxMatrix& iMatrix )
{
VxMatrix inverseMatrix;
Vx3DInverseMatrix( inverseMatrix, iMatrix );
//#if DIRECT3D_VERSION<0x0900
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &inverseMatrix);
//#else
// VxMatrix inverseTransposeMatrix;
// Vx3DTransposeMatrix( inverseTransposeMatrix, inverseMatrix );
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &inverseTransposeMatrix);
//#endif
#ifdef _DEBUG
CGtype pBaseType = cgGetParameterBaseType( m_ParamDesc );
XASSERT(pBaseType == CG_FLOAT);
#endif
VxMatrix inverseTransposeMatrix;
Vx3DTransposeMatrix( inverseTransposeMatrix, inverseMatrix );
WrapCGSetMatrixParameter(iMPI, inverseTransposeMatrix);
}
//--------------------------------------------------------------------------
void
ParamMeaning::SetValueByInverseTransposingMatrix44( const MeaningProcessingInfo& iMPI, const VxMatrix& iMatrix )
{
VxMatrix inverseMatrix;
Vx3DInverseMatrix44( inverseMatrix, iMatrix );
//#if DIRECT3D_VERSION<0x0900
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &inverseMatrix);
//#else
// VxMatrix inverseTransposeMatrix;
// Vx3DTransposeMatrix( inverseTransposeMatrix, inverseMatrix );
// iMPI.fx->SetMatrix( m_D3DHandle, (D3DXMATRIX*) &inverseTransposeMatrix);
//#endif
#ifdef _DEBUG
CGtype pBaseType = cgGetParameterBaseType( m_ParamDesc );
XASSERT(pBaseType == CG_FLOAT);
#endif
VxMatrix inverseTransposeMatrix;
Vx3DTransposeMatrix( inverseTransposeMatrix, inverseMatrix );
WrapCGSetMatrixParameter(iMPI, inverseTransposeMatrix);
}
//--------------------------------------------------------------------------
void
ParamMeaning::SetValueFromCKTexture( const MeaningProcessingInfo& iMPI, CKTexture* iTex )
{
DXBASETEXTURE Tex = 0;
if( iTex ){
iTex->EnsureVideoMemory( iMPI.rc );
CKTEXTUREDESC* texDesc = (CKTEXTUREDESC*)
iMPI.rc->GetRasterizerContext()->GetTextureData( iTex->GetRstTextureIndex() );
if( texDesc ) Tex = texDesc->GLTextureIndex;
}
//HRESULT hr = iMPI.fx->SetTexture( m_D3DHandle, Tex );
//assert( SUCCEEDED(hr) );
// cgGLSetTextureParameter(m_ParamDesc,Tex);
// cgSetSamplerState(m_ParamDesc);
// cgGLSetupSampler(m_ParamDesc,Tex);
//--- Set the PreviousTexture variable to point to this texture
//iMPI.shader->GetManager()->m_PreviousTextureParam = m_D3DHandle;
}
class ExposedFloatSliderParamMeaning;
//--------------------------------------------------------------------------------
// Exposed Float Slider
//--------------------------------------------------------------------------------
class ExposedFloatSliderParamMeaning : public ExposedFloatParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ExposedFloatSliderParamMeaning );
void CopyDefaultValueFromShaderToParamCB( const MeaningProcessingInfo& iMPI )
{
VxVector* paramPtr = (VxVector*)iMPI.param->GetWriteDataPtr();
//iMPI.fx->GetFloat( m_D3DHandle, &paramPtr->x);
cgGLGetParameter1f(m_ParamDesc,&paramPtr->x);
paramPtr->y = m_UIMin;
paramPtr->z = m_UIMax;
};
float m_UIMin;
float m_UIMax;
};
//--------------------------------------------------------------------------------
// Exposed Float
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
Meaning*
ExposedFloatParamMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
ExposedFloatParamMeaning* inst = NULL;
//--- Here are the Annotations we are interested in
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
float annotUIMin = EPSILON;
float annotUIMax = EPSILON;
iMII.sdm->ExpectingAnnotation( Annot_UIMin, AnnotType_Float, &annotUIMin );
iMII.sdm->ExpectingAnnotation( Annot_UIMax, AnnotType_Float, &annotUIMax );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
//--- UIMin and UIMax ?
if( annotUIMin!=EPSILON && annotUIMax!=EPSILON ){
inst = (ExposedFloatSliderParamMeaning*)Instantiate_MeaningCG( ExposedFloatSliderParamMeaning, iMII );
inst->m_Guid = CKPGUID_FLOATSLIDER;
((ExposedFloatSliderParamMeaning*)inst)->m_UIMin = annotUIMin;
((ExposedFloatSliderParamMeaning*)inst)->m_UIMax = annotUIMax;
} else
#endif // DIRECT3D_VERSION>=0x0900
{
inst = new ExposedFloatParamMeaning;
inst->m_Guid = CKPGUID_FLOAT;
}
return inst;
}
//--------------------------------------------------------------------------
void ExposedFloatParamMeaning::PostIntantiationCallBack(const MeaningInstantiatorInfo& iMII)
{
ExposedParamMeaning::PostIntantiationCallBack(iMII);
m_ValueCache.Resize(ShaderManagerCG::GetCGEffectTechniqueCount(iMII.fx));
}
//--------------------------------------------------------------------------
void
ExposedFloatParamMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
//iMPI.fx->SetFloat( m_D3DHandle, *(float*)iMPI.param->GetReadDataPtr());
float newValue = *(float*)iMPI.param->GetReadDataPtr();
if ((!ParamMeaningCaching) ||
m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter ||
newValue != m_ValueCache[iMPI.techniqueIndex])
{
m_ValueCache[iMPI.techniqueIndex] = newValue;
WrapCGSetParameter1f(iMPI, newValue);
TouchDependentRenderStates(iMPI);
}
}
//--------------------------------------------------------------------------
void
ExposedFloatParamMeaning::CopyDefaultValueFromShaderToParamCB( const MeaningProcessingInfo& iMPI )
{
//iMPI.fx->GetFloat( m_D3DHandle, (float*)iMPI.param->GetWriteDataPtr());
cgGLGetParameter1f(m_ParamDesc, (float*)iMPI.param->GetWriteDataPtr());
XASSERT(ShaderManagerCG::GetCGEffectTechniqueCount(iMPI.fx) == m_ValueCache.Size());
for (int k = 0; k < m_ValueCache.Size(); ++k)
{
m_ValueCache[k] = *(float*)iMPI.param->GetWriteDataPtr();
}
};
//--------------------------------------------------------------------------------
// Exposed Dword
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
Meaning*
ExposedDwordParamMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
ExposedDwordParamMeaning* inst = NULL;
inst = new ExposedDwordParamMeaning;
inst->m_Guid = CKPGUID_INT;
return inst;
}
//--------------------------------------------------------------------------
void ExposedDwordParamMeaning::PostIntantiationCallBack(const MeaningInstantiatorInfo& iMII)
{
ExposedParamMeaning::PostIntantiationCallBack(iMII);
m_ValueCache.Resize(ShaderManagerCG::GetCGEffectTechniqueCount(iMII.fx));
}
//--------------------------------------------------------------------------
void
ExposedDwordParamMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
// iMPI.fx->SetInt( m_D3DHandle, *(int*)iMPI.param->GetReadDataPtr());
int value = *(int*)iMPI.param->GetReadDataPtr();
if ((!ParamMeaningCaching) ||
value != m_ValueCache[iMPI.techniqueIndex])
{
m_ValueCache[iMPI.techniqueIndex] = value;
WrapCGSetParameter1i(iMPI, value);
TouchDependentRenderStates(iMPI);
}
}
//--------------------------------------------------------------------------
void
ExposedDwordParamMeaning::CopyDefaultValueFromShaderToParamCB( const MeaningProcessingInfo& iMPI )
{
XASSERT(!iMPI.techStateCache);
// iMPI.fx->GetInt( m_D3DHandle, (int*)iMPI.param->GetWriteDataPtr());
cgGetParameterValueic(m_ParamDesc, 1, (int*)iMPI.param->GetWriteDataPtr());
XASSERT(ShaderManagerCG::GetCGEffectTechniqueCount(iMPI.fx) == m_ValueCache.Size());
for (int k = 0; k < m_ValueCache.Size(); ++k)
{
m_ValueCache[k] = *(int*)iMPI.param->GetWriteDataPtr();
}
};
//--------------------------------------------------------------------------------
// Exposed Standard Params (To Derived)
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
void
ExposedParamMeaning::PostIntantiationCallBack( const MeaningInstantiatorInfo& iMII )
{
ParamMeaning::PostIntantiationCallBack( iMII );
m_ExpositionType = ExpositionType_Exposed;
}
//--------------------------------------------------------------------------
ExposedParamMeaning::~ExposedParamMeaning()
{
}
//--------------------------------------------------------------------------
void ExposedParamMeaning::CopyDefaultValueFromShaderToParamCB( const MeaningProcessingInfo& iMPI )
{
//--- By default do this, but obviously it's better to define a
///// real derived method for each kind of exposed parameters
if( !( iMPI.param->GetGUID() == CKPGUID_3DENTITY
|| iMPI.param->GetGUID() == CKPGUID_TEXTURE
|| iMPI.param->GetGUID() == CKPGUID_DATAARRAY ) ){
//#if DIRECT3D_VERSION<0x0900
int dataSize = iMPI.param->GetDataSize();
switch(dataSize){
case 4:
cgGetParameterValueic(m_ParamDesc, 1, (int*)iMPI.param->GetWriteDataPtr());
//iMPI.fx->GetInt( m_D3DHandle, (DWORD*) iMPI.param->GetWriteDataPtr());
break;
case 8:
cgGLGetParameter2f(m_ParamDesc, (float*)iMPI.param->GetWriteDataPtr());
break;
case 12:
cgGLGetParameter3f(m_ParamDesc, (float*)iMPI.param->GetWriteDataPtr());
case 16:
cgGLGetParameter4f(m_ParamDesc, (float*)iMPI.param->GetWriteDataPtr());
// iMPI.fx->GetVector( m_D3DHandle, (D3DXVECTOR4*) iMPI.param->GetWriteDataPtr());
break;
case 64:
cgGetMatrixParameterfr(m_ParamDesc,(float*)iMPI.param->GetWriteDataPtr());
// iMPI.fx->GetMatrix( m_D3DHandle, (D3DXMATRIX*) iMPI.param->GetWriteDataPtr());
break;
default:
XASSERT(0);
break;
}
//#else
if( iMPI.param->GetGUID() == CKPGUID_STRING ){
const char *tmp;
//iMPI.fx->GetString( m_D3DHandle, &tmp );
tmp = cgGetStringParameterValue(m_ParamDesc);
iMPI.param->SetStringValue( (char*)tmp );
}
// else {
// iMPI.fx->GetValue( m_D3DHandle, iMPI.param->GetWriteDataPtr(), iMPI.param->GetDataSize() );
// const double *cgGetParameterValues(CGparameter param, CGenum value_type, int *nvalues);
// }
//#endif
}
}
//--------------------------------------------------------------------------
static const CKGUID columnMatchingGuid[] = {
CKGUID(),
CKPGUID_FLOAT,
CKPGUID_2DVECTOR,
CKPGUID_VECTOR,
CKPGUID_COLOR,
};
//--------------------------------------------------------------------------
//#if DIRECT3D_VERSION<0x0900
//Meaning*
//ExposedParamMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII ){
//
// const D3DXPARAMETER_DESC& desc = iMII.paramDesc;
//
// ExposedParamMeaning* inst = NULL;
//
// switch( desc.Type )
// {
// case D3DXPT_DWORD:
// inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedDwordParamMeaning, iMII );
// break;
// case D3DXPT_FLOAT:
// inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedFloatParamMeaning, iMII );
// break;
// case D3DXPT_VECTOR:
// inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedXDVectorParamMeaning, iMII );
// inst->m_Guid = CKPGUID_VECTOR4;
// break;
// case D3DXPT_MATRIX:
// inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedMatrixParamMeaning, iMII );
// break;
// case D3DXPT_TEXTURE:
// inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedTextureParamMeaning, iMII );
// break;
// }
//
// return inst;
//}
//#else
Meaning*
ExposedParamMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII ){
// const D3DXPARAMETER_DESC& desc = iMII.paramDesc;
CGparameterclass pClassType = cgGetParameterClass( iMII.paramDesc );
CGtype pBaseType = cgGetParameterBaseType( iMII.paramDesc );
CGtype pType = cgGetParameterType( iMII.paramDesc );
int RowSize = cgGetParameterRows( iMII.paramDesc );
int ColSize = cgGetParameterColumns( iMII.paramDesc );
ExposedParamMeaning* inst = NULL;
// static CKGUID typemap[] =
// {
// CKGUID(), //D3DXPT_VOID,
// CKPGUID_BOOL, //D3DXPT_BOOL,
// CKPGUID_INT, //D3DXPT_INT,
// CKPGUID_FLOAT, //D3DXPT_FLOAT,
// CKPGUID_STRING, //D3DXPT_STRING,
// CKPGUID_TEXTURE,//D3DXPT_TEXTURE,
// CKPGUID_TEXTURE,//D3DXPT_TEXTURE1D,
// CKPGUID_TEXTURE,//D3DXPT_TEXTURE2D,
// CKPGUID_TEXTURE,//D3DXPT_TEXTURE3D,
// CKPGUID_TEXTURE,//D3DXPT_TEXTURECUBE,
// CKGUID(), //D3DXPT_SAMPLER,
// CKGUID(), //D3DXPT_SAMPLER1D,
// CKGUID(), //D3DXPT_SAMPLER2D,
// CKGUID(), //D3DXPT_SAMPLER3D,
// CKGUID(), //D3DXPT_SAMPLERCUBE,
// CKGUID(), //D3DXPT_PIXELSHADER,
// CKGUID(), //D3DXPT_VERTEXSHADER,
// CKGUID(), //D3DXPT_PIXELFRAGMENT,
// CKGUID() //D3DXPT_VERTEXFRAGMENT,
// };
switch( pClassType )//desc.Class
{
case CG_PARAMETERCLASS_OBJECT:
if( pBaseType == CG_TEXTURE ) {
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedTextureParamMeaning, iMII );
} else{
XASSERT(0);
}
break;
case CG_PARAMETERCLASS_SAMPLER:
// if( pBaseType == CG_TEXTURE ){
// inst = (ExposedParamMeaning*)Instantiate_MeaningCG( NonExposedSamplerParamMeaning, iMII );
// } else{
XASSERT(0);
// }
break;
case CG_PARAMETERCLASS_SCALAR:
if( pBaseType == CG_FLOAT || pBaseType == CG_HALF){
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedFloatParamMeaning, iMII );
} else if( pBaseType == CG_INT){
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedDwordParamMeaning, iMII );
if( inst ) inst->m_Guid = CKPGUID_INT;
} else if( pBaseType == CG_BOOL){
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedDwordParamMeaning, iMII );
if( inst ) inst->m_Guid = CKPGUID_BOOL;
} else{
XASSERT(0);
}
break;
case CG_PARAMETERCLASS_MATRIX:
if (pBaseType == CG_FLOAT || pBaseType == CG_HALF){
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedMatrixParamMeaning, iMII );
}
else{
XASSERT(0);
}
break;
case CG_PARAMETERCLASS_VECTOR:
if(pBaseType == CG_FLOAT || pBaseType == CG_HALF) {
switch( ColSize )
{
case 2:
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( Exposed2DVectorParamMeaning, iMII );
break;
default:
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedXDVectorParamMeaning, iMII );
break;
}
}
break;
case CG_PARAMETERCLASS_ARRAY:
if( pBaseType == CG_FLOAT || pBaseType == CG_HALF ) {
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedArrayParamMeaning, iMII );
inst->m_Guid = CKPGUID_DATAARRAY;
if(RowSize > 1) { //Matrix
((ExposedArrayParamMeaning*)inst)->m_Guid2 = CKPGUID_MATRIX;
}
else { //vector
XASSERT(ColSize<=4);
((ExposedArrayParamMeaning*)inst)->m_Guid2 = columnMatchingGuid[ ColSize ];
//if 4 floats, we choose by default color but it could be Vector4D, let's check annotation
if(ColSize==4)
{
XString annotType;
iMII.sdm->ExpectingAnnotation( Annot_Type, AnnotType_String, &annotType );
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
if((annotType.Length())&&(iMII.sdm->GetAnnotStrValueIndexFromString( annotType )==AnnotStr_Vector))
((ExposedArrayParamMeaning*)inst)->m_Guid2 = CKPGUID_VECTOR4;
}
}
}
else if(ColSize == 1) { //scalar
if(pBaseType == CG_INT){
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedArrayParamMeaning, iMII );
inst->m_Guid = CKPGUID_DATAARRAY;
((ExposedArrayParamMeaning*)inst)->m_Guid2 = CKPGUID_INT;//typemap[desc.Type];
}
else if(pBaseType == CG_BOOL) {
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedArrayParamMeaning, iMII );
inst->m_Guid = CKPGUID_DATAARRAY;
((ExposedArrayParamMeaning*)inst)->m_Guid2 = CKPGUID_BOOL;//typemap[desc.Type];
}
else if(pBaseType == CG_TEXTURE) {
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedArrayParamMeaning, iMII );
inst->m_Guid = CKPGUID_DATAARRAY;
((ExposedArrayParamMeaning*)inst)->m_Guid2 = CKPGUID_TEXTURE;//typemap[desc.Type];
}
else if(pBaseType == CG_STRING) {
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedArrayParamMeaning, iMII );
inst->m_Guid = CKPGUID_DATAARRAY;
((ExposedArrayParamMeaning*)inst)->m_Guid2 = CKPGUID_STRING;//typemap[desc.Type];
}
else{
XASSERT(0);
inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedArrayParamMeaning, iMII );
inst->m_Guid = CKPGUID_DATAARRAY;
((ExposedArrayParamMeaning*)inst)->m_Guid2 = CKGUID();//typemap[desc.Type];
}
}
break;
default:
XASSERT(0);
break;
}
if( !inst ) return NULL;
return inst;
}
//#endif
//--------------------------------------------------------------------------------
// Exposed Vector Param (To Derived)
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
CLASSIC_INSTANTIATOR_DEFINITION_CG( ExposedVectorizableParamMeaning );
void
ExposedVectorizableParamMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
int inputSize = iMPI.param->GetDataSize();
SetValueByCastingVectorParam( iMPI, inputSize, iMPI.param->GetReadDataPtr() );
}
//--------------------------------------------------------------------------------
// TexelSize
//--------------------------------------------------------------------------------
class ParamMeaning_TexelSize : public ParamMeaning {
public:
ParamMeaning_TexelSize() : m_TexIdPtr( NULL ),m_TexId(0),m_TexelSize(0.f,0.f){}
static Meaning* MeaningInstantiator( const MeaningInstantiatorInfo& iMII ){
//--- Here are the Annotations we are interested in
XString annotName;
iMII.sdm->ExpectingAnnotation( Annot_Name, AnnotType_String, &annotName );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
ParamMeaning_TexelSize* inst = new ParamMeaning_TexelSize;
if( annotName.Length() )
{
//--- Can be assimilated to a sampler to be liked with a texture
samplerRef spr;
spr.TexIdPtrPtr = &(inst->m_TexIdPtr);
spr.TexName = annotName.CStr();
iMII.shader->m_Samplers.PushBack(spr);
}
else {
#pragma todo ("TexelSize : change the error message")
XString strErrors = "TexelSize need to specified texture. <string Name=\"TexName\";>";
iMII.sdm->GetShaderManager()->m_Output.PushBack( strErrors );
}
return inst;
}
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
//--- Check that texture param exists
if( m_TexIdPtr )
{
if (*m_TexIdPtr != m_TexId) { // Current texture as been changed, need update.
//--- Bind OpenGL texture
m_TexId = *m_TexIdPtr;
GLenum err = glGetError(); // flush a potential non catch OGL error
XASSERT(err == GL_NO_ERROR);
GLenum targets[3] = {GL_TEXTURE_2D,GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_CUBE_MAP};
int i;
for (i = 0 ; i < 3 ; i++) {
glBindTexture(targets[i], m_TexId);
if (glGetError() == GL_NO_ERROR)
break;
XASSERT(i<2); //if i>2 and geGetError return an error, assert
}
if(targets[i] == GL_TEXTURE_RECTANGLE_ARB)
m_TexelSize.Set( 1.f, 1.f );
else {
//--- Get texture desc
GLint width;
GLint height;
glGetTexLevelParameteriv(targets[i],0,GL_TEXTURE_WIDTH,(GLint*)&width);
glGetTexLevelParameteriv(targets[i],0,GL_TEXTURE_HEIGHT,(GLint*)&height);
if (width && height)
//--- Compute Texel Size from Texture Width and Height
m_TexelSize.Set( 1.0f/width, 1.0f/height );
else
m_TexelSize.Set( 0.f, 0.f );
}
}
}
else {
//--- Initialize texelSize to 0, that way if there's no valid texture,
///// texelSize won't be undefined (can also be used to test texture validity)
m_TexelSize.Set( 0.f, 0.f );
}
GLCHECK();
//--- Put Texel Size inside given parameter (the one with the texelsize semantic)
SetValueByCastingVectorParam( iMPI, sizeof(Vx2DVector), &m_TexelSize );
}
GLuint* m_TexIdPtr;
GLuint m_TexId;
Vx2DVector m_TexelSize;
};
//--------------------------------------------------------------------------------
// TexureSize
//--------------------------------------------------------------------------------
class ParamMeaning_TextureSize : public ParamMeaning {
public:
ParamMeaning_TextureSize() : m_TexIdPtr( NULL ),m_TexId(0),m_TextureSize(0.f,0.f){}
static Meaning* MeaningInstantiator( const MeaningInstantiatorInfo& iMII ){
//--- Here are the Annotations we are interested in
XString annotName;
iMII.sdm->ExpectingAnnotation( Annot_Name, AnnotType_String, &annotName );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
ParamMeaning_TextureSize* inst = new ParamMeaning_TextureSize;
if( annotName.Length() )
{
//--- Can be assimilated to a sampler to be liked with a texture
samplerRef spr;
spr.TexIdPtrPtr = &(inst->m_TexIdPtr);
spr.TexName = annotName.CStr();
iMII.shader->m_Samplers.PushBack(spr);
}
else {
XString strErrors = "TexureSize need to specified texture. <string Name=\"TexName\";>";
iMII.sdm->GetShaderManager()->m_Output.PushBack( strErrors );
}
return inst;
}
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
//--- Check that texture param exists
if( m_TexIdPtr )
{
if (*m_TexIdPtr != m_TexId) { // Current texture as been changed, need update.
//--- Bind OpenGL texture
m_TexId = *m_TexIdPtr;
GLenum err = glGetError(); // flush a potential non catch OGL error
XASSERT(err == GL_NO_ERROR);
GLenum targets[3] = {GL_TEXTURE_2D,GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_CUBE_MAP};
int i;
for (i = 0 ; i < 3 ; i++) {
glBindTexture(targets[i], m_TexId);
if (glGetError() == GL_NO_ERROR)
break;
XASSERT(i<2); //if i>2 and geGetError return an error, assert
}
//--- Get texture desc
GLint width;
GLint height;
glGetTexLevelParameteriv(targets[i],0,GL_TEXTURE_WIDTH,(GLint*)&width);
glGetTexLevelParameteriv(targets[i],0,GL_TEXTURE_HEIGHT,(GLint*)&height);
if (width && height)
//--- Set Texture Size from Texture Width and Height
m_TextureSize.Set( (int)width, (int)height );
else
m_TextureSize.Set( 0.f, 0.f );
}
}
else {
//--- Initialize textureSize to 0, that way if there's no valid texture,
///// textureSize won't be undefined (can also be used to test texture validity)
m_TextureSize.Set( 0.f, 0.f );
}
GLCHECK();
//--- Put Texture Size inside given parameter (the one with the texureSize semantic)
SetValueByCastingVectorParam( iMPI, sizeof(Vx2DVector), &m_TextureSize );
}
GLuint* m_TexIdPtr;
GLuint m_TexId;
Vx2DVector m_TextureSize;
};
//--------------------------------------------------------------------------------
// Exposed 2DVector Param (To Derived)
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
//#if DIRECT3D_VERSION>=0x0900
Meaning*
Exposed2DVectorParamMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
//--- Here are the Annotations we are interested in
bool annotIsTexelSize = false;
iMII.sdm->ExpectingAnnotation( Annot_IsTexelSize, AnnotType_Bool, &annotIsTexelSize );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
//--- IsTexelSize = true ?
if( annotIsTexelSize == true ){
ParamMeaning * inst = (ParamMeaning*)Instantiate_MeaningCG( ParamMeaning_TexelSize, iMII );
return inst;
}
//--- Otherwise
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedVectorizableParamMeaning, iMII );
inst->m_Guid = CKPGUID_2DVECTOR;
return inst;
}
//--------------------------------------------------------------------------------
// Object's Position Param
//--------------------------------------------------------------------------------
class ExposedParamMeaning_ObjectPos : public ExposedParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ExposedParamMeaning_ObjectPos );
ExposedParamMeaning_ObjectPos() :
m_ReferentialEnum( AnnotStr_Unknown ){}
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
CK3dEntity* ent = (CK3dEntity*)iMPI.param->GetValueObject(FALSE);
if( !ent ) return;
VxVector objPos;
//--- Get referential in which to retrieve light information
CK3dEntity* referential = (m_ReferentialEnum == AnnotStr_Local)? iMPI.ent:NULL;
ent->GetPosition( &objPos, referential );
// NOTE: we should be able to do just the above, but iMPI.ent is NULL for
// exposed params, so for the moment we inverse the current world matrix.
// When there will be PerObjectMeanings iMPI.ent will be correct,
// and we'll remove this crappy matrix inversion
if( m_ReferentialEnum == AnnotStr_Local ){
VxMatrix worldMatrix = iMPI.rc->GetWorldTransformationMatrix();
VxMatrix invWorldMatrix;
Vx3DInverseMatrix( invWorldMatrix, worldMatrix );
Vx3DMultiplyMatrixVector( &objPos, invWorldMatrix, &objPos );
}
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &objPos );
}
int m_ReferentialEnum;
};
//#endif // _XBOX
//--------------------------------------------------------------------------------
// Exposed XDVector Param (To Derived)
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
Meaning*
ExposedXDVectorParamMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
//#if DIRECT3D_VERSION<0x0900
// ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedVectorizableParamMeaning, iMII );
// inst->m_Guid = CKPGUID_VECTOR4;
//#else
int colSize = cgGetParameterColumns(iMII.paramDesc);
//--- Here are the Annotations we are interested in
XString annotType;
iMII.sdm->ExpectingAnnotation( Annot_Type, AnnotType_String, &annotType );
XString annotSpace;
iMII.sdm->ExpectingAnnotation( Annot_Space, AnnotType_String, &annotSpace );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
//--- Space = ?
int annotSpaceStrValueIndex = AnnotStr_Unknown;
if( annotSpace.Length() ){
annotSpaceStrValueIndex = iMII.sdm->GetAnnotStrValueIndexFromString( annotSpace );
}
//--- Type = ?
if( annotType.Length() ){
int annotStrValueIndex = iMII.sdm->GetAnnotStrValueIndexFromString( annotType );
switch( annotStrValueIndex ){
//--- Type = "3dEntity" ?
case AnnotStr_Entity3D:
{
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedParamMeaning_ObjectPos, iMII );
inst->m_Guid = CKPGUID_3DENTITY;
((ExposedParamMeaning_ObjectPos*)inst)->m_ReferentialEnum = annotSpaceStrValueIndex;
return inst;
} break;
//--- Type = "Camera" ?
case AnnotStr_Camera:
{
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedParamMeaning_ObjectPos, iMII );
inst->m_Guid = CKPGUID_CAMERA;
((ExposedParamMeaning_ObjectPos*)inst)->m_ReferentialEnum = annotSpaceStrValueIndex;
return inst;
} break;
//--- Type = "Light" ?
case AnnotStr_Light:
{
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedParamMeaning_ObjectPos, iMII );
inst->m_Guid = CKPGUID_LIGHT;
((ExposedParamMeaning_ObjectPos*)inst)->m_ReferentialEnum = annotSpaceStrValueIndex;
return inst;
} break;
//--- Type = "vector" ?
case AnnotStr_Vector:
{
if( colSize == 4 ){
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedVectorizableParamMeaning, iMII );
inst->m_Guid = CKPGUID_VECTOR4;
return inst;
}
} break;
}
}
//--- Otherwise it's a single ExposedVectorizableParamMeaning
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedVectorizableParamMeaning, iMII );
if( colSize>4 || colSize<1 ) return inst;
inst->m_Guid = columnMatchingGuid[ colSize ];
//#endif
return inst;
}
//--------------------------------------------------------------------------------
// Object's Matrix Param
//--------------------------------------------------------------------------------
class ExposedParamMeaning_ObjectMatrix : public ExposedParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ExposedParamMeaning_ObjectMatrix );
ExposedParamMeaning_ObjectMatrix() :
m_ReferentialEnum( AnnotStr_Unknown ){}
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
CK3dEntity* ent = (CK3dEntity*)iMPI.param->GetValueObject(FALSE);
if( !ent ) return;
//--- Get referential in which to retrieve information
CK3dEntity* referential = (m_ReferentialEnum == AnnotStr_Local)? iMPI.ent:NULL;
VxMatrix objMatrix = ent->GetWorldMatrix();
if( referential ){
Vx3DMultiplyMatrix( objMatrix, referential->GetInverseWorldMatrix(), ent->GetWorldMatrix() );
}
SetValueByMatrix( iMPI, objMatrix );
}
int m_ReferentialEnum;
};
//--------------------------------------------------------------------------------
// Exposed Matrix Params
//--------------------------------------------------------------------------------
Meaning* ExposedMatrixParamMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
//#if DIRECT3D_VERSION>=0x0900
//--- Here are the Annotations we are interested in
XString annotType;
iMII.sdm->ExpectingAnnotation( Annot_Type, AnnotType_String, &annotType );
XString annotSpace;
iMII.sdm->ExpectingAnnotation( Annot_Space, AnnotType_String, &annotSpace );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
//--- Space = ?
int annotSpaceStrValueIndex = AnnotStr_Unknown;
if( annotSpace.Length() ){
annotSpaceStrValueIndex = iMII.sdm->GetAnnotStrValueIndexFromString( annotSpace );
}
//--- Type = ?
if( annotType.Length() ){
int annotStrValueIndex = iMII.sdm->GetAnnotStrValueIndexFromString( annotType );
switch( annotStrValueIndex ){
//--- Type = "3dEntity" ?
case AnnotStr_Entity3D:
{
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedParamMeaning_ObjectMatrix, iMII );
inst->m_Guid = CKPGUID_3DENTITY;
((ExposedParamMeaning_ObjectMatrix*)inst)->m_ReferentialEnum = annotSpaceStrValueIndex;
return inst;
} break;
//--- Type = "Camera" ?
case AnnotStr_Camera:
{
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedParamMeaning_ObjectMatrix, iMII );
inst->m_Guid = CKPGUID_CAMERA;
((ExposedParamMeaning_ObjectPos*)inst)->m_ReferentialEnum = annotSpaceStrValueIndex;
return inst;
} break;
//--- Type = "Light" ?
case AnnotStr_Light:
{
ExposedParamMeaning* inst = (ExposedParamMeaning*)Instantiate_MeaningCG( ExposedParamMeaning_ObjectMatrix, iMII );
inst->m_Guid = CKPGUID_LIGHT;
((ExposedParamMeaning_ObjectPos*)inst)->m_ReferentialEnum = annotSpaceStrValueIndex;
return inst;
} break;
}
}
//#endif
ExposedMatrixParamMeaning* inst = new ExposedMatrixParamMeaning;
inst->m_Guid = CKPGUID_MATRIX;
return inst;
}
void
ExposedMatrixParamMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
VxMatrix* matrix = (VxMatrix*)iMPI.param->GetReadDataPtr();
SetValueByMatrix(iMPI,*matrix);
}
//#if DIRECT3D_VERSION>=0x0900
//--------------------------------------------------------------------------------
// Exposed Array Params
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------
CLASSIC_INSTANTIATOR_DEFINITION_CG( ExposedArrayParamMeaning );
void
ExposedArrayParamMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
CKDataArray* ar = (CKDataArray*) iMPI.param->GetValueObject();
if( !ar ) return;
int columnCount = ar->GetColumnCount();
int rowCount = ar->GetRowCount();
int elements = cgGetArrayTotalSize( m_ParamDesc );
int RowSize = cgGetParameterRows( m_ParamDesc );
int ColSize = cgGetParameterColumns( m_ParamDesc );
//--- Do Nothing if destination size is smaller than source size
if( elements < ( rowCount * columnCount ) ) return;
//--- Do Nothing if Columns Types are different from the Shader Array Type
for( int a=0 ; a<columnCount ; ++a ){
CK_ARRAYTYPE columnType = ar->GetColumnType(0);
CKGUID columnGUID = CKGUID();
switch( columnType ){
case CKARRAYTYPE_INT:
columnGUID = CKPGUID_INT;
break;
case CKARRAYTYPE_FLOAT:
columnGUID = CKPGUID_FLOAT;
break;
case CKARRAYTYPE_STRING:
columnGUID = CKGUID();
break;
case CKARRAYTYPE_OBJECT:
columnGUID = CKGUID();
break;
case CKARRAYTYPE_PARAMETER:
columnGUID = ar->GetColumnParameterGuid( a );
break;
}
if( columnGUID != m_Guid2 ) return;
}
//--- Copy values from CKArray
CGtype pBaseType = cgGetParameterBaseType( m_ParamDesc );
switch(pBaseType) {
case CG_FLOAT:// scalar, vector2,3,4 , matrix
{
const DWORD stride = RowSize*ColSize*sizeof(float);
unsigned int paramBytesSize = elements*stride;
BYTE* temp = new BYTE[ paramBytesSize ];
BYTE* it = temp;
// NB : As with the HLSL version : treat virtools array as having 'column-major' order!
for(int i = 0;i<columnCount;i++){
for( int j = 0;j<rowCount ; j++ ){
ar->GetElementValue(j,i,it);
it += stride;
}
}
if(RowSize > 1) { //Matrix
XASSERT((ColSize == 4)&&(RowSize == 4));
WrapCGSetMatrixParameterArray(iMPI, (const VxMatrix *) temp, elements, false);
}
else { //vector
switch(ColSize) {
case 1:
WrapCGSetParameterArray1f(iMPI, (float*)temp, elements);
break;
case 2:
WrapCGSetParameterArray2f(iMPI, (float*)temp, elements);
break;
case 3:
WrapCGSetParameterArray3f(iMPI, (float*)temp, elements);
break;
case 4:
WrapCGSetParameterArray4f(iMPI, (float*)temp, elements);
break;
default:
XASSERT(0);
}
}
delete [] temp;
}
break;
case CG_INT: // scalar
case CG_BOOL:
{
CGparameter param = NULL;
int* value = NULL;
for(int i = 0;i<columnCount;i++){
for( int j = 0;j<rowCount ; j++ ){
value = (int*)ar->GetElement(j,i);
param = cgGetArrayParameter(m_ParamDesc, 0);
//WrapCGSetParameter1i(param, *value);
cgSetParameter1i(param, *value);
}
}
}
break;
case CG_TEXTURE: // scalar
{
#pragma todo("Texture arrays not handled")
CGparameter param = NULL;
CKTEXTUREDESC* value = NULL;
for(int i = 0;i<columnCount;i++){
for( int j = 0;j<rowCount ; j++ ){
value = (CKTEXTUREDESC*)ar->GetElement(j,i);
param = cgGetArrayParameter(m_ParamDesc, 0);
//cgSetStringParameterValue(param,value);
cgGLSetTextureParameter(param, value->GLTextureIndex);
//cgGLSetupSampler(param, value->GLTextureIndex);
}
}
}
break;
case CG_STRING: //scalar
{
CGparameter param = NULL;
char* str = NULL;
for(int i = 0;i<columnCount;i++){
for( int j = 0;j<rowCount ; j++ ){
str = (char*)ar->GetElement(j,i);
param = cgGetArrayParameter(m_ParamDesc, 0);
cgSetStringParameterValue(param,str);
}
}
}
break;
default:
XASSERT(0);
}
TouchDependentRenderStates(iMPI);
// BYTE* temp = new BYTE[ paramBytesSize ];
// BYTE* it = temp;
// const DWORD stride = m_ParamDesc.Bytes/m_ParamDesc.Elements;
//
// for(int i = 0;i<columnCount;i++){
//
// for( int j = 0;j<rowCount ; j++ ){
// ar->GetElementValue(j,i,it);
// it += stride;
// }
// }
//
// iMPI.fx->SetValue( m_D3DHandle, temp, paramBytesSize );
//
// delete [] temp;
}
//#endif
//--------------------------------------------------------------------------------
// Exposed Texture Params
//--------------------------------------------------------------------------------
GLint StringToGLFormat( const char* pstrFormat );
//--------------------------------------------------------------------------------
// Default Exposed Texture
//--------------------------------------------------------------------------------
class DefaultTextureParamMeaning : public ParamMeaning {
public:
virtual void ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
if(m_CKID && m_TexIdPtr)
{
CKTexture* tex = (CKTexture*)iMPI.shader->GetManager()->GetCKContext()->GetObject(m_CKID);
if( tex ){
tex->EnsureVideoMemory( iMPI.rc );
CKTEXTUREDESC* texDesc = (CKTEXTUREDESC*)
iMPI.rc->GetRasterizerContext()->GetTextureData( tex->GetRstTextureIndex() );
*m_TexIdPtr = texDesc ? texDesc->GLTextureIndex : 0;
}
else {
*m_TexIdPtr = 0;
m_CKID = 0;
}
}
}
CK_ID m_CKID;
GLuint* m_TexIdPtr;
};
//--------------------------------------------------------------------------
typedef BOOL (*_glCreateTextureFromDDSFile)(VCKGL15Rasterizer::CKGLRasterizerContext* ctx, const char* iFilename, GLuint &oGlName, int &ioMipMapCount, int &oBytesPerPixel, int &oWidth, int &oHeight, int &oDepth);
_glCreateTextureFromDDSFile g_glCreateTextureFromDDSFile = NULL;
Meaning*
ExposedTextureParamMeaning::MeaningInstantiator( const MeaningInstantiatorInfo& iMII ){
//--- Here are the Annotations we are interested in
XString annotName;
XString annotRscName;
XString annotFunction;
// XString annotTarget;
XString annotTextureType;
XString annotFormat;
int annotWidth = 0;
int annotHeight= 0;
int annotDepth = 0;
int annotMipLevels = 1;
VxVector4 annotDim( 0, 0, 0, 0 );
iMII.sdm->ExpectingAnnotation( Annot_Name, AnnotType_String, &annotName );
iMII.sdm->ExpectingAnnotation( Annot_ResourceName, AnnotType_String, &annotRscName );
iMII.sdm->ExpectingAnnotation( Annot_Function, AnnotType_String, &annotFunction );
// iMII.sdm->ExpectingAnnotation( Annot_Target, AnnotType_String, &annotTarget );
iMII.sdm->ExpectingAnnotation( Annot_ResourceType, AnnotType_String, &annotTextureType );
iMII.sdm->ExpectingAnnotation( Annot_Format, AnnotType_String, &annotFormat );
iMII.sdm->ExpectingAnnotation( Annot_Width, AnnotType_Int, &annotWidth );
iMII.sdm->ExpectingAnnotation( Annot_Height, AnnotType_Int, &annotHeight );
iMII.sdm->ExpectingAnnotation( Annot_Depth, AnnotType_Int, &annotDepth );
iMII.sdm->ExpectingAnnotation( Annot_Dimensions, AnnotType_Vector4, &annotDim );
iMII.sdm->ExpectingAnnotation( Annot_MIPLevels, AnnotType_Int, &annotMipLevels );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
//--- Prepare texture reference for registration
textureRef texRef;
texRef.TexId = 0;
texRef.TexIdPtrPtr = NULL;
//--- Do the job
CKContext* ctx = iMII.sdm->GetCKContext();
CKRenderContext* rc = iMII.shader->GetRenderContext();
GLuint idTex = 0;
CKTEXTUREDESC* existingTex = NULL;
CKTexture* tex = NULL;
CKBOOL res = TRUE;
DefaultTextureParamMeaning* existingInst = NULL;
XString strErrors;
//--- Use an Existing CKTexture if Name
if( annotName.Length() )
{
tex = (CKTexture*) ctx->GetObjectByNameAndClass( annotName.Str(), CKCID_TEXTURE );
if(tex){
existingInst = new DefaultTextureParamMeaning;
existingInst->m_TexIdPtr = NULL;
existingInst->m_CKID = tex->GetID();
//--- Register texture id
texRef.TexIdPtrPtr = &existingInst->m_TexIdPtr;
tex->EnsureVideoMemory( rc );
existingTex = (CKTEXTUREDESC*) tex->GetRstTextureObject();
if(existingTex){
//iMII.fx->SetTexture( iMII.h, existingTex );
texRef.TexId = existingTex->GLTextureIndex;
}
} else {
strErrors = "Unknown Texture ";
strErrors += annotName;
iMII.sdm->GetShaderManager()->m_Output.PushBack( strErrors );
}
}
//--- Load a texture file if ResourceName
if( annotRscName.Length() )
{
// Get GL rasterizer context
VCKGL15Rasterizer::CKGLRasterizerContext* rstCtx = (VCKGL15Rasterizer::CKGLRasterizerContext*)rc->GetRasterizerContext();
// load a dll in order to retrieve a specific function and call it
if (!g_glCreateTextureFromDDSFile) {
VxSharedLibrary glShl;
if(NULL != glShl.Load("CKGLRasterizer.dll")){
g_glCreateTextureFromDDSFile = (_glCreateTextureFromDDSFile)glShl.GetFunctionPtr("glCreateTextureFromDDSFile");
}
glShl.ReleaseLibrary();
}
idTex = 0;
ctx->GetPathManager()->ResolveFileName( annotRscName, BITMAP_PATH_IDX );
int annotStrValueIndex;
//--- There's a Texture Type Specified
if( annotTextureType.Length() )
{
annotStrValueIndex = iMII.sdm->GetAnnotStrValueIndexFromString( annotTextureType );
} else
//--- There's no Texture Type Specified
{
annotStrValueIndex = AnnotStr_2d;
}
switch( annotStrValueIndex )
{
case AnnotStr_Volume:
case AnnotStr_3d:
{
XASSERT(!(annotStrValueIndex == AnnotStr_3d));
GLuint pVolumeTex = 0;
int mipmapCount = -1;
int oBytesPerPixel = 0;
int oWidth = 0;
int oHeight = 0;
int oDepth = 0;
if (g_glCreateTextureFromDDSFile &&
g_glCreateTextureFromDDSFile(rstCtx,annotRscName.CStr(),pVolumeTex,mipmapCount,oBytesPerPixel,oWidth,oHeight,oDepth))
{
idTex = pVolumeTex;
}
else
{
strErrors = "Could not load volume texture ";
strErrors += annotRscName.CStr();
iMII.sdm->GetShaderManager()->m_Output.PushBack( strErrors );
}
} break;
case AnnotStr_Cube:
{
GLuint pCubeTex = 0;
int mipmapCount = -1;
int oBytesPerPixel = 0;
int oWidth = 0;
int oHeight = 0;
int oDepth = 0;
if (g_glCreateTextureFromDDSFile &&
g_glCreateTextureFromDDSFile(rstCtx,annotRscName.CStr(),pCubeTex,mipmapCount,oBytesPerPixel,oWidth,oHeight,oDepth))
{
idTex = pCubeTex;
}
else
{
CKBitmapData bitmap(ctx);
bitmap.SetSystemCaching(CKBITMAP_DISCARD);
res &= bitmap.LoadSlotImage(annotRscName.CStr());
VxImageDescEx desc;
res &= bitmap.GetImageDesc(desc);
CKBYTE* imagePtr = bitmap.LockSurfacePtr();
res &= (bitmap.GetSlotCount() == 6);
if (res && imagePtr) {
glGenTextures(1, &pCubeTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, pCubeTex);
for (int i = 0 ; i < 6 ; i++)
{
bitmap.SetCurrentSlot(i);
imagePtr = bitmap.LockSurfacePtr();
if (bitmap.GetImageDesc(desc) && imagePtr)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA8, desc.Width, desc.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imagePtr);
}
idTex = pCubeTex;
XASSERT(glGetError()==GL_NO_ERROR);
}
else
{
strErrors = "Could not load cube texture ";
strErrors += annotRscName.CStr();
iMII.sdm->GetShaderManager()->m_Output.PushBack( strErrors );
}
bitmap.FlushSurfacePtr();
}
} break;
case AnnotStr_Unknown:
{
strErrors = "Unknown Texture Type ";
strErrors += annotTextureType.CStr();
iMII.sdm->GetShaderManager()->m_Output.PushBack( strErrors );
}
case AnnotStr_2d:
{
GLuint p2DTex = 0;
#pragma todo ("Use Automatic MipMap Generation, or take the MipMap level include in the DDS file ?")
int mipmapCount = -1; // Automatic MipMap Generation, or take the MipMap level include in the DDS
int oBytesPerPixel = 0;
int oWidth = 0;
int oHeight = 0;
int oDepth = 0;
if (g_glCreateTextureFromDDSFile &&
g_glCreateTextureFromDDSFile(rstCtx,annotRscName.CStr(),p2DTex,mipmapCount,oBytesPerPixel,oWidth,oHeight,oDepth))
{
idTex = p2DTex;
}
else
{
CKBitmapData bitmap(ctx);
bitmap.SetSystemCaching(CKBITMAP_DISCARD);
res &= bitmap.LoadSlotImage(annotRscName.CStr());
VxImageDescEx desc;
res &= bitmap.GetImageDesc(desc);
CKBYTE* imagePtr = bitmap.LockSurfacePtr();
if (res && imagePtr) {
glGenTextures(1, &p2DTex);
glBindTexture(GL_TEXTURE_2D, p2DTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, desc.Width, desc.Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, imagePtr);
idTex = p2DTex;
XASSERT(glGetError()==GL_NO_ERROR);
}
else
{
strErrors = "Could not load texture ";
strErrors += annotRscName.CStr();
iMII.sdm->GetShaderManager()->m_Output.PushBack( strErrors );
}
bitmap.FlushSurfacePtr();
}
}break;
}
//--- Apply successfully loaded texture to effect
if( res && idTex != 0 )
{
//iMII.fx->SetTexture( iMII.h, idTex );
//idTex->Release();
texRef.TexId = idTex;
iMII.shader->m_Textures.Insert(cgGetParameterName(iMII.paramDesc), texRef);
if (existingInst) delete existingInst;
return NULL;
}
}
//--- Procedural texture if Function
else if( annotFunction.Length() )
{
CKShader* shader = iMII.shader->GetCKShader();
float* pixelBuffer = NULL;
CGprogram tp = cgCreateProgramFromEffect(iMII.fx, CG_PROFILE_GENERIC,annotFunction.CStr(), NULL);
if(tp)
{
//--- Using Existing Texture
if( existingTex ){
GLenum glTarget= GL_TEXTURE_2D;
GLint glWidth = 1;
GLint glHeight = 1;
GLint glDepth = 1;
GLint glComps = 4;
GLint doMipMap = 0;
if(existingTex->Flags & CKRST_TEXTURE_CUBEMAP){
glTarget = GL_TEXTURE_CUBE_MAP;
}
else if (existingTex->Flags & CKRST_TEXTURE_VOLUMEMAP) {
glTarget = GL_TEXTURE_3D;
}
glBindTexture(glTarget, existingTex->GLTextureIndex);
glGetTexLevelParameteriv(glTarget,0,GL_TEXTURE_WIDTH,&glWidth);
glGetTexLevelParameteriv(glTarget,0,GL_TEXTURE_HEIGHT,&glHeight);
glGetTexLevelParameteriv(glTarget,0,GL_TEXTURE_DEPTH,&glDepth);
// try to get the first mipmap-level, if it's here, set the auto mipmap generation On
glGetTexLevelParameteriv(glTarget,1,GL_TEXTURE_WIDTH,&doMipMap);
if (doMipMap)
glTexParameteri(glTarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
pixelBuffer = new float[glComps*glWidth*glHeight*glDepth];
cgEvaluateProgram(tp, pixelBuffer, glComps, glWidth, glHeight, glDepth);
if (existingTex->Flags & CKRST_TEXTURE_VOLUMEMAP) {
PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = NULL;
#ifndef macintosh
glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)wglGetProcAddress("glTexSubImage3D");
#else
glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)aglGetProcAddress("glTexSubImage3D");
#endif
if(glTexSubImage3D)
glTexSubImage3D(GL_TEXTURE_3D,/*MipLevel*/0,0,0,0,glWidth,glHeight,glDepth,GL_RGBA,GL_FLOAT,pixelBuffer);
}
else{
//if(existingTex->Flags & CKRST_TEXTURE_CUBEMAP)
glTexSubImage2D(GL_TEXTURE_2D,/*MipLevel*/0,0,0,glWidth,glHeight,GL_RGBA,GL_FLOAT,pixelBuffer);
}
if ( pixelBuffer )
delete[] pixelBuffer;
pixelBuffer = NULL;
// Register texture id from texture name
//texRef.TexId = existingTex->GLTextureIndex;
} else if(!existingInst)
//--- Not Using Existing Texture
{
GLint fmt = GL_RGBA8;
if( annotFormat.Length() ){
fmt = StringToGLFormat( annotFormat.CStr() );
}
// pTextureShader->SetDefaults();
if( annotDim.x != 0 ) annotWidth = (UINT)annotDim.x;
if( annotDim.y != 0 ) annotHeight = (UINT)annotDim.y;
if( annotDim.z != 0 ) annotDepth = (UINT)annotDim.z;
if( annotWidth == 0 ) annotWidth = 64;
if( annotHeight == 0 ) annotHeight = 64;
if( annotDepth == 0 ) annotDepth = 64;
int annotStrValueIndex;
//--- There's a Texture Type Specified
if( annotTextureType.Length() )
{
annotStrValueIndex = iMII.sdm->GetAnnotStrValueIndexFromString( annotTextureType );
} else
//--- There's no Texture Type Specified
{
annotStrValueIndex = AnnotStr_2d;
}
switch( annotStrValueIndex ){
case AnnotStr_Volume:
case AnnotStr_3d:
{
XASSERT(idTex == 0);
glGenTextures(1, &idTex);
glBindTexture(GL_TEXTURE_3D,idTex);
pixelBuffer = new float[4*annotWidth*annotHeight*annotDepth];
cgEvaluateProgram(tp, pixelBuffer, 4, annotWidth, annotHeight, annotDepth);
PFNGLTEXIMAGE3DPROC glTexImage3D = NULL;
#ifndef macintosh
glTexImage3D = (PFNGLTEXIMAGE3DPROC)wglGetProcAddress("glTexImage3D");
#else
glTexImage3D = (PFNGLTEXIMAGE3DPROC)aglGetProcAddress("glTexImage3D");
#endif
if (annotMipLevels>1)
glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
if (glTexImage3D)
glTexImage3D(GL_TEXTURE_3D, 0, fmt, annotWidth, annotHeight, annotDepth, 0, GL_RGBA, GL_FLOAT, pixelBuffer );
} break;
case AnnotStr_Cube:
{
#pragma todo ("Texture Shader on a cubemap seem not to be working, clarify this")
// LPDIRECT3DCUBETEXTURE9 pCubeTex = NULL;
// if( SUCCEEDED( hr = D3DXCreateCubeTexture( dev9,
// annotWidth, annotMipLevels, 0, fmt, D3DPOOL_MANAGED, &pCubeTex) ) )
// {
// if( SUCCEEDED( hr = D3DXFillCubeTextureTX( pCubeTex, pTextureShader ) ) )
// pTex = pCubeTex;
// }
} break;
case AnnotStr_2d:
{
XASSERT(idTex == 0);
glGenTextures(1, &idTex);
glBindTexture(GL_TEXTURE_2D,idTex);
pixelBuffer = new float[4*annotWidth*annotHeight];
cgEvaluateProgram(tp, pixelBuffer, 4, annotWidth, annotHeight, 1);
if (annotMipLevels>1)
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, fmt, annotWidth, annotHeight, 0, GL_RGBA, GL_FLOAT, pixelBuffer );
} break;
}
// iMII.fx->SetTexture( iMII.h, pTex );
// SAFERELEASE(pTex);
// SAFERELEASE(pTextureShader);
// SAFERELEASE(ppConstantTable);
cgDestroyProgram(tp);
if ( pixelBuffer )
delete[] pixelBuffer;
//pixelBuffer = NULL;
texRef.TexId = idTex;
iMII.shader->m_Textures.Insert(cgGetParameterName(iMII.paramDesc), texRef);
if (existingInst)
delete existingInst;
GLCHECK();
return NULL;
}
// SAFERELEASE(pFunction);
cgDestroyProgram(tp);
// return NULL;
}
// if( pBufferErrors != NULL )
// {
// strErrors = (CHAR*)pBufferErrors->GetBufferPointer();
// iMII.sdm->GetShaderManager()->m_Output.PushBack( strErrors );
// pBufferErrors->Release();
// }
}
//--- Do not exposed texture if an existing texture has been found
///// return NULL has not be called just after existing texture has been found because
///// this texture can be filled after that by a texture shader.
if( existingTex || existingInst){
iMII.shader->m_Textures.Insert(cgGetParameterName(iMII.paramDesc), texRef);
return existingInst;
}
//--- Otherwise, simply Expose a Texture Parameter Meaning
ExposedTextureParamMeaning* inst = new ExposedTextureParamMeaning;
inst->m_Guid = CKPGUID_TEXTURE;
inst->m_TexIdPtr = NULL;
//--- Register texture id from texture name
texRef.TexIdPtrPtr = &inst->m_TexIdPtr;
iMII.shader->m_Textures.Insert(cgGetParameterName(iMII.paramDesc), texRef);
return inst;
}
//--------------------------------------------------------------------------
void
ExposedTextureParamMeaning::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
GLCHECK()
if (m_TexIdPtr) {
CKTexture* tex = (CKTexture*)iMPI.param->GetValueObject( FALSE );
if( tex ){
tex->EnsureVideoMemory( iMPI.rc );
CKTEXTUREDESC* texDesc = (CKTEXTUREDESC*)
iMPI.rc->GetRasterizerContext()->GetTextureData( tex->GetRstTextureIndex() );
*m_TexIdPtr = texDesc ? texDesc->GLTextureIndex : 0;
}
else
*m_TexIdPtr = 0;
}
GLCHECK()
}
//--------------------------------------------------------------------------------
// Ambient
//--------------------------------------------------------------------------------
class ParamMeaning_Ambient : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Ambient );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
if(iMPI.mat)
SetValueByCastingVectorParam( iMPI, sizeof(VxColor), &iMPI.mat->GetAmbient() );
}
};
//--------------------------------------------------------------------------------
// Emissive
//--------------------------------------------------------------------------------
class ParamMeaning_Emissive : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Emissive );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
if(iMPI.mat)
SetValueByCastingVectorParam( iMPI, sizeof(VxColor), &iMPI.mat->GetEmissive() );
}
};
//--------------------------------------------------------------------------------
// Diffuse
//--------------------------------------------------------------------------------
class ParamMeaning_Diffuse : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Diffuse );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
if(iMPI.mat)
SetValueByCastingVectorParam( iMPI, sizeof(VxColor), &iMPI.mat->GetDiffuse() );
}
};
//--------------------------------------------------------------------------------
// Specular
//--------------------------------------------------------------------------------
class ParamMeaning_Specular : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Specular );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
if(iMPI.mat)
SetValueByCastingVectorParam( iMPI, sizeof(VxColor), &iMPI.mat->GetSpecular() );
}
};
//--------------------------------------------------------------------------------
// Power
//--------------------------------------------------------------------------------
class ParamMeaning_Power : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Power );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float power = iMPI.mat->GetPower();
SetValueByCastingVectorParam( iMPI, sizeof(float), &power );
}
};
//--------------------------------------------------------------------------------
// AlphaTestEnable
//--------------------------------------------------------------------------------
class ParamMeaning_AlphaTestEnable : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_AlphaTestEnable );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float alphaTestEnable = iMPI.mat->AlphaTestEnabled() ? 1.f : 0.f;
SetValueByCastingVectorParam( iMPI, sizeof(float), &alphaTestEnable );
}
};
//--------------------------------------------------------------------------------
// AlphaTestEnable
//--------------------------------------------------------------------------------
class ParamMeaning_AlphaBlendEnable : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_AlphaBlendEnable );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float alphaBlendEnable = iMPI.mat->AlphaBlendEnabled() ? 1.f : 0.f;
SetValueByCastingVectorParam( iMPI, sizeof(float), &alphaBlendEnable );
}
};
//--------------------------------------------------------------------------------
// AlphaFunc
//--------------------------------------------------------------------------------
class ParamMeaning_AlphaFunc : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_AlphaFunc );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
XASSERT(((CKDWORD) iMPI.mat->GetAlphaFunc()) < sizeofarray(GLCmpFunc)); // superstitious
float glAlphaFunc = (float) GLCmpFunc[iMPI.mat->GetAlphaFunc()];
SetValueByCastingVectorParam( iMPI, sizeof(float), &glAlphaFunc );
}
};
//--------------------------------------------------------------------------------
// AlphaRef
//--------------------------------------------------------------------------------
class ParamMeaning_AlphaRef : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_AlphaRef );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float alphaRef = iMPI.mat->GetAlphaRef() * (1.f / 255.f);
SetValueByCastingVectorParam( iMPI, sizeof(float), &alphaRef );
}
};
//--------------------------------------------------------------------------------
// SingleSided
//--------------------------------------------------------------------------------
class ParamMeaning_SingleSided : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_SingleSided );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float singleSided = iMPI.mat->IsTwoSided() ? 0.f : 1.f;
SetValueByCastingVectorParam( iMPI, sizeof(float), &singleSided );
}
};
//--------------------------------------------------------------------------------
// DoubleSided
//--------------------------------------------------------------------------------
class ParamMeaning_DoubleSided : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_DoubleSided );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float singleSided = iMPI.mat->IsTwoSided() ? 1.f : 0.f;
SetValueByCastingVectorParam( iMPI, sizeof(float), &singleSided );
}
};
//--------------------------------------------------------------------------------
// Texture
//--------------------------------------------------------------------------------
class ParamMeaning_Texture : public ParamMeaning {
public:
static Meaning* MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
ParamMeaning_Texture* inst = new ParamMeaning_Texture;
inst->m_ChannelIndex = iMII.semIndex - Sem_Texture0;
inst->m_TexIdPtr = NULL;
if( iMII.semIndex <= Sem_Texture ) inst->m_ChannelIndex = -1;
else if( iMII.semIndex >= Sem_Texture7 ) inst->m_ChannelIndex = 7;
textureRef texRef;
texRef.TexId = 0;
texRef.TexIdPtrPtr = &inst->m_TexIdPtr;
iMII.shader->m_Textures.Insert(cgGetParameterName(iMII.paramDesc), texRef);
return inst;
}
void ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
if (m_TexIdPtr)
{
CKTexture* tex = NULL;
//--- : TEXURE
if( m_ChannelIndex == -1 ){
if( iMPI.mat ) tex = iMPI.mat->GetTexture();
}
//--- : TEXURE0, TEXURE1, ... or TEXTURE7 (Channels)
else {
//--- Real Channels of a Mesh
if( iMPI.ent ){
CKMesh* mesh = iMPI.ent->GetCurrentMesh();
if( mesh ){
CKMaterial* channelMat = mesh->GetChannelMaterial( m_ChannelIndex );
if( channelMat ) tex = channelMat->GetTexture();
}
}
//--- Pseudo-Channels (ex: Combine RTViews BB)
else {
tex = iMPI.rc->m_ShaderManager->m_PseudoChannelTexture[ m_ChannelIndex ];
}
}
//--- Assign Texture
if( tex ){
tex->EnsureVideoMemory( iMPI.rc );
CKTEXTUREDESC* texDesc = (CKTEXTUREDESC*)
iMPI.rc->GetRasterizerContext()->GetTextureData( tex->GetRstTextureIndex() );
*m_TexIdPtr = texDesc ? texDesc->GLTextureIndex : 0;
}
else
*m_TexIdPtr = 0;
}
}
GLuint* m_TexIdPtr;
int m_ChannelIndex;
};
//--------------------------------------------------------------------------------
// Sampler
//--------------------------------------------------------------------------------
class ParamMeaning_Sampler : public ParamMeaning {
public:
void ResetSamplerSetup()
{
// default value that indicate we don't setup that state
m_WrapS = -1;
m_WrapT = -1;
m_WrapR = -1;
m_MinFilter = -1;
m_MagFilter = -1;
m_GenerateMipMap = -1;
m_UseBorderColor = false;
m_BorderColor[0] = m_BorderColor[1] = m_BorderColor[2] = m_BorderColor[3] = 0.f;
}
static Meaning* MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
ParamMeaning_Sampler* inst = new ParamMeaning_Sampler;
inst->ResetSamplerSetup();
inst->m_ParamDesc = iMII.paramDesc;
inst->m_TexIdPtr = NULL;
inst->m_TexId = 0;
samplerRef spr;
spr.TexIdPtrPtr = &(inst->m_TexIdPtr);
spr.TexName = NULL;
const char *texturePostFix;
switch(cgGetParameterType(iMII.paramDesc)) {
case CG_SAMPLER1D:
inst->m_TexTarget = GL_TEXTURE_1D;
texturePostFix = "1D";
break;
case CG_SAMPLER3D:
inst->m_TexTarget = GL_TEXTURE_3D;
texturePostFix = "3D";
break;
case CG_SAMPLERRECT:
texturePostFix = "Rectangle";
inst->m_TexTarget = GL_TEXTURE_RECTANGLE_ARB;
break;
case CG_SAMPLERCUBE:
texturePostFix = "CubeMap";
inst->m_TexTarget = GL_TEXTURE_CUBE_MAP;
break;
case CG_SAMPLER2D:
texturePostFix = "2D";
inst->m_TexTarget = GL_TEXTURE_2D;
break;
default:
inst->m_TexTarget = GL_TEXTURE_2D;
break;
}
inst->m_UseCGSamplerFallback = false;
// Precompute texture id and sampler state assignement if possibles (this way we can avoid a call
// to cgSetSampler)
CGstateassignment stateassign = cgGetFirstSamplerStateAssignment(inst->m_ParamDesc);
while (stateassign) {
CGstate samplerState = cgGetSamplerStateAssignmentState(stateassign);
CGtype stateType = cgGetStateType(samplerState);
CGparameter texParam = NULL;
if (stateType == CG_TEXTURE)
{
texParam = cgGetTextureStateAssignmentValue(stateassign);
}
if (texParam) {
spr.TexName = cgGetParameterName(texParam);
}
else
{
CGstate state = cgGetSamplerStateAssignmentState(stateassign);
XString stateAssignementName = cgGetStateName(state);
stateAssignementName.ToLower();
int valueCount = 0;
if (stateAssignementName == "addressu" || stateAssignementName == "wraps")
{
const int *values = cgGetIntStateAssignmentValues(stateassign, &valueCount);
if (valueCount == 1)
{
inst->m_WrapS = *values;
}
else
{
inst->m_UseCGSamplerFallback = true;
}
}
else if (stateAssignementName == "addressv" || stateAssignementName == "wrapt")
{
const int *values = cgGetIntStateAssignmentValues(stateassign, &valueCount);
if (valueCount == 1)
{
inst->m_WrapT = *values;
}
else
{
inst->m_UseCGSamplerFallback = true;
}
}
else if (stateAssignementName == "addressw" || stateAssignementName == "wrapr")
{
const int *values = cgGetIntStateAssignmentValues(stateassign, &valueCount);
if (valueCount == 1)
{
inst->m_WrapR = *values;
}
else
{
inst->m_UseCGSamplerFallback = true;
}
}
else if (stateAssignementName == "minfilter")
{
const int *values = cgGetIntStateAssignmentValues(stateassign, &valueCount);
if (valueCount == 1)
{
inst->m_MinFilter = *values;
}
else
{
inst->m_UseCGSamplerFallback = true;
}
}
else if (stateAssignementName == "magfilter")
{
const int *values = cgGetIntStateAssignmentValues(stateassign, &valueCount);
if (valueCount == 1)
{
inst->m_MagFilter = *values;
}
else
{
inst->m_UseCGSamplerFallback = true;
}
}
else if (stateAssignementName == "bordercolor")
{
const float *values = cgGetFloatStateAssignmentValues(stateassign, &valueCount);
if (valueCount == 4)
{
memcpy(&inst->m_BorderColor[0], values, 4 * sizeof(float));
inst->m_UseBorderColor = true;
}
else
{
inst->m_UseCGSamplerFallback = true;
}
}
else if (stateAssignementName == "generatemipmap")
{
const CGbool *values = cgGetBoolStateAssignmentValues(stateassign, &valueCount);
if (valueCount == 1)
{
inst->m_MagFilter = *values ? 1 : 0;
}
else
{
inst->m_UseCGSamplerFallback = true;
}
}
else
{
// unknown sampler state
inst->m_UseCGSamplerFallback = true;
}
// Make sure that state is static (e.g it doesn't depends on a parameter of the shader
// (else we must rely on cgSetupSampler to make sure the state will be correctly evaluated)
if (cgGetNumDependentStateAssignmentParameters(stateassign) != 0)
{
inst->m_UseCGSamplerFallback = true;
}
}
stateassign = cgGetNextStateAssignment(stateassign);
}
if (inst->m_UseCGSamplerFallback)
{
inst->ResetSamplerSetup();
}
// Determine wether the sampler is "per-pass" or "per-technique"
iMII.shader->m_Samplers.PushBack(spr);
inst->m_PerTechSamplerInfo.Resize(iMII.techniqueCount);
CGtechnique currTech = cgGetFirstTechnique(iMII.fx);
int techIndex = 0;
while (currTech)
{
// for each pass in this technique
CGpass currPass = cgGetFirstPass(currTech);
XArray<int> &stageArray = inst->m_PerTechSamplerInfo[techIndex].PerPassSamplerStage;
while (currPass)
{
int samplerStageBits = 0;
///////////////////////////
// Programmable pipeline //
///////////////////////////
CGstateassignment fragmentPrgStateAssign = cgGetNamedStateAssignment(currPass, "FragmentProgram");
if (!fragmentPrgStateAssign)
{
fragmentPrgStateAssign = cgGetNamedStateAssignment(currPass, "PixelShader");
}
if (fragmentPrgStateAssign)
{
CGprogram fragmentPrg = cgGetProgramStateAssignmentValue(fragmentPrgStateAssign);
if (fragmentPrg)
{
CGparameter progSampler = cgGetNamedParameter(fragmentPrg, cgGetParameterName(inst->m_ParamDesc));
if (progSampler)
{
CGresource paramResource = cgGetParameterResource(progSampler);
//if (strcmp(cgGetResourceString(paramResource), "CG_UNDEFINED") != 0)
if (paramResource != CG_UNDEFINED)
{
samplerStageBits |= (1 << cgGetParameterResourceIndex(progSampler));
}
}
}
}
CGstateassignment vertexPrgStateAssign = cgGetNamedStateAssignment(currPass, "VertexProgram");
if (!vertexPrgStateAssign)
{
vertexPrgStateAssign = cgGetNamedStateAssignment(currPass, "VertexShader");
}
if (vertexPrgStateAssign)
{
CGprogram vertexPrg = cgGetProgramStateAssignmentValue(vertexPrgStateAssign);
if (vertexPrg)
{
CGparameter progSampler = cgGetNamedParameter(vertexPrg, cgGetParameterName(inst->m_ParamDesc));
if (progSampler)
{
CGresource paramResource = cgGetParameterResource(progSampler);
//if (strcmp(cgGetResourceString(paramResource), "CG_UNDEFINED") != 0)
if (paramResource != CG_UNDEFINED)
{
samplerStageBits |= (1 << cgGetParameterResourceIndex(progSampler));
}
}
}
}
////////////////////
// Fixed pipeline //
////////////////////
//
char stateNameBuf[256];
for (int stage = 0; stage < 16; ++stage)
{
sprintf(stateNameBuf, "Texture%sEnable[%u]", texturePostFix, stage);
CGstateassignment sa = cgGetNamedStateAssignment(currPass, stateNameBuf);
if (sa)
{
//XASSERT(cgGetNumDependentStateAssignmentParameters(sa) == 0); // conditionnal texture binding not supported, sorry ...
// see if texture used for that stage
int nvalues;
const CGbool *value =cgGetBoolStateAssignmentValues(sa, &nvalues);
XASSERT(nvalues == 1);
if (*value) // stage enabled ?
{
sprintf(stateNameBuf, "Texture%s[%u]", texturePostFix, stage);
sa = cgGetNamedStateAssignment(currPass, stateNameBuf);
if (sa)
{
//XASSERT(cgGetNumDependentStateAssignmentParameters(sa) == 0); // conditionnal texture selector not supported (don't know if even possible)
CGparameter sampler = cgGetSamplerStateAssignmentValue(sa);
if (sampler == inst->m_ParamDesc) // is it me ?
{
samplerStageBits |= 1 << stage;
}
}
}
}
}
//
stageArray.PushBack(samplerStageBits);
//
currPass = cgGetNextPass(currPass);
}
// Is the same for all passes in the technique ? -> reduce the array
if (!stageArray.IsEmpty())
{
int lastSamplerValue = stageArray[0];
bool allSame = true;
bool used = lastSamplerValue != 0;
for (int stage = 1; stage < stageArray.Size(); ++stage)
{
if (stageArray[stage] != 0)
{
used = true;
}
if (stageArray[stage] != lastSamplerValue)
{
allSame = false;
break;
}
}
if (!used)
{
stageArray.Clear(); // not used at all for that technique
}
else
if (allSame)
{
stageArray.Resize(1); // there is a single pass, or the sampler is "per-technique"
// (that is, it is used for all passes of the technique and remains bound to the
// same texture stage for all passes)
}
}
++ techIndex;
currTech = cgGetNextTechnique(currTech);
}
return inst;
}
virtual bool IsSampler() const { return true; }
// If this meaning is a sampler, returns true if this sampler has variable texture stage binding
// for the various passes of a shader (for that reason it will always return false for a single pass shader)
virtual bool IsPassDependantSampler(int techniqueIndex) const
{
PerTechSamplerInfo &stagePerPass = m_PerTechSamplerInfo[techniqueIndex];
return stagePerPass.PerPassSamplerStage.Size() > 1;
}
void ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
if (m_TexIdPtr) {
//
PerTechSamplerInfo &stagePerPass = m_PerTechSamplerInfo[iMPI.techniqueIndex];
if (iMPI.isPerPassMeanings)
{
if (stagePerPass.PerPassSamplerStage.Size() == 1)
{
return; // we are in the per-pass sampler setup, and this sampler is "per-technique" -> it was already setup during ShaderCG::ExecuteMeanings
}
}
else
{
if (stagePerPass.PerPassSamplerStage.Size() > 1)
{
// per technique setup, and this sampler is "per-pass" -> ignore
return;
}
}
if (stagePerPass.PerPassSamplerStage.IsEmpty())
{
// not used at all for that technique
return;
}
RCKShaderCG *parentShader = (RCKShaderCG *) iMPI.shader->GetCKShader();
int currentPassIndex = parentShader->GetCurrentPassIndex();
int textureStageBits = stagePerPass.PerPassSamplerStage[stagePerPass.PerPassSamplerStage.Size() == 1 ? 0 : currentPassIndex];
if (textureStageBits == 0)
{
// not used for current pass of current technique
return;
}
VCKGL15Rasterizer::CKGLRasterizerContext *ogRC = (VCKGL15Rasterizer::CKGLRasterizerContext *) iMPI.rc->GetRasterizerContext();
XASSERT(ogRC->m_glActiveTextureARB);
bool samplerSetupDone = false;
// examine each bit of 'textureStageBits' to see where that texture should be bound
for (int stage = 0; textureStageBits && stage < 16; ++stage, textureStageBits >>= 1)
{
if (!(textureStageBits & 1)) continue; // set for that stage ?
// set texture stage for that texture
ogRC->m_glActiveTextureARB(GL_TEXTURE0_ARB + stage);
GLCHECK();
ogRC->EnableGLTextureTarget(m_TexTarget);
//
glBindTexture(m_TexTarget, *m_TexIdPtr);
//
GLenum actualTarget = m_TexTarget;
GLenum err = glGetError();
if (err == GL_INVALID_OPERATION)
{
// texture dimension not compatible with the target, find the good target as a fallback
static const GLenum targets[] = {GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_CUBE_MAP};
int i;
for (i = 0 ; i < sizeofarray(targets) ; i++)
{
glEnable(targets[i]);
glBindTexture(targets[i], *m_TexIdPtr);
if (glGetError() == GL_NO_ERROR)
break;
XASSERT(i< sizeofarray(targets) - 1); // not found ??
}
actualTarget = targets[i];
}
else
{
XASSERT(err == GL_NO_ERROR);
}
//
ShaderManagerCG *sm = ((RCKShaderCG *) iMPI.shader->GetCKShader())->m_ShaderManager;
sm->SignalTextureStageUsed(stage, actualTarget);
if (!samplerSetupDone)
{
static volatile bool forceCGSetupSampler = false;
if (m_UseCGSamplerFallback || forceCGSetupSampler)
{
// there are some unkown (or dynamic) state assignment -> fallback on cg setup code
cgGLSetupSampler(m_ParamDesc,*m_TexIdPtr);
}
else
{
if (m_WrapS != -1) glTexParameteri(actualTarget, GL_TEXTURE_WRAP_S, m_WrapS);
if (m_WrapT != -1) glTexParameteri(actualTarget, GL_TEXTURE_WRAP_T, m_WrapT);
if (m_WrapR != -1) glTexParameteri(actualTarget, GL_TEXTURE_WRAP_R, m_WrapR);
if (m_MinFilter != -1) glTexParameteri(actualTarget, GL_TEXTURE_MIN_FILTER, m_MinFilter);
if (m_MagFilter != -1) glTexParameteri(actualTarget, GL_TEXTURE_MAG_FILTER, m_MagFilter);
if (m_GenerateMipMap != -1) glTexParameteri(actualTarget, GL_GENERATE_MIPMAP, m_GenerateMipMap);
if (m_UseBorderColor) glTexParameterfv(actualTarget, GL_TEXTURE_BORDER_COLOR, m_BorderColor);
}
if (actualTarget != m_TexTarget)
{
// not the good texture dimension : silently potential errors at setup
glGetError();
}
if (*m_TexIdPtr != m_TexId)
{
m_TexId = *m_TexIdPtr;
//--- HACK : detection of mip-mapping level on the texture
// Revert back from mip enums to GL_LINEAR if no mipmaps are found
GLint useMipMap;
glGetTexLevelParameteriv(actualTarget == GL_TEXTURE_CUBE_MAP_ARB ? GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB : actualTarget, 1, GL_TEXTURE_WIDTH, &useMipMap);
GLCHECK();
if (!useMipMap){
GLint minFilter;
glGetTexParameteriv(actualTarget, GL_TEXTURE_MIN_FILTER, &minFilter);
GLCHECK();
if (minFilter >= GL_NEAREST_MIPMAP_NEAREST && minFilter <= GL_LINEAR_MIPMAP_LINEAR)
{
glTexParameteri(actualTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLCHECK();
}
}
}
samplerSetupDone = true;
}
//
GLCHECK();
}
ogRC->m_glActiveTextureARB(GL_TEXTURE0_ARB);
}
/*
// old code
if (m_TexIdPtr) {
GLCHECK();
cgGLSetupSampler(m_ParamDesc,*m_TexIdPtr);
if (*m_TexIdPtr != m_TexId) { // Current texture as been changed. Need update sampler
m_TexId = *m_TexIdPtr;
glBindTexture(m_TexTarget, m_TexId);
//cgSetSamplerState(m_ParamDesc);
//cgGLSetTextureParameter(m_ParamDesc,m_TexId);
//cgGLSetupSampler(m_ParamDesc,m_TexId);
//--- HACK : detection of mip-mapping level on the texture
GLint useMipMap;
glGetTexLevelParameteriv(m_TexTarget == GL_TEXTURE_CUBE_MAP_ARB ? GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB : m_TexTarget,1,GL_TEXTURE_WIDTH, &useMipMap);
if (!useMipMap){
GLint minFilter;
glGetTexParameteriv(m_TexTarget, GL_TEXTURE_MIN_FILTER, &minFilter);
if (minFilter >= GL_NEAREST_MIPMAP_NEAREST && minFilter <= GL_LINEAR_MIPMAP_LINEAR)
glTexParameteri(m_TexTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}
GLCHECK();
}
*/
}
GLuint* m_TexIdPtr; // Current Texture Id (reference on TexId of the textureRef in the m_Textures table)
GLuint m_TexId; // Previous Texture Id
GLenum m_TexTarget;// Current Texture target type
// handle of sampler into fragment program for each pass
struct PerTechSamplerInfo
{
// Size = 0 if not used, Size = 1 if per technique or single pass, pass-dependent otherwise
XArray<int> PerPassSamplerStage; // for each pass -> a bitfield giving to what stage that texture is bound (possibly to several stage with fixed pipeline)
};
XClassArray<PerTechSamplerInfo> m_PerTechSamplerInfo;
bool m_UseCGSamplerFallback; // rely on cgGLSetupSampler if some sampler state are unknown or
// dependent on a shader parameter (very unlikely, though, so we don't bother
// to optimize that case)
// Tex parameters for fast sampler setup
GLint m_WrapS;
GLint m_WrapT;
GLint m_WrapR;
GLint m_MinFilter;
GLint m_MagFilter;
GLint m_GenerateMipMap;
bool m_UseBorderColor;
float m_BorderColor[4];
// cg sampler states that we don't handle yet :
// MipFilter (for now, it is unclear to me what mipfilter
// should do given that MagFilter and MinFilter already choose between trilinear and bilinear ... so order matter)
// MipMapLodBias
// LODBias
// SRGBTexture
// MinMipLevel
// MaxMipLevel
// MaxAnisotropy
// DepthMode
// CompareMode
// CompareFunc
};
//--------------------------------------------------------------------------------
// BoundingBoxMax
//--------------------------------------------------------------------------------
class ParamMeaning_BBoxMax : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BBoxMax );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxVector boxMax(0,0,0);
if( iMPI.ent ) boxMax = iMPI.ent->GetBoundingBox( TRUE ).Max;
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &boxMax );
}
};
//--------------------------------------------------------------------------------
// BoundingBoxMin
//--------------------------------------------------------------------------------
class ParamMeaning_BBoxMin : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BBoxMin );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxVector boxMin(0,0,0);
if( iMPI.ent ) boxMin = iMPI.ent->GetBoundingBox( TRUE ).Min;
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &boxMin );
}
};
//--------------------------------------------------------------------------------
// BoundingBoxSize
//--------------------------------------------------------------------------------
class ParamMeaning_BBoxSize : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BBoxSize );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxVector boxSize(0,0,0);
if( iMPI.ent )
boxSize = iMPI.ent->GetBoundingBox( TRUE ).GetSize();
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &boxSize );
}
};
//--------------------------------------------------------------------------------
// BoundingBoxCenter
//--------------------------------------------------------------------------------
class ParamMeaning_BBoxCenter : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BBoxCenter );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxVector boxCenter(0,0,0);
if( iMPI.ent )
boxCenter = iMPI.ent->GetBoundingBox( TRUE ).GetCenter();
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &boxCenter );
}
};
//--------------------------------------------------------------------------------
// BoundingSphereRadius
//--------------------------------------------------------------------------------
class ParamMeaning_BoundingSphereRadius : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BoundingSphereRadius );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float sphereRadius = 0;
if( iMPI.ent ){
CKMesh* mesh = iMPI.ent->GetCurrentMesh();
if( mesh ){
sphereRadius = mesh->GetRadius();
}
}
SetValueByCastingVectorParam( iMPI, sizeof(float), &sphereRadius );
}
};
//--------------------------------------------------------------------------------
// BoundingSphereMax
//--------------------------------------------------------------------------------
class ParamMeaning_BoundingSphereMax : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BoundingSphereMax );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float sphereMax = 0;
if( iMPI.ent )
sphereMax = iMPI.ent->GetBoundingBox( TRUE ).GetHalfSize().Magnitude();
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &sphereMax );
}
};
//--------------------------------------------------------------------------------
// BoundingSphereMin
//--------------------------------------------------------------------------------
class ParamMeaning_BoundingSphereMin : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BoundingSphereMin );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float sphereMin = 0;
if( iMPI.ent )
sphereMin = Min(iMPI.ent->GetBoundingBox( TRUE ).GetHalfSize());
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &sphereMin );
}
};
//--------------------------------------------------------------------------------
// EyePos
//--------------------------------------------------------------------------------
class ParamMeaning_EyePos : public ParamMeaning {
public:
ParamMeaning_EyePos() : m_ReferentialEnum( AnnotStr_Unknown ){}
static Meaning* MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
//--- Here are the Annotations we are interested in
XString annotSpace;
iMII.sdm->ExpectingAnnotation( Annot_Space, AnnotType_String, &annotSpace );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
//--- Space = ?
int annotSpaceStrValueIndex = AnnotStr_Unknown;
if( annotSpace.Length() ){
annotSpaceStrValueIndex = iMII.sdm->GetAnnotStrValueIndexFromString( annotSpace );
}
ParamMeaning_EyePos* inst = new ParamMeaning_EyePos;
inst->m_ReferentialEnum = annotSpaceStrValueIndex;
return inst;
}
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
CK3dEntity* referential = (m_ReferentialEnum == AnnotStr_Local)? iMPI.ent:NULL;
VxVector cameraPos = iMPI.rc->GetViewpoint()->GetWorldMatrix()[3];
if( referential ) referential->InverseTransform( &cameraPos, &cameraPos );
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &cameraPos );
}
int m_ReferentialEnum;
};
//--------------------------------------------------------------------------------
// World
// WorldTranspose
// WorldInverse
// WorldInverseTranspose
//--------------------------------------------------------------------------------
class ParamMeaning_World : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_World );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByMatrix(iMPI,iMPI.rc->GetWorldTransformationMatrix());
}
};
class ParamMeaning_WorldTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByTranposingMatrix( iMPI, iMPI.rc->GetWorldTransformationMatrix() );
}
};
class ParamMeaning_WorldInverse : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldInverse );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByInversingMatrix( iMPI, iMPI.rc->GetWorldTransformationMatrix() );
}
};
class ParamMeaning_WorldInverseTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldInverseTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByInverseTransposingMatrix( iMPI, iMPI.rc->GetWorldTransformationMatrix() );
}
};
//--------------------------------------------------------------------------------
// View
// ViewTranspose
// ViewInverse
// ViewInverseTranspose
//--------------------------------------------------------------------------------
class ParamMeaning_View : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_View );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByMatrix(iMPI,iMPI.rc->GetViewTransformationMatrix());
}
};
class ParamMeaning_ViewTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ViewTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByTranposingMatrix( iMPI, iMPI.rc->GetViewTransformationMatrix() );
}
};
class ParamMeaning_ViewInverse : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ViewInverse );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByInversingMatrix( iMPI, iMPI.rc->GetViewTransformationMatrix() );
}
};
class ParamMeaning_ViewInverseTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ViewInverseTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByInverseTransposingMatrix( iMPI, iMPI.rc->GetViewTransformationMatrix() );
}
};
//--------------------------------------------------------------------------------
// Projection
// ProjectionTranspose
// ProjectionInverse
// ProjectionInverseTranspose
//--------------------------------------------------------------------------------
class ParamMeaning_Projection : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Projection );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// SetValueByMatrix(iMPI,iMPI.rc->GetProjectionTransformationMatrix());
WrapCGSetStateMatrixParameter(iMPI, CG_GL_PROJECTION_MATRIX,
CG_GL_MATRIX_IDENTITY);
}
};
class ParamMeaning_ProjectionTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ProjectionTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// SetValueByTranposingMatrix( iMPI, iMPI.rc->GetProjectionTransformationMatrix() );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_PROJECTION_MATRIX,
CG_GL_MATRIX_TRANSPOSE);
}
};
class ParamMeaning_ProjectionInverse : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ProjectionInverse );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// SetValueByInversingMatrix44( iMPI, iMPI.rc->GetProjectionTransformationMatrix() );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_PROJECTION_MATRIX,
CG_GL_MATRIX_INVERSE);
}
};
class ParamMeaning_ProjectionInverseTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ProjectionInverseTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// SetValueByInverseTransposingMatrix44( iMPI, iMPI.rc->GetProjectionTransformationMatrix() );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_PROJECTION_MATRIX,
CG_GL_MATRIX_INVERSE_TRANSPOSE);
}
};
//--------------------------------------------------------------------------------
// WorldView
// WorldViewTranspose
// WorldViewInverse
// WorldViewInverseTranspose
//--------------------------------------------------------------------------------
class ParamMeaning_WorldView : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldView );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// CKRasterizerContext* rstCtx = iMPI.rc->GetRasterizerContext();
// SetValueByMatrix(iMPI,rstCtx->m_ModelViewMatrix);
WrapCGSetStateMatrixParameter(iMPI, CG_GL_MODELVIEW_MATRIX,
CG_GL_MATRIX_IDENTITY);
}
};
class ParamMeaning_WorldViewTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldViewTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// CKRasterizerContext* rstCtx = iMPI.rc->GetRasterizerContext();
// SetValueByTranposingMatrix( iMPI, rstCtx->m_ModelViewMatrix );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_MODELVIEW_MATRIX,
CG_GL_MATRIX_TRANSPOSE);
}
};
class ParamMeaning_WorldViewInverse : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldViewInverse );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// CKRasterizerContext* rstCtx = iMPI.rc->GetRasterizerContext();
// SetValueByInversingMatrix( iMPI, rstCtx->m_ModelViewMatrix );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_MODELVIEW_MATRIX,
CG_GL_MATRIX_INVERSE);
}
};
class ParamMeaning_WorldViewInverseTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldViewInverseTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// CKRasterizerContext* rstCtx = iMPI.rc->GetRasterizerContext();
// SetValueByInverseTransposingMatrix( iMPI, rstCtx->m_ModelViewMatrix );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_MODELVIEW_MATRIX,
CG_GL_MATRIX_INVERSE_TRANSPOSE);
}
};
//--------------------------------------------------------------------------------
// ViewProjection
// ViewProjectionTranspose
// ViewProjectionInverse
// ViewProjectionInverseTranspose
//--------------------------------------------------------------------------------
class ParamMeaning_ViewProjection : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ViewProjection );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxMatrix vpMatrix;
Vx3DMultiplyMatrix4( vpMatrix, iMPI.rc->GetProjectionTransformationMatrix(), iMPI.rc->GetViewTransformationMatrix() );
SetValueByMatrix(iMPI,vpMatrix);
}
};
class ParamMeaning_ViewProjectionTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ViewProjectionTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxMatrix vpMatrix;
Vx3DMultiplyMatrix4( vpMatrix, iMPI.rc->GetProjectionTransformationMatrix(), iMPI.rc->GetViewTransformationMatrix() );
SetValueByTranposingMatrix( iMPI, vpMatrix );
}
};
class ParamMeaning_ViewProjectionInverse : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ViewProjectionInverse );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxMatrix vpMatrix;
Vx3DMultiplyMatrix4( vpMatrix, iMPI.rc->GetProjectionTransformationMatrix(), iMPI.rc->GetViewTransformationMatrix() );
SetValueByInversingMatrix44( iMPI, vpMatrix );
}
};
class ParamMeaning_ViewProjectionInverseTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ViewProjectionInverseTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxMatrix vpMatrix;
Vx3DMultiplyMatrix4( vpMatrix, iMPI.rc->GetProjectionTransformationMatrix(), iMPI.rc->GetViewTransformationMatrix() );
SetValueByInverseTransposingMatrix44( iMPI, vpMatrix );
}
};
//--------------------------------------------------------------------------------
// WorldViewProjection
// WorldViewProjectionTranspose
// WorldViewProjectionInverse
// WorldViewProjectionInverseTranspose
//--------------------------------------------------------------------------------
class ParamMeaning_WorldViewProjection : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldViewProjection );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
//CKRasterizerContext* rstCtx = iMPI.rc->GetRasterizerContext();
//SetValueByMatrix(iMPI,rstCtx->m_TotalMatrix);
WrapCGSetStateMatrixParameter(iMPI, CG_GL_MODELVIEW_PROJECTION_MATRIX,
CG_GL_MATRIX_IDENTITY);
}
};
class ParamMeaning_WorldViewProjectionTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldViewProjectionTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// CKRasterizerContext* rstCtx = iMPI.rc->GetRasterizerContext();
// SetValueByTranposingMatrix( iMPI, rstCtx->m_TotalMatrix );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_MODELVIEW_PROJECTION_MATRIX,
CG_GL_MATRIX_TRANSPOSE);
}
};
class ParamMeaning_WorldViewProjectionInverse : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldViewProjectionInverse );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// CKRasterizerContext* rstCtx = iMPI.rc->GetRasterizerContext();
// SetValueByInversingMatrix44( iMPI, rstCtx->m_TotalMatrix );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_MODELVIEW_PROJECTION_MATRIX,
CG_GL_MATRIX_INVERSE);
}
};
class ParamMeaning_WorldViewProjectionInverseTranspose : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_WorldViewProjectionInverseTranspose );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// CKRasterizerContext* rstCtx = iMPI.rc->GetRasterizerContext();
// SetValueByInverseTransposingMatrix44( iMPI, rstCtx->m_TotalMatrix );
WrapCGSetStateMatrixParameter(iMPI, CG_GL_MODELVIEW_PROJECTION_MATRIX,
CG_GL_MATRIX_INVERSE_TRANSPOSE);
}
};
//--------------------------------------------------------------------------------
// ObjectPos
//--------------------------------------------------------------------------------
class ParamMeaning_ObjectPos : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ObjectPos );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
SetValueByCastingVectorParam( iMPI, sizeof(VxVector), &iMPI.rc->GetWorldTransformationMatrix()[3] );
}
};
//--------------------------------------------------------------------------------
// Time
//--------------------------------------------------------------------------------
class ParamMeaning_Time : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Time );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
CKTimeManager* tm = iMPI.rc->GetCKContext()->GetTimeManager();
const float time = tm->GetAbsoluteTime()*0.001f;
//#if defined(_XBOX) && (_XBOX_VER<200)
// D3DXVECTOR4 v;
// v.x = time;
// v.y = sinf(time);
// v.z = cosf(time);
// v.w = 1.0f;
// iMPI.fx->SetVector( m_D3DHandle, &v);
//#else
WrapCGSetParameter1f(iMPI, time);
TouchDependentRenderStates(iMPI);
//iMPI.fx->SetFloat( m_D3DHandle, time);
//#endif
}
};
//--------------------------------------------------------------------------------
// ElapsedTime
//--------------------------------------------------------------------------------
class ParamMeaning_ElapsedTime : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ElapsedTime );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
CKTimeManager* tm = iMPI.rc->GetCKContext()->GetTimeManager();
float elapsedTime = tm->GetLastDeltaTime()*0.001f;
WrapCGSetParameter1f(iMPI, elapsedTime);
TouchDependentRenderStates(iMPI);
//iMPI.fx->SetFloat( m_D3DHandle, elapsedTime );
}
};
//--------------------------------------------------------------------------------
// LastTime
//--------------------------------------------------------------------------------
class ParamMeaning_LastTime : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_LastTime );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
CKTimeManager* tm = iMPI.rc->GetCKContext()->GetTimeManager();
float lastTime = (tm->GetAbsoluteTime()-tm->GetLastDeltaTime())*0.001f;
WrapCGSetParameter1f(iMPI, lastTime);
TouchDependentRenderStates(iMPI);
//iMPI.fx->SetFloat( m_D3DHandle, lastTime);
}
};
//--------------------------------------------------------------------------------
// ViewportPixelSize
//--------------------------------------------------------------------------------
class ParamMeaning_ViewportPixelSize : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ViewportPixelSize );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxRect rect;
iMPI.rc->GetViewRect( rect );
#ifdef macintosh
Vx2DVector BottomRight(rect.right,rect.bottom);
SetValueByCastingVectorParam( iMPI, sizeof(Vx2DVector), &BottomRight );
#else
SetValueByCastingVectorParam( iMPI, sizeof(Vx2DVector), &rect.m_BottomRight );
#endif
}
};
//--------------------------------------------------------------------------------
// Random
//--------------------------------------------------------------------------------
class ParamMeaning_Random : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Random );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
float randomValue = (float)rand()/(float)RAND_MAX;
WrapCGSetParameter1f(iMPI, randomValue);
TouchDependentRenderStates(iMPI);
//iMPI.fx->SetFloat( m_D3DHandle, randomValue);
}
};
//--------------------------------------------------------------------------------
// BonesPerVertex
//--------------------------------------------------------------------------------
class ParamMeaning_BonesPerVertex : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BonesPerVertex );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
if( !iMPI.ent ) return;
if( !(iMPI.ent->GetFlags()&CK_3DENTITY_HWSKINING) ) return;
CKSkin* sk = iMPI.ent->GetSkin();
if( !sk ) return;
int bonesPerVertex = sk->GetMaxBonesPerVertex();
WrapCGSetParameter1i(iMPI, bonesPerVertex);
//iMPI.fx->SetInt( m_D3DHandle, bonesPerVertex);
}
};
//--------------------------------------------------------------------------------
// Bones
//--------------------------------------------------------------------------------
class ParamMeaning_Bones : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_Bones );
void SetBonesInCG(const MeaningProcessingInfo& iMPI, bool transposed)
{
if( !iMPI.ent ) return;
if( !(iMPI.ent->GetFlags()&CK_3DENTITY_HWSKINING) ) return;
CKSkin* sk = iMPI.ent->GetSkin();
if( !sk )
return;
//iMPI.fx->SetMatrixArray( m_D3DHandle, (const D3DXMATRIX*)sk->GetTransformedBonesArray(), (sk->GetBoneCount()+1) );
if( m_NumRows <= 0 || m_NumCols < 0) return;
int boneCount = XMin(sk->GetBoneCount() + 1, m_NumBones); // + 1 for object matrix at the end
if (boneCount <= 0) return;
//
WrapCGSetMatrixParameterArray(iMPI, sk->GetTransformedBonesArray(), boneCount, transposed);
}
void ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
SetBonesInCG(iMPI, false); // Row-major order to mimic previous code behavior (same than direct 3D)
// As a matter of fact, some people may have been successful at using it
// when using bones as 4x4 matrix in cg
// (old code relied on cgGLSetMatrixParameterArrayfr)
}
virtual void PostIntantiationCallBack( const MeaningInstantiatorInfo& iMPI )
{
ParamMeaning::PostIntantiationCallBack(iMPI);
m_NumBones = 0;
CGtype matrixType = cgGetParameterType(m_ParamDesc);
if (matrixType == CG_ARRAY)
{
if (cgGetArrayDimension(m_ParamDesc) == 1)
{
m_NumBones = cgGetArraySize(m_ParamDesc, 0);
}
}
}
int m_NumBones;
};
//--------------------------------------------------------------------------------
// TBones
//--------------------------------------------------------------------------------
class ParamMeaning_TBones : public ParamMeaning_Bones {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_TBones );
void ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
SetBonesInCG(iMPI, true); // Row-major order to mimic previous code behavior (same than direct 3D)
// As a matter of fact, some people may have been successful at using it
// when using bones as 4x4 matrix in cg
// (old code relied on cgGLSetMatrixParameterArrayfr)
}
};
//--------------------------------------------------------------------------------
// RBones
//--------------------------------------------------------------------------------
//class ParamMeaning_RBones : public ParamMeaning {
//public:
// CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_RBones );
// void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
//
//#if defined(_XBOX) && (_XBOX_VER<200)
// gRestoreConstantMode = TRUE;
// D3DDevice::SetShaderConstantMode(D3DSCM_192CONSTANTS);
//#endif
// if( !iMPI.ent )
// return;
//
// if( !(iMPI.ent->GetFlags()&CK_3DENTITY_HWSKINING) )
// return;
//
// CKSkin* sk = iMPI.ent->GetSkin();
// if( !sk ) return;
// const VxMatrix* buffer = sk->GetTransformedBonesArray();
// int index = 0;
// //iMPI.fx->GetInt( m_D3DHandle, &index );
// cgGetParameterValueic(m_ParamDesc, 1, &index);
//
// VxDirectXData* dx = iMPI.rc->GetDirectXInfo();
// DXDEVICE* dev = (DXDEVICE*) dx->D3DDevice;
// VxMatrix matrix;
// const DWORD boneCount = sk->GetBoneCount();
// for( DWORD i=0 ; i<boneCount ; i++ ){
//
//#if DIRECT3D_VERSION<0x0900
// dev->SetVertexShaderConstantF( index+3*i, buffer[i], 3 );
//#else
// D3DXMatrixTranspose( &matrix, (const D3DXMATRIX *)(((BYTE*)buffer)+i*sizeof(VxMatrix)) );
// dev->SetVertexShaderConstantF( index+3*i, matrix, 3 );
//#endif
// }
// }
//};
//--------------------------------------------------------------------------------
// RTBones
//--------------------------------------------------------------------------------
//class ParamMeaning_RTBones : public ParamMeaning {
//public:
// CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_RTBones );
// void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
//
//#if defined(_XBOX) && _XBOX_VER<200
// gRestoreConstantMode = TRUE;
// D3DDevice::SetShaderConstantMode(D3DSCM_192CONSTANTS);
//#endif
//
// if( !iMPI.ent )
// return;
//
// if( !(iMPI.ent->GetFlags()&CK_3DENTITY_HWSKINING) )
// return;
//
// CKSkin* sk = iMPI.ent->GetSkin();
// if( !sk ) return;
// const D3DXMATRIX* buffer = (const D3DXMATRIX*)sk->GetTransformedBonesArray();
// int index = 0;
// //iMPI.fx->GetInt( m_D3DHandle, &index );
// cgGetParameterValueic(m_ParamDesc, 1, &index);
//
// VxDirectXData* dx = iMPI.rc->GetDirectXInfo();
// DXDEVICE* dev = (DXDEVICE*) dx->D3DDevice;
// D3DXMATRIX matrix;
// const DWORD boneCount = sk->GetBoneCount();
// for( DWORD i=0 ; i<boneCount ; i++ ){
//
//#if DIRECT3D_VERSION<0x0900
// dev->SetVertexShaderConstantF( index+3*i, buffer[i], 3 );
//#else
// D3DXMatrixTranspose( &matrix, (const D3DXMATRIX *)(((BYTE*)buffer)+i*sizeof(VxMatrix)) );
// dev->SetVertexShaderConstantF( index+3*i, matrix, 3 );
//#endif
// }
// }
//};
//#if defined(_XBOX) && _XBOX_VER<200
//class ParamMeaning_BonesIndexConstant : public ParamMeaning {
//public:
// CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_BonesIndexConstant );
// void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
// DWORD idx = 0;
// iMPI.fx->GetDword(m_D3DHandle,&idx);
// XGVECTOR4 v(255.002f,0.0f,0.0f,0.0f);
// D3DDevice::SetVertexShaderConstantFast(idx,&v,1);
// }
//};
//#endif
//--------------------------------------------------------------------------------
// PassCount
//--------------------------------------------------------------------------------
class ParamMeaning_PassCount : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_PassCount );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
//#ifdef XBOX1
// iMPI.fx->SetFloat( m_D3DHandle, (float) iMPI.rc->m_ShaderManager->m_CurrentPassCount);
//#else
//iMPI.fx->SetInt( m_D3DHandle, iMPI.rc->m_ShaderManager->m_CurrentPassCount);
WrapCGSetParameter1i(iMPI, iMPI.rc->m_ShaderManager->m_CurrentPassCount);
//#endif
}
};
//--------------------------------------------------------------------------------
// PassIndex
//--------------------------------------------------------------------------------
class ParamMeaning_PassIndex : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_PassIndex );
void PostIntantiationCallBack( const MeaningInstantiatorInfo& iMII )
{
ParamMeaning::PostIntantiationCallBack( iMII );
m_ExpositionType = ExpositionType_AutomaticPerPass;
}
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
//#ifdef XBOX1
// iMPI.fx->SetFloat( m_D3DHandle, (float) iMPI.rc->m_ShaderManager->m_CurrentPassIndex);
//#else
//iMPI.fx->SetInt( m_D3DHandle, iMPI.rc->m_ShaderManager->m_CurrentPassIndex);
WrapCGSetParameter1i(iMPI, iMPI.rc->m_ShaderManager->m_CurrentPassIndex);
//#endif
}
};
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
//--------------------------------------------------------------------------------
// LightCount
//--------------------------------------------------------------------------------
class ParamMeaning_LightCount : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_LightCount );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
ManagerCG* sdm = iMPI.shader->GetManager();
CKShaderManager* shaderMan = sdm->GetShaderManager();
//--- Retrieve lights array
XArray< CKShaderManager::NearestLight >& nearestLights =
*shaderMan->GetNearestLights( iMPI.ent, INT_MAX, false );
int lightCount = ( &nearestLights )? nearestLights.Size():0;
//iMPI.fx->SetInt( m_D3DHandle, lightCount );
WrapCGSetParameter1i(iMPI, lightCount);
}
};
//--------------------------------------------------------------------------------
// Activity NearestLight
//--------------------------------------------------------------------------------
class ParamMeaning_ActivityNearestLight : public ParamMeaning_NearestLight {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ActivityNearestLight );
//-----------------------------------------------------------------------------
virtual int GiveStride( const MeaningProcessingInfo& iMPI ){
//return sizeof(DWORD);
return sizeof(CKBOOL);
}
//-----------------------------------------------------------------------------
virtual void GiveDefaultValues( const MeaningProcessingInfo& iMPI, void* iTempBuffer, int iFinalArrayCount ){
//--- By Default Fill Temp Array With Default Activity
for( int a=0 ; a<iFinalArrayCount ; ++a ){
((CKBOOL*)iTempBuffer)[a] = m_DefaultActivity;
}
}
//-----------------------------------------------------------------------------
virtual void GiveValue( const MeaningProcessingInfo& iMPI, CKLight& iLight, void* iValueBuf ){
*(CKBOOL*)iValueBuf = 0;
if( iLight.IsVisible() && iLight.GetActivity() ){
*(CKBOOL*)iValueBuf = 1;
}
}
//-----------------------------------------------------------------------------
virtual void AssignValues( const MeaningProcessingInfo& iMPI, void* iValueBuf, const int iElemCount )
{
if (iElemCount) { // Is an Array
WrapCGSetParameterArray1f(iMPI, (const float*)iValueBuf, iElemCount);
}
else {
WrapCGSetParameter1i(iMPI, *(CKBOOL*)iValueBuf);
}
TouchDependentRenderStates(iMPI);
}
//DWORD m_DefaultActivity;
CKBOOL m_DefaultActivity;
};
//--------------------------------------------------------------------------------
// Position NearestLight
//--------------------------------------------------------------------------------
class ParamMeaning_PositionNearestLight : public ParamMeaning_NearestLight {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_PositionNearestLight );
ParamMeaning_PositionNearestLight() :
m_ReferentialEnum( AnnotStr_Unknown ),m_Referential( NULL ),m_DirectionalLightScaleHack(0){}
//-----------------------------------------------------------------------------
virtual int GiveStride( const MeaningProcessingInfo& iMPI ){
return sizeof(VxVector);
}
//-----------------------------------------------------------------------------
virtual void GiveDefaultValues( const MeaningProcessingInfo& iMPI, void* iTempBuffer, int iFinalArrayCount ){
//--- Get referential in which to retrieve light information
m_Referential = (m_ReferentialEnum == AnnotStr_Local)? iMPI.ent:NULL;
//--- By Default Fill Temp Array With Current Camera Information
VxVector cameraPos = iMPI.rc->GetViewpoint()->GetWorldMatrix()[3];
if( m_Referential ) m_Referential->InverseTransform( &cameraPos, &cameraPos );
for( int a=0 ; a<iFinalArrayCount ; ++a ){
((VxVector*)iTempBuffer)[a] = cameraPos;
}
}
//-----------------------------------------------------------------------------
virtual void GiveValue( const MeaningProcessingInfo& iMPI, CKLight& iLight, void* iValueBuf ){
iLight.GetPosition( (VxVector*)iValueBuf, m_Referential );
if( iLight.GetType() == VX_LIGHTDIREC && m_DirectionalLightScaleHack < 0)
*((VxVector*)iValueBuf) = iLight.GetWorldMatrix()[2] * m_DirectionalLightScaleHack;
}
//-----------------------------------------------------------------------------
virtual void AssignValues( const MeaningProcessingInfo& iMPI, void* iValueBuf, const int iElemCount )
{
if (iElemCount) { // Is an Array
WrapCGSetParameterArray3f(iMPI, (const float*)iValueBuf, iElemCount);
}
else {
WrapCGSetParameter3fv(iMPI, (const float*)iValueBuf);
}
TouchDependentRenderStates(iMPI);
}
float m_DirectionalLightScaleHack;
int m_ReferentialEnum;
CK3dEntity* m_Referential;
};
//--------------------------------------------------------------------------------
// Matrix NearestLight
//--------------------------------------------------------------------------------
class ParamMeaning_MatrixNearestLight : public ParamMeaning_NearestLight {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_MatrixNearestLight );
ParamMeaning_MatrixNearestLight() :
m_ReferentialEnum( AnnotStr_Unknown ),m_Referential( NULL ){}
//-----------------------------------------------------------------------------
virtual int GiveStride( const MeaningProcessingInfo& iMPI ){
return sizeof(VxMatrix);
}
//-----------------------------------------------------------------------------
virtual void GiveDefaultValues( const MeaningProcessingInfo& iMPI, void* iTempBuffer, int iFinalArrayCount ){
//--- Get referential in which to retrieve light information
m_Referential = (m_ReferentialEnum == AnnotStr_Local)? iMPI.ent:NULL;
//--- By Default Fill Temp Array With Current Camera Information
VxMatrix cameraMat;
if( m_Referential ){
Vx3DMultiplyMatrix( cameraMat, m_Referential->GetInverseWorldMatrix(), iMPI.rc->GetViewpoint()->GetWorldMatrix() );
} else {
cameraMat = iMPI.rc->GetViewpoint()->GetWorldMatrix();
}
for( int a=0 ; a<iFinalArrayCount ; ++a ){
((VxMatrix*)iTempBuffer)[a] = cameraMat;
}
}
//-----------------------------------------------------------------------------
virtual void GiveValue( const MeaningProcessingInfo& iMPI, CKLight& iLight, void* iValueBuf ){
if( m_Referential ){
Vx3DMultiplyMatrix( *(VxMatrix*)iValueBuf, m_Referential->GetInverseWorldMatrix(), iLight.GetWorldMatrix() );
} else {
*(VxMatrix*)iValueBuf = iLight.GetWorldMatrix();
}
}
//-----------------------------------------------------------------------------
virtual void AssignValues( const MeaningProcessingInfo& iMPI, void* iValueBuf, const int iElemCount )
{
if (iElemCount) { // Is an Array
//iMPI.fx->SetMatrixArray( m_D3DHandle, (D3DXMATRIX*)iValueBuf, iElemCount );
WrapCGSetMatrixParameterArray(iMPI, (const VxMatrix*)iValueBuf, iElemCount, false /* transposed */);
}
else {
WrapCGSetMatrixParameter(iMPI, *(const VxMatrix *) iValueBuf);
}
}
int m_ReferentialEnum;
CK3dEntity* m_Referential;
};
//--------------------------------------------------------------------------------
// Color NearestLight
//--------------------------------------------------------------------------------
class ParamMeaning_ColorNearestLight : public ParamMeaning_NearestLight {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_ColorNearestLight );
//-----------------------------------------------------------------------------
virtual int GiveStride( const MeaningProcessingInfo& iMPI ){
return sizeof(VxColor);
}
//-----------------------------------------------------------------------------
virtual void GiveDefaultValues( const MeaningProcessingInfo& iMPI, void* iTempBuffer, int iFinalArrayCount ){
for( int a=0 ; a<iFinalArrayCount ; ++a ){
((VxColor*)iTempBuffer)[a] = m_DefaultColor;
}
}
//-----------------------------------------------------------------------------
virtual void GiveValue( const MeaningProcessingInfo& iMPI, CKLight& iLight, void* iValueBuf ){
*(VxColor*)iValueBuf = iLight.GetColor();
}
//-----------------------------------------------------------------------------
virtual void AssignValues( const MeaningProcessingInfo& iMPI, void* iValueBuf, const int iElemCount )
{
if (iElemCount) { // Is an Array
WrapCGSetParameterArray4f(iMPI, (const float*)iValueBuf, iElemCount);
}
else {
WrapCGSetParameter4fv(iMPI, (float*)iValueBuf);
}
TouchDependentRenderStates(iMPI);
}
VxColor m_DefaultColor;
};
//--------------------------------------------------------------------------------
// Range NearestLight
//--------------------------------------------------------------------------------
class ParamMeaning_RangeNearestLight : public ParamMeaning_NearestLight {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_RangeNearestLight );
//-----------------------------------------------------------------------------
virtual int GiveStride( const MeaningProcessingInfo& iMPI ){
return sizeof(float);
}
//-----------------------------------------------------------------------------
virtual void GiveDefaultValues( const MeaningProcessingInfo& iMPI, void* iTempBuffer, int iFinalArrayCount ){
for( int a=0 ; a<iFinalArrayCount ; ++a ){
((float*)iTempBuffer)[a] = m_DefaultRange;
}
}
//-----------------------------------------------------------------------------
virtual void GiveValue( const MeaningProcessingInfo& iMPI, CKLight& iLight, void* iValueBuf ){
*(VxColor*)iValueBuf = iLight.GetRange();
}
//-----------------------------------------------------------------------------
virtual void AssignValues( const MeaningProcessingInfo& iMPI, void* iValueBuf, const int iElemCount )
{
if (iElemCount) { // Is an Array
WrapCGSetParameterArray1f(iMPI, (float*)iValueBuf, iElemCount);
}
else {
WrapCGSetParameter1f(iMPI, *(float*)iValueBuf);
}
TouchDependentRenderStates(iMPI);
}
float m_DefaultRange;
};
//--------------------------------------------------------------------------------
// NearestLight (Switcher to derive from)
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
Meaning*
ParamMeaning_NearestLight::MeaningInstantiator( const MeaningInstantiatorInfo& iMII )
{
//--- Here are the Annotations we are interested in
int nearestIndex = 0;
iMII.sdm->ExpectingAnnotation( Annot_Nearest, AnnotType_Int, &nearestIndex );
bool annotSort = true;
iMII.sdm->ExpectingAnnotation( Annot_Sort, AnnotType_Bool, &annotSort );
float annotDefaultRange = 200.0f;
iMII.sdm->ExpectingAnnotation( Annot_Default, AnnotType_Float, &annotDefaultRange );
VxColor annotDefaultColor(0,0,0,1);
iMII.sdm->ExpectingAnnotation( Annot_Default, AnnotType_Vector4, &annotDefaultColor );
bool annotDefaultActivity = false;
iMII.sdm->ExpectingAnnotation( Annot_Default, AnnotType_Bool, &annotDefaultActivity );
XString annotSpace;
iMII.sdm->ExpectingAnnotation( Annot_Space, AnnotType_String, &annotSpace );
bool annotDirectionalHack = false;
iMII.sdm->ExpectingAnnotation( Annot_DirectionalLightHack, AnnotType_Bool, &annotDirectionalHack );
float annotDirectionalScaleHack = 1.f;
iMII.sdm->ExpectingAnnotation( Annot_DirectionalLightHack, AnnotType_Float, &annotDirectionalScaleHack );
//--- Parse Annotations to find expected ones
iMII.sdm->ParseExpectedAnnotations( iMII.fx, cgGetFirstParameterAnnotation(iMII.paramDesc) );
//--- Space = ?
int annotSpaceStrValueIndex = AnnotStr_Unknown;
if( annotSpace.Length() ){
annotSpaceStrValueIndex = iMII.sdm->GetAnnotStrValueIndexFromString( annotSpace );
}
//--- Depending on the Parameter Type, switch to the correct Meaning
int lightArraySize = 1;
ParamMeaning_NearestLight* inst = NULL;
CGparameterclass pClassType = cgGetParameterClass( iMII.paramDesc );
CGtype pBaseType = cgGetParameterBaseType( iMII.paramDesc );
int ColSize = cgGetParameterColumns( iMII.paramDesc );
int elements = cgGetArrayTotalSize( iMII.paramDesc );
//--- We Only Deal With FLOAT, or BOOL (see at bottom)
if( pBaseType == CG_FLOAT ){
//--- Set Wanted Light Array Size if more than 1 Element
if( elements > 1){
CGparameter param = cgGetArrayParameter(iMII.paramDesc,0);
pClassType = cgGetParameterClass(param);
lightArraySize = elements;
nearestIndex = 0;
}
switch( pClassType )
{
//--- float
case CG_PARAMETERCLASS_SCALAR:
inst = (ParamMeaning_NearestLight*)Instantiate_MeaningCG( ParamMeaning_RangeNearestLight, iMII );
((ParamMeaning_RangeNearestLight*)inst)->m_DefaultRange = annotDefaultRange;
break;
//--- float4x4
case CG_PARAMETERCLASS_MATRIX:
inst = (ParamMeaning_NearestLight*)Instantiate_MeaningCG( ParamMeaning_MatrixNearestLight, iMII );
((ParamMeaning_MatrixNearestLight*)inst)->m_ReferentialEnum = annotSpaceStrValueIndex;
break;
case CG_PARAMETERCLASS_VECTOR:
{
switch( ColSize )
{
//--- float
case 1:
inst = (ParamMeaning_NearestLight*)Instantiate_MeaningCG( ParamMeaning_RangeNearestLight, iMII );
((ParamMeaning_RangeNearestLight*)inst)->m_DefaultRange = annotDefaultRange;
break;
//--- float4
case 4:
inst = (ParamMeaning_NearestLight*)Instantiate_MeaningCG( ParamMeaning_ColorNearestLight, iMII );
((ParamMeaning_ColorNearestLight*)inst)->m_DefaultColor = annotDefaultColor;
break;
//--- float3
default:
inst = (ParamMeaning_NearestLight*)Instantiate_MeaningCG( ParamMeaning_PositionNearestLight, iMII );
((ParamMeaning_PositionNearestLight*)inst)->m_ReferentialEnum = annotSpaceStrValueIndex;
if ( annotDirectionalHack )
{
if (annotDirectionalScaleHack < 1.f)
annotDirectionalScaleHack = 1.f;
((ParamMeaning_PositionNearestLight*)inst)->m_DirectionalLightScaleHack = -10000000.f * annotDirectionalScaleHack;
}
else
((ParamMeaning_PositionNearestLight*)inst)->m_DirectionalLightScaleHack = 0;
break;
}
}
break;
}
}
else if( pBaseType == CG_BOOL ){
//--- Set Wanted Light Array Size if more than 1 Element
if( elements > 1){
lightArraySize = elements;
nearestIndex = 0;
}
inst = (ParamMeaning_NearestLight*)Instantiate_MeaningCG( ParamMeaning_ActivityNearestLight, iMII );
((ParamMeaning_ActivityNearestLight*)inst)->m_DefaultActivity = annotDefaultActivity? 1:0;
}
if( !inst ) return NULL;
inst->m_WantedLightArraySize = lightArraySize;
inst->m_NearestIndex = nearestIndex;
inst->m_Sort = annotSort;
return inst;
}
//--------------------------------------------------------------------------------
void
ParamMeaning_NearestLight::ProcessCallBack( const MeaningProcessingInfo& iMPI )
{
int arrayCount = cgGetArrayTotalSize( m_ParamDesc );
int elements = arrayCount ? arrayCount : 1;
bool valuesModified = false;
//--- Prepare final array
const int stride = GiveStride( iMPI );
const int bytesCount = elements*stride;
if (bytesCount > m_CachedValues.Size())
{
m_CachedValues.Resize(bytesCount);
m_CachedValues.Fill(0);
valuesModified = true;
}
VxScratch tempScratch( bytesCount );
void* tempBuffer = tempScratch.Mem();
//--- Get Nearest Lights Array and Range
int minLightIndex, maxLightIndex;
XArray< CKShaderManager::NearestLight >& nearestLights =
*_GetLightsArrayRange( iMPI, minLightIndex, maxLightIndex, m_Sort );
//--- By Default Fill Temp Array With Default Values
GiveDefaultValues( iMPI, tempBuffer, elements );
//--- Fill Temp Array With Interesting Information From Valid Lights
if( &nearestLights ){
int nearestLightIndex = minLightIndex;
BYTE* valuePtr = (BYTE*)tempBuffer;
BYTE *cacheValuePtr = &m_CachedValues[0];
for( int a=0 ; a<elements ; ++a, ++nearestLightIndex, valuePtr += stride, cacheValuePtr += stride){
//--- Break If we try to reach a light index greater than valid lights
if( nearestLightIndex > maxLightIndex ) break;
//--- Otherwise Get Information from the light indexed
CK_ID lightID = nearestLights[nearestLightIndex].lightID;
CKLight* light = (CKLight*)iMPI.rc->GetCKContext()->GetObject( lightID );
if( !light ) continue;
GiveValue( iMPI, *light, valuePtr );
if (!valuesModified)
{
if (memcmp(cacheValuePtr, valuePtr, stride) != 0)
{
memcpy(cacheValuePtr, valuePtr, stride); // update cache
valuesModified = true;
}
}
}
}
if ((!ParamMeaningLightCaching) ||
m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex].m_ForceUseCGSetParameter ||
valuesModified)
{
//--- Put Relevant Information in the Final Buffer
AssignValues( iMPI, tempBuffer, arrayCount );
}
}
//--------------------------------------------------------------------------------
void
ParamMeaning_NearestLight::AssignValues( const MeaningProcessingInfo& iMPI, void* iValueBuf, const int iElemCount )
{
//iMPI.fx->SetValue( m_D3DHandle, iValueBuf, m_ParamDesc.Bytes );
const char* name = cgGetParameterName(m_ParamDesc);
//cgGLEnableClientState( m_ParamDesc );
// cgGLSetParameterPointer(m_ParamDesc, /*iElemCount*/3, /*GL_UNSIGNED_BYTE*/GL_FLOAT, /*GiveStride( iMPI )*/0, (float*)iValueBuf);
WrapCGSetParameter3fv(iMPI, (float*)iValueBuf);
TouchDependentRenderStates(iMPI);
// cgSetParameterValuefr(m_ParamDesc, iElemCount, (float*)iValueBuf);
}
//--------------------------------------------------------------------------------
// Get Lights Array Range
//
// Convenient function to retrieve lights array
// Note: This function is Used by different light meanings
//
XArray< CKShaderManager::NearestLight >*
ParamMeaning_NearestLight::_GetLightsArrayRange( const MeaningProcessingInfo& iMPI,
int& oMinLightIndex,
int& oMaxLightIndex,
bool iSort )
{
ManagerCG* sdm = iMPI.shader->GetManager();
CKShaderManager* shaderMan = sdm->GetShaderManager();
//--- Retrieve lights array
int minLightIndex = m_NearestIndex;
int maxLightIndex = XMax( m_WantedLightArraySize-1, m_NearestIndex );
XArray< CKShaderManager::NearestLight >& nearestLights =
*shaderMan->GetNearestLights( iMPI.ent, maxLightIndex+1, iSort );
if( !&nearestLights ) return NULL;
//--- in case there's not enough lights in the scene to fill the destination array,
///// majorate maxLightIndex to the real count
maxLightIndex = XMin( maxLightIndex, nearestLights.Size()-1 );
if( maxLightIndex < minLightIndex ) return NULL;
oMinLightIndex = minLightIndex;
oMaxLightIndex = maxLightIndex;
return &nearestLights;
}
#endif
//--------------------------------------------------------------------------------
// Global Ambient
//--------------------------------------------------------------------------------
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
class ParamMeaning_GlobalAmbient : public ParamMeaning {
public:
CLASSIC_INSTANTIATOR_DEF_INSIDE_CG( ParamMeaning_GlobalAmbient );
void ProcessCallBack( const MeaningProcessingInfo& iMPI ){
VxColor col = iMPI.rc->GetAmbientLight();
SetValueByCastingVectorParam( iMPI, sizeof(VxColor), &col );
}
};
#endif
/***************************************************************************
____ _ _
/ ___|| |__ __ _ __| | ___ _ __
\___ \| '_ \ / _` |/ _` |/ _ \ '__|
___) | | | | (_| | (_| | __/ |
|____/|_| |_|\__,_|\__,_|\___|_|
***************************************************************************/
//--------------------------------------------------------------------------------
ShaderCG::ShaderCG()
{
m_SDM = NULL;
m_FX = NULL;
m_RC = NULL;
m_Shader = NULL;
}
//--------------------------------------------------------------------------------
void
ShaderCG::Init( ManagerCG* iShaderManager, CGeffect iDxFX, CKRenderContext* iRC, CKShader* iShader )
{
m_SDM = iShaderManager;
m_FX = iDxFX;
m_RC = iRC;
m_Shader = iShader;
BuildDescription();
}
//--------------------------------------------------------------------------------
ShaderCG::~ShaderCG()
{
DestroyDescription();
}
//--------------------------------------------------------------------------------
void
ShaderCG::BuildDescription()
{
//--- Make sure everything is cleared before we build the description
DestroyDescription();
// D3DXEFFECT_DESC shaderDesc;
// m_FX->GetDesc( &shaderDesc );
MeaningInstantiatorInfo mii( m_FX, m_SDM, this );
// Count the number of technique in that effect
mii.techniqueCount = ShaderManagerCG::GetCGEffectTechniqueCount(m_FX);
m_PerTechniquePerPassSamplers.Resize(mii.techniqueCount);
//--- Parse all Parameters
CGparameter currentParam = cgGetFirstEffectParameter(m_FX);
int paramIndex = 0;
while( currentParam != NULL ){
mii.paramIndex = paramIndex;
//#if DIRECT3D_VERSION<0x0900
// mii.h = paramIndex;
//#else
// mii.h = m_FX->GetParameter( NULL, paramIndex );
//#endif
mii.paramDesc = currentParam;
ParamMeaning* paramMeaning = BuildParamMeaning( mii );
if( paramMeaning ){
paramMeaning->m_PerTechniquePerPassConstantSetup.Resize(mii.techniqueCount);
m_CGParamToMeaning.Insert(currentParam, paramMeaning);
//-- per pass samplers
if (paramMeaning->IsSampler())
{
for (int techIndex = 0; techIndex < mii.techniqueCount; ++techIndex)
{
if (paramMeaning->IsPassDependantSampler(techIndex))
{
m_PerTechniquePerPassSamplers[techIndex].PushBack(paramMeaning);
}
}
}
//--- Exposed Params
if( paramMeaning->m_ExpositionType == ExpositionType_Exposed ){
//--- Exposed Param Meanings
m_ExposedParams.PushBack( (ExposedParamMeaning*)paramMeaning );
//--- Store meaning also in a hash to get it by name
m_ParamMeaningFromName.Insert( cgGetParameterName(paramMeaning->m_ParamDesc), (ExposedParamMeaning*)paramMeaning );
}
//--- Automatic Params
else {
//--- Automatic Param Meanings Per Pass
if( paramMeaning->m_ExpositionType == ExpositionType_AutomaticPerPass ){
m_ParamsPerPass.PushBack( paramMeaning );
}
//--- Automatic Param Meanings
else {
m_Params.PushBack( paramMeaning );
}
}
} else {
//... TODO: Print Message "Can't find meaning for parameter"
}
currentParam = cgGetNextParameter(currentParam);
++paramIndex;
}
// link Sampler and Textures
int samplerNum = m_Samplers.Size();
for (int i = 0 ; i < samplerNum ; i++) {
const char* texname = m_Samplers[i].TexName.CStr();
textureRef* tex = m_Textures.FindPtr(texname);
if(tex) {
*(m_Samplers[i].TexIdPtrPtr) = &(tex->TexId);
if(tex->TexIdPtrPtr) // exposed texture parameter (or default virtools texture)
*(tex->TexIdPtrPtr) = &(tex->TexId);
}
}
m_Samplers.Clear();
//#if DIRECT3D_VERSION>=0x0900
// //--- Parse all Functions
// for( UINT fctIndex=0 ; fctIndex < shaderDesc.Functions ; ++fctIndex ){
//
// mii.functionIndex = paramIndex;
// mii.h = m_FX->GetFunction( fctIndex );
//
// FctMeaning* fctMeaning = BuildFctMeaning( mii );
//
// if( fctMeaning ){
//
// //--- Function Meaning
// m_Functs.PushBack( fctMeaning );
//
// //--- Store meaning also in a hash to get it by name
// m_FctMeaningFromName.Insert( fctMeaning->m_FunctionDesc.Name, (FctMeaning*)fctMeaning );
//
// } else {
// XASSERT(FALSE);
// //... TODO: Print Message "Can't find meaning for funtion"
// }
// }
//#endif
//--- Parse all Techniques
CGtechnique currentTech = cgGetFirstTechnique(m_FX);
int techIndex = 0;
while(currentTech != NULL)
{
mii.techIndex = techIndex;//paramIndex;
mii.techDesc = currentTech;
//#if DIRECT3D_VERSION<0x0900
// mii.h = techIndex;
//#else
// D3DXHANDLE techHandle = m_FX->GetTechnique( techIndex );
// mii.h = techHandle;
//#endif
TechMeaning* techMeaning = BuildTechMeaning( mii );
if( techMeaning ){
//--- Tech Meaning
m_Techs.PushBack( techMeaning );
//--- Store meaning also in a hash to get it by name
m_TechIndexFromName.Insert(cgGetTechniqueName(techMeaning->m_TechDesc), techIndex );
} else {
XASSERT(FALSE);
//... TODO: Print Message "Can't find meaning for technique"
}
currentTech = cgGetNextTechnique(currentTech);
++techIndex;
}
}
//--------------------------------------------------------------------------------
void
ShaderCG::DestroyDescription()
{
if( !m_SDM ) return;
// m_SDM->m_PreviousTextureParam = NULL;
m_ParamMeaningFromName.Clear();
m_TechIndexFromName.Clear();
m_FctMeaningFromName.Clear();
//--- destroy all texture created by the Shader
XHashTable<textureRef, const char*>::Iterator it = m_Textures.Begin();
XHashTable<textureRef, const char*>::Iterator itEnd = m_Textures.End();
for(; it != itEnd; it++) {
if(!(*it).TexIdPtrPtr) {
//--- not a virtools texture, manual delete is required
glDeleteTextures(1, &(*it).TexId);
(*it).TexId = 0;
GLCHECK();
}
}
m_Textures.Clear();
m_PerTechniquePerPassSamplers.Clear();
//--- Parse all Automatic Parameter Meanings
const int paramCount = m_Params.Size();
for( int paramIndex=0 ; paramIndex<paramCount ; ++paramIndex ){
delete m_Params[paramIndex];
}
m_Params.Resize(0);
//--- Parse all Automatic Per Pass Parameter Meanings
const int paramPerPassCount = m_ParamsPerPass.Size();
for( int paramPerPassIndex=0 ; paramPerPassIndex<paramPerPassCount ; ++paramPerPassIndex ){
delete m_ParamsPerPass[paramPerPassIndex];
}
m_ParamsPerPass.Resize(0);
//--- Parse all Exposed Parameter Meanings
const int exposedParamCount = m_ExposedParams.Size();
for( int exposedParamIndex=0 ; exposedParamIndex<exposedParamCount ; ++exposedParamIndex ){
delete m_ExposedParams[exposedParamIndex];
}
m_ExposedParams.Resize(0);
//--- Parse all Function Meanings
const int fctCount = m_Functs.Size();
for( int fctIndex=0 ; fctIndex<fctCount ; ++fctIndex ){
delete m_Functs[fctIndex];
}
m_Functs.Resize(0);
//--- Parse all Technique Meanings
const int techCount = m_Techs.Size();
for( int techIndex=0 ; techIndex<techCount ; ++techIndex ){
delete m_Techs[techIndex];
}
m_Techs.Resize(0);
}
//--------------------------------------------------------------------------------
ParamMeaning*
ShaderCG::BuildParamMeaning( MeaningInstantiatorInfo& ioMII )
{
MeaningInstantiatorPtr miptr;
const char* sem = cgGetParameterSemantic(ioMII.paramDesc);
if( sem && strcmp(sem, "") ){
//--- Seek it in the Semantic array (if there's a Semantic)
XString semanticStr = sem;
ioMII.semIndex = m_SDM->GetSemanticIndexFromString( semanticStr );
miptr = m_SDM->m_MeaningInstantiatorForParamBySemantic[ ioMII.semIndex ];
} else {
//--- Otherwise seek it in the Class/Type array
//int typeIndex = cgGetParameterBaseType(ioMII.paramDesc);//ioMII.paramDesc.Type;
int classIndex = cgGetParameterClass(ioMII.paramDesc);//ioMII.paramDesc.Class;
#pragma todo ("ShaderCG::BuildParamMeaning : m_MeaningInstantiatorForParamByClassAndType tab id are not correct")
//miptr = m_SDM->m_MeaningInstantiatorForParamByClassAndType[ classIndex ][ typeIndex ];
if (classIndex == CG_PARAMETERCLASS_SAMPLER)
miptr = ParamMeaning_Sampler::MeaningInstantiator;
else
miptr = ExposedParamMeaning::MeaningInstantiator;
}
//--- Instantiate the Meaning
return (ParamMeaning*)InstantiateMeaningWithPost( miptr, ioMII );
}
//--------------------------------------------------------------------------------
//#if DIRECT3D_VERSION>=0x0900
//FctMeaning*
//ShaderCG::BuildFctMeaning( MeaningInstantiatorInfo& ioMII )
//{
// MeaningInstantiatorPtr miptr;
//
// m_FX->GetFunctionDesc( ioMII.h, &ioMII.functionDesc );
//
// const int fctMeaningInstCount = m_SDM->m_MeaningInstantiatorForFunctions.Size();
// for( int a=0 ; a<fctMeaningInstCount ; ++a ){
//
// miptr = m_SDM->m_MeaningInstantiatorForFunctions[a];
// FctMeaning* funcMeaning = (FctMeaning*)InstantiateMeaningWithPost( miptr, ioMII );
// if( funcMeaning ) return funcMeaning;
// }
// return NULL;
//}
//#endif
//--------------------------------------------------------------------------------
TechMeaning*
ShaderCG::BuildTechMeaning( MeaningInstantiatorInfo& ioMII )
{
MeaningInstantiatorPtr miptr;
// m_FX->GetTechniqueDesc( ioMII.h, &ioMII.techDesc );
const int techMeaningInstCount = m_SDM->m_MeaningInstantiatorForTechniques.Size();
for( int a=0 ; a<techMeaningInstCount ; ++a ){
miptr = m_SDM->m_MeaningInstantiatorForTechniques[a];
TechMeaning* techMeaning = (TechMeaning*)InstantiateMeaningWithPost( miptr, ioMII );
if( techMeaning ) return techMeaning;
}
return NULL;
}
//--------------------------------------------------------------------------
PassMeaning*
ShaderCG::BuildPassMeaning( MeaningInstantiatorInfo& ioMII )
{
//#if DIRECT3D_VERSION>=0x0900
MeaningInstantiatorPtr miptr;
// ioMII.fx->GetPassDesc( ioMII.h, &ioMII.passDesc );
const int passMeaningInstCount = m_SDM->m_MeaningInstantiatorForPasses.Size();
for( int a=0 ; a<passMeaningInstCount ; ++a ){
miptr = m_SDM->m_MeaningInstantiatorForPasses[a];
PassMeaning* passMeaning = (PassMeaning*)InstantiateMeaningWithPost( miptr, ioMII );
if( passMeaning ) return passMeaning;
}
//#endif
return NULL;
}
//--------------------------------------------------------------------------
Meaning*
ShaderCG::InstantiateMeaning( MeaningInstantiatorPtr iMiptr, const MeaningInstantiatorInfo& iMPI )
{
Meaning* meaning = iMiptr( iMPI );
return meaning;
}
//--------------------------------------------------------------------------
Meaning*
ShaderCG::InstantiateMeaningWithPost( MeaningInstantiatorPtr iMiptr, const MeaningInstantiatorInfo& iMPI )
{
Meaning* meaning = iMiptr( iMPI );
if( meaning ){
meaning->PostIntantiationCallBack( iMPI );
}
return meaning;
}
//--------------------------------------------------------------------------
void
ShaderCG::ExecuteMeanings( MeaningProcessingInfo& iMPI )
{
//--- If there's no m_SDM set, it's certainly the default shader... so don't execute any meaning
///// Note: there should be any case in which we get there with the default shader.
if( !m_SDM ) return;
//--- Parse all Automatic Parameter Meanings
const int paramCount = m_Params.Size();
for( int paramIndex=0 ; paramIndex<paramCount ; ++paramIndex ){
ParamMeaning* paramMeaning = m_Params[paramIndex];
paramMeaning->ProcessCallBack( iMPI );
}
//--- Parse all Function Meanings
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
const int fctCount = m_Functs.Size();
for( int fctIndex=0 ; fctIndex<fctCount ; ++fctIndex ){
m_Functs[fctIndex]->ProcessCallBack( iMPI );
}
//--- Execute Current Technique Meaning
do {
CKMaterial* mat = iMPI.mat;
if( !mat ) break;
CKMaterialShader* mfx = iMPI.matShader;
if( !mfx ) break;
int techIndex = mfx->m_TechIndex;
if( techIndex == -1 ) break;
// ro : pour eviter plantage : a laisser
// car appel de function a suivre
if( techIndex >= m_Techs.Size() ) {
break;
}
m_Techs[techIndex]->ProcessCallBack( iMPI );
} while(0);
#endif
}
//--------------------------------------------------------------------------------
void
ShaderCG::ExecutePerPassMeanings( MeaningProcessingInfo& iMPI )
{
XASSERT(iMPI.isPerPassMeanings);
//--- If there's no m_SDM set, it's certainly the default shader... so don't execute any meaning
///// Note: there should be any case in which we get there with the default shader.
if( !m_SDM ) return;
//--- Parse all Automatic Parameter Per Pass Meanings
const int paramCount = m_ParamsPerPass.Size();
for( int paramIndex=0 ; paramIndex<paramCount ; ++paramIndex ){
ParamMeaning* paramMeaning = m_ParamsPerPass[paramIndex];
paramMeaning->ProcessCallBack( iMPI );
}
const perPassSamplers &passSamplers = m_PerTechniquePerPassSamplers[iMPI.techniqueIndex];
const int samplerCount = passSamplers.Size();
// Handle samplers that are per pass for the current technique
for (int samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex)
{
passSamplers[samplerIndex]->ProcessCallBack(iMPI);
}
}
/***************************************************************************
__ __
| \/ | __ _ _ __ __ _ __ _ ___ _ __
| |\/| |/ _` | '_ \ / _` |/ _` |/ _ \ '__|
| | | | (_| | | | | (_| | (_| | __/ |
|_| |_|\__,_|_| |_|\__,_|\__, |\___|_|
|___/
***************************************************************************/
//--------------------------------------------------------------------------------
ManagerCG::ManagerCG() :
m_EverythinghasAlreadyBeenRegistered( FALSE ),
m_Context( NULL )
{
}
//--------------------------------------------------------------------------------
// Semantic Related
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
void
ManagerCG::RegisterSemanticName( int iSemanticEnum, const char* iName, const char* iDesc )
{
XString name = iName;
name.ToLower();
#if DIRECT3D_VERSION<0x0900 && !defined(macintosh)
DWORD fcc = SemanticEnumToFourCC(iSemanticEnum);
m_SemanticHash.Insert( fcc,iSemanticEnum);
#else
m_SemanticHash.Insert( name, iSemanticEnum);
m_SemanticNameString.PushBack( iName );
if( iDesc )
RegisterSemanticDesc( iSemanticEnum, iDesc );
#endif
}
//--------------------------------------------------------------------------------
void
ManagerCG::RegisterSemanticDesc( int iSemanticEnum, const char* iDesc )
{
//--- Don't add empty descriptions
if( iDesc && strlen(iDesc) ){
m_SemanticDescString[ iSemanticEnum ] = iDesc;
}
}
//--------------------------------------------------------------------------------
void
ManagerCG::GetSemanticDesc( int iSemanticEnum, XString*& oSemDesc )
{
oSemDesc = &m_SemanticDescString[ iSemanticEnum ];
}
//--------------------------------------------------------------------------------
const XClassArray<XString>&
ManagerCG::GetSemanticOriginalNames()
{
return m_SemanticNameString;
}
//--------------------------------------------------------------------------------
#if DIRECT3D_VERSION<0x0900 && !defined(macintosh)
int
ManagerCG::GetSemanticIndexFromFourCC( DWORD iFcc)
{
int index = Sem_Unknown;
m_SemanticHash.LookUp( iFcc, index );
return index;
}
#else
int
ManagerCG::GetSemanticIndexFromString( XString& iStr )
{
int index = Sem_Unknown;
XString strLower( iStr );
strLower.ToLower();
m_SemanticHash.LookUp( strLower, index );
return index;
}
#endif
//--------------------------------------------------------------------------------
// Annotation Related
//--------------------------------------------------------------------------------
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
//--------------------------------------------------------------------------------
const XClassArray<XString>&
ManagerCG::GetAnnotationOriginalNames()
{
return m_AnnotationNameString;
}
//--------------------------------------------------------------------------------
void
ManagerCG::RegisterAnnotationName( int iAnnotationEnum, const char* iName )
{
XString nameLower = iName;
nameLower.ToLower();
m_AnnotationHash.Insert( nameLower, iAnnotationEnum );
m_AnnotationNameString.PushBack( iName );
}
//--------------------------------------------------------------------------------
void
ManagerCG::RegisterAnnotationStringValues( int iAnnotStrEnum, const char* iValue )
{
XString nameLower = iValue;
nameLower.ToLower();
m_AnnotStrHash.Insert( nameLower, iAnnotStrEnum );
}
//--------------------------------------------------------------------------------
int
ManagerCG::GetAnnotationIndexFromString( XString& iStr )
{
int index = Annot_Unknown;
XString strLower( iStr );
strLower.ToLower();
m_AnnotationHash.LookUp( strLower, index );
return index;
}
//--------------------------------------------------------------------------------
int
ManagerCG::GetAnnotStrValueIndexFromString( XString& iStr )
{
int index = AnnotStr_Unknown;
iStr.ToLower();
m_AnnotStrHash.LookUp( iStr, index );
return index;
}
#endif
//--------------------------------------------------------------------------------
void
ManagerCG::ExpectingAnnotation( int iAnnotationEnum, int iAnnotationType, void* iValuePtr, bool* iAnnotIsUsedPtr )
{
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
if( !iValuePtr ) return;
AnnotationExpected annotExpected( iAnnotationEnum, iAnnotationType, iValuePtr, iAnnotIsUsedPtr );
m_AnnotationsExpected.PushBack( annotExpected );
#endif
}
//--------------------------------------------------------------------------------
void
ManagerCG::ParseExpectedAnnotations( CGeffect iFx, CGannotation iFirstAnnotation )
{
//--- Parse Annotations
CGannotation currentAnnot = iFirstAnnotation;
while( currentAnnot != NULL )
{
XString annotationStr = cgGetAnnotationName(currentAnnot);
CGtype annotType = cgGetAnnotationType(currentAnnot);
int annotationIndex = GetAnnotationIndexFromString( annotationStr );
//--- Find Matching Expected Annotation
const int annotExpectedCount = m_AnnotationsExpected.Size();
int a;
for( a=0 ; a<annotExpectedCount ; ++a ){
//--- Matching Expected Annotation Found
if( annotationIndex == m_AnnotationsExpected[ a ].annotEnum ){
bool res = false;
bool annotIsUsed = false;
switch( m_AnnotationsExpected[ a ].annotType )
{
case AnnotType_String:
{
if ( annotType != CG_STRING ) break;
const char* value = cgGetStringAnnotationValue(currentAnnot);
if(value==NULL) break;
*(XString*)m_AnnotationsExpected[ a ].valuePtr = value;
annotIsUsed = true;
} break;
case AnnotType_Bool:
{
int nb = 0;
if ( annotType != CG_BOOL ) break;
const BOOL* value = cgGetBooleanAnnotationValues(currentAnnot,&nb);
if (value == NULL || nb == 0) break;
*(bool*)m_AnnotationsExpected[ a ].valuePtr = *value? true:false;
annotIsUsed = true;
} break;
case AnnotType_Float:
{
int nb;
if ( annotType != CG_FLOAT ) break;
const float* value = cgGetFloatAnnotationValues(currentAnnot,&nb);
if (value == NULL || nb != 1) break;
*(float*)m_AnnotationsExpected[ a ].valuePtr = *value;
annotIsUsed = true;
} break;
case AnnotType_Int:
{
int nb;
if ( annotType != CG_INT ) break;
const int* value = cgGetIntAnnotationValues(currentAnnot,&nb);
if (value == NULL || nb == 0) break;
*(int*)m_AnnotationsExpected[ a ].valuePtr = *value;
annotIsUsed = true;
} break;
case AnnotType_Vector4:
{
int nb;
VxVector4 vect(0,0,0,1);
if ( annotType != CG_FLOAT4 && annotType != CG_FLOAT3 ) break;
const float* value = cgGetFloatAnnotationValues(currentAnnot,&nb);
if (value == NULL || (nb != 4 && nb != 3)) break;
for (int i=0; i < nb ; i++) {
vect[i] = value[i];
}
*(VxVector4*)m_AnnotationsExpected[ a ].valuePtr = vect/*VxVector4(value)*/;
annotIsUsed = true;
} break;
}
//--- No Need to Continue if an Expected Annotation was Found
if( annotIsUsed ){
if( m_AnnotationsExpected[ a ].annotIsUsedPtr ) *(m_AnnotationsExpected[ a ].annotIsUsedPtr) = true;
break;
}
}
}
currentAnnot = cgGetNextAnnotation(currentAnnot);
}
//--- Reset AnnotationsExpected Array
m_AnnotationsExpected.Resize(0);
}
//--------------------------------------------------------------------------------
// General
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
void
ManagerCG::RegisterParamMeaningForSemantic( int iSemEnum, MeaningInstantiatorPtr iFctPtr )
{
m_MeaningInstantiatorForParamBySemantic[ iSemEnum ] = iFctPtr;
}
//--------------------------------------------------------------------------------
#if DIRECT3D_VERSION<0x0900 && !defined(macintosh)
void
ManagerCG::RegisterParamMeaningForType( int iType, MeaningInstantiatorPtr iFctPtr )
{
m_MeaningInstantiatorForParamByType[ iType ] = iFctPtr;
}
#else
void
ManagerCG::RegisterParamMeaningForClassAndType( int iClass, int iType, MeaningInstantiatorPtr iFctPtr )
{
m_MeaningInstantiatorForParamByClassAndType[ iClass ][ iType ] = iFctPtr;
}
#endif
//--------------------------------------------------------------------------------
void
ManagerCG::RegisterFctMeaning( MeaningInstantiatorPtr iFctPtr )
{
m_MeaningInstantiatorForFunctions.PushBack( iFctPtr );
}
//--------------------------------------------------------------------------------
void
ManagerCG::RegisterTechMeaning( MeaningInstantiatorPtr iFctPtr )
{
m_MeaningInstantiatorForTechniques.PushBack( iFctPtr );
}
//--------------------------------------------------------------------------------
void
ManagerCG::RegisterPassMeaning( MeaningInstantiatorPtr iPassPtr )
{
m_MeaningInstantiatorForPasses.PushBack( iPassPtr );
}
//--------------------------------------------------------------------------------
void
ManagerCG::Init( CKContext* iContext )
{
m_Context = iContext;
if( m_EverythinghasAlreadyBeenRegistered ) return;
m_EverythinghasAlreadyBeenRegistered = TRUE;
m_ShaderManager = (CKShaderManager*)iContext->GetManagerByGuid( ShaderManagerGUID );
//--- Register All Semantics Names
RegisterSemanticName( Sem_Ambient, "Ambient", "Virtools material's ambient color" );
RegisterSemanticName( Sem_Attenuation, "Attenuation", "" );
RegisterSemanticName( Sem_BoundingBoxMax, "BoundingBoxMax", "Bounding box maximum x, y, z coordinates (float3, or vector)" );
RegisterSemanticName( Sem_BoundingBoxMin, "BoundingBoxMin", "Bounding box minimum x, y, z coordinates (float3, or vector)" );
RegisterSemanticName( Sem_BoundingBoxSize, "BoundingBoxSize", "Bounding box size (float3, or vector)" );
RegisterSemanticName( Sem_BoundingCenter, "BoundingCenter", "Bounding box center (float3, or vector)" );
RegisterSemanticName( Sem_BoundingSphereSize, "BoundingSphereSize", "Bounding sphere median radius (float)" );
RegisterSemanticName( Sem_BoundingSphereMin, "BoundingSphereMin", "Bounding sphere minimum radius (float)" );
RegisterSemanticName( Sem_BoundingSphereMax, "BoundingSphereMax", "Bounding sphere maximum radius (float)" );
RegisterSemanticName( Sem_Diffuse, "Diffuse",
"- as a Virtools semantic: Virtools material's diffuse color (float4)\n"
"- as render state: renderstate enum standing for diffuse stage\n"
"- as a Vertex Shader Input semantic: the input vertex diffuse color" );
RegisterSemanticName( Sem_ElapsedTime, "ElapsedTime", "Last Delta time in milliseconds" );
RegisterSemanticName( Sem_Emissive, "Emissive", "Virtools material's emissive color (float4)" );
RegisterSemanticName( Sem_EnvironmentNormal, "EnvironmentNormal", "" );
RegisterSemanticName( Sem_Height, "Height", "" );
RegisterSemanticName( Sem_Joint, "Joint", "" );
RegisterSemanticName( Sem_JointWorld, "JointWorld", "" );
RegisterSemanticName( Sem_JointWorldInverse, "JointWorldInverse", "" );
RegisterSemanticName( Sem_JointWorldInverseTranspose, "JointWorldInversetranspose", "" );
RegisterSemanticName( Sem_JointWorldView, "JointWorldView", "" );
RegisterSemanticName( Sem_JointWorldViewInverse, "JointWorldViewInverse", "" );
RegisterSemanticName( Sem_JointWorldViewInverseTranspose, "JointWorldViewInverseTranspose", "" );
RegisterSemanticName( Sem_JointWorldViewProjection, "JointWorldViewProjection", "" );
RegisterSemanticName( Sem_JointWorldViewProjectionInverse, "JointWorldViewProjectionInverse", "" );
RegisterSemanticName( Sem_JointWorldViewProjectionInverseTranspose, "JointWorldViewProjectionInverseTranspose", "" );
RegisterSemanticName( Sem_LastTime, "LastTime", "Last simulation time in seconds (float)" );
RegisterSemanticName( Sem_Normal, "Normal", "" );
RegisterSemanticName( Sem_Opacity, "Opacity", "" );
RegisterSemanticName( Sem_Position, "Position", "Virtools object's position (float3)" );
RegisterSemanticName( Sem_Projection, "Projection", "Projection matrix (float4x4)" );
RegisterSemanticName( Sem_ProjectionInverse, "ProjectionInverse", "Inversed Projection matrix (float4x4)" );
RegisterSemanticName( Sem_ProjectionInverseTranspose, "ProjectionInverseTranspose", "Transposed Inversed Projection matrix (float4x4)" );
RegisterSemanticName( Sem_Random, "Random", "Random number in range [0.0 - 1.0] (float)" );
RegisterSemanticName( Sem_Refraction, "Refraction", "" );
RegisterSemanticName( Sem_RenderColorTarget, "RenderColorTarget", "" );
RegisterSemanticName( Sem_RenderDepthStencilTarget, "RenderDepthDtencilTarget", "" );
RegisterSemanticName( Sem_RenderTargetClipping, "RenderTargetClipping", "" );
RegisterSemanticName( Sem_RenderTargetDimensions, "RenderTargetDimensions", "Size of the viewport in pixels" );
RegisterSemanticName( Sem_Specular, "Specular",
"- as a Virtools semantic: Virtools material's specular color (float4)\n"
"- as a VS input semantic: the input vertex specular color" );
RegisterSemanticName( Sem_SpecularPower, "SpecularPower", "Virtools material's specular power (float)" );
RegisterSemanticName( Sem_StandardsGlobal, "StandardsGlobal", "" );
RegisterSemanticName( Sem_TextureMatrix, "TextureMatrix", "" );
RegisterSemanticName( Sem_Time, "Time", "Time elapsed since Virtools play event occured in seconds (float)" );
RegisterSemanticName( Sem_UnitsScale, "UnitsScale", "" );
RegisterSemanticName( Sem_View, "View", "" );
RegisterSemanticName( Sem_ViewInverse, "ViewInverse", "" );
RegisterSemanticName( Sem_ViewInverseTranspose, "ViewInverseTranspose", "" );
RegisterSemanticName( Sem_ViewProjection, "ViewProjection", "" );
RegisterSemanticName( Sem_ViewProjectionInverse, "ViewProjectionInverse", "" );
RegisterSemanticName( Sem_ViewProjectionInverseTranspose, "ViewProjectionInverseTranspose", "" );
RegisterSemanticName( Sem_World, "World", "" );
RegisterSemanticName( Sem_WorldInverse, "WorldInverse", "" );
RegisterSemanticName( Sem_WorldInverseTranspose, "WorldInverseTranspose", "" );
RegisterSemanticName( Sem_WorldView, "WorldView", "" );
RegisterSemanticName( Sem_WorldViewInverse, "WorldViewInverse", "" );
RegisterSemanticName( Sem_WorldViewInverseTranspose, "WorldViewInverseTranspose", "" );
RegisterSemanticName( Sem_WorldViewProjection, "WorldViewProjection", "" );
RegisterSemanticName( Sem_WorldViewProjectionInverse, "WorldViewProjectionInverse", "" );
RegisterSemanticName( Sem_WorldViewProjectionInverseTranspose, "WorldViewProjectionInverseTranspose", "" );
// Some Semantic Synonyms
RegisterSemanticName( Sem_WorldViewProjectionInverse, "Inv_WorldViewProjection" ); // Synonym
RegisterSemanticName( Sem_WorldViewProjectionInverse, "IWorldViewProjection" ); // Synonym
RegisterSemanticName( Sem_WorldViewProjectionInverse, "WorldViewProjectionI" ); // Synonym
RegisterSemanticName( Sem_WorldViewProjectionInverseTranspose, "Inv_TWorldViewProjection" ); // Synonym
RegisterSemanticName( Sem_WorldViewProjectionInverseTranspose, "ITWorldViewProjection" ); // Synonym
RegisterSemanticName( Sem_WorldViewProjectionInverseTranspose, "WorldViewProjectionIT" ); // Synonym
RegisterSemanticName( Sem_WorldInverse, "Inv_World" ); // Synonym
RegisterSemanticName( Sem_WorldInverse, "IWorld" ); // Synonym
RegisterSemanticName( Sem_WorldInverse, "WorldI" ); // Synonym
RegisterSemanticName( Sem_WorldInverseTranspose, "Inv_TWorld" ); // Synonym
RegisterSemanticName( Sem_WorldInverseTranspose, "ITWorld" ); // Synonym
RegisterSemanticName( Sem_WorldInverseTranspose, "WorldIT" ); // Synonym
RegisterSemanticName( Sem_ViewInverse, "Inv_View" ); // Synonym
RegisterSemanticName( Sem_ViewInverse, "IView" ); // Synonym
RegisterSemanticName( Sem_ViewInverse, "ViewI" ); // Synonym
RegisterSemanticName( Sem_ViewInverseTranspose, "Inv_TView" ); // Synonym
RegisterSemanticName( Sem_ViewInverseTranspose, "ITView" ); // Synonym
RegisterSemanticName( Sem_ViewInverseTranspose, "ViewIT" ); // Synonym
RegisterSemanticName( Sem_WorldViewInverse, "Inv_WorldView" ); // Synonym
RegisterSemanticName( Sem_WorldViewInverse, "IWorldView" ); // Synonym
RegisterSemanticName( Sem_WorldViewInverse, "WorldViewI" ); // Synonym
RegisterSemanticName( Sem_WorldViewInverseTranspose, "Inv_TWorldView" ); // Synonym
RegisterSemanticName( Sem_WorldViewInverseTranspose, "ITWorldView" ); // Synonym
RegisterSemanticName( Sem_WorldViewInverseTranspose, "WorldViewIT" ); // Synonym
RegisterSemanticName( Sem_ViewProjectionInverse, "Inv_ViewProjection" ); // Synonym
RegisterSemanticName( Sem_ViewProjectionInverse, "IViewProjection" ); // Synonym
RegisterSemanticName( Sem_ViewProjectionInverse, "ViewProjectionI" ); // Synonym
RegisterSemanticName( Sem_ViewProjectionInverseTranspose, "Inv_TViewProjection" ); // Synonym
RegisterSemanticName( Sem_ViewProjectionInverseTranspose, "ITViewProjection" ); // Synonym
RegisterSemanticName( Sem_ViewProjectionInverseTranspose, "ViewProjectionIT" ); // Synonym
RegisterSemanticName( Sem_ProjectionInverse, "Inv_Projection" ); // Synonym
RegisterSemanticName( Sem_ProjectionInverse, "IProjection" ); // Synonym
RegisterSemanticName( Sem_ProjectionInverse, "ProjectionI" ); // Synonym
RegisterSemanticName( Sem_ProjectionInverseTranspose, "Inv_TProjection" ); // Synonym
RegisterSemanticName( Sem_ProjectionInverseTranspose, "ITProjection" ); // Synonym
RegisterSemanticName( Sem_ProjectionInverseTranspose, "ProjectionIT" ); // Synonym
RegisterSemanticName( Sem_SpecularPower, "Power" ); // Synonym
RegisterSemanticName( Sem_AlphaTestEnable, "AlphaTestEnable", "Virtools material's alpha test checkbox (bool)" );
RegisterSemanticName( Sem_AlphaBlendEnable, "AlphaBlendEnable", "Virtools material's transparency" );
RegisterSemanticName( Sem_AlphaFunc, "AlphaFunc", "Virtools material's alpha test function, value can be directly bound to the corresponding render state (int)" );
RegisterSemanticName( Sem_AlphaRef, "AlphaRef", "Virtools material's alpha test reference value, in the [0, 1] range (float)" );
RegisterSemanticName( Sem_DoubleSided, "DoubleSided", "Virtools material's double sided flag" );
RegisterSemanticName( Sem_SingleSided, "SingleSided", "Negation of Virtools material's double sided flag" );
RegisterSemanticName( Sem_Position, "ObjectPos" ); // Synonym
RegisterSemanticName( Sem_BoundingBoxMax, "Local_BBox_Max" ); // Synonym
RegisterSemanticName( Sem_BoundingBoxMax, "LocalBBoxMax" ); // Synonym
RegisterSemanticName( Sem_BoundingBoxMin, "Local_BBox_Min" ); // Synonym
RegisterSemanticName( Sem_BoundingBoxMin, "LocalBBoxMin" ); // Synonym
RegisterSemanticName( Sem_BoundingBoxSize, "Local_BBox_Size" ); // Synonym
RegisterSemanticName( Sem_BoundingBoxSize, "LocalBBoxSize" ); // Synonym
RegisterSemanticName( Sem_WorldViewProjectionTranspose, "TWorldViewProjection", "" );
RegisterSemanticName( Sem_WorldTranspose, "TWorld", "" );
RegisterSemanticName( Sem_ViewTranspose, "TView", "" );
RegisterSemanticName( Sem_ProjectionTranspose, "TProjection", "" );
RegisterSemanticName( Sem_WorldViewTranspose, "TWorldView", "" );
RegisterSemanticName( Sem_ViewProjectionTranspose, "TViewProjection", "" );
RegisterSemanticName( Sem_EyePos, "EyePos", "Current camera position (float3)" );
RegisterSemanticName( Sem_EyePos, "CamPos" ); // Synonym
RegisterSemanticName( Sem_EyePos, "World_Camera_Position" ); // Synonym
RegisterSemanticName( Sem_EyePos, "WorldCameraPosition" ); // Synonym
RegisterSemanticName( Sem_Texture, "Texture",
"- as a Virtools semantic: Virtools material's texture\n"
"- as render state: renderstate enum standing for texture stage" );
RegisterSemanticName( Sem_Texture0, "Texture0", "Virtools texture of channel 0 of current mesh" );
RegisterSemanticName( Sem_Texture1, "Texture1", "Virtools texture of channel 1 of current mesh" );
RegisterSemanticName( Sem_Texture2, "Texture2", "Virtools texture of channel 2 of current mesh" );
RegisterSemanticName( Sem_Texture3, "Texture3", "Virtools texture of channel 3 of current mesh" );
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
RegisterSemanticName( Sem_Texture4, "Texture4", "Virtools texture of channel 4 of current mesh" );
RegisterSemanticName( Sem_Texture5, "Texture5", "Virtools texture of channel 5 of current mesh" );
RegisterSemanticName( Sem_Texture6, "Texture6", "Virtools texture of channel 6 of current mesh" );
RegisterSemanticName( Sem_Texture7, "Texture7", "Virtools texture of channel 7 of current mesh" );
#endif
RegisterSemanticName( Sem_PassCount, "PassCount", "Shader's pass count (int)" );
RegisterSemanticName( Sem_PassIndex, "PassIndex", "Current rendering pass index (int)" );
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
RegisterSemanticName( Sem_Bones, "Bones", "Array of bones matrices of the skinned character (float4x4[])" );
RegisterSemanticName( Sem_Bones, "Joint" ); // Synonym
#endif
RegisterSemanticName( Sem_TBones, "TBones", "Array of transposed bones matrices of the skinned character (float4x4[])" );
RegisterSemanticName( Sem_TBones, "TJoint" ); // Synonym
RegisterSemanticName( Sem_RBones, "RBones", "Index of the register where bones matrices of the skinned character will be copied (int)" );
RegisterSemanticName( Sem_RBones, "RJoint" ); // Synonym
RegisterSemanticName( Sem_RTBones, "RTBones", "Index of the register where transposed bones matrices of the skinned character will be copied (int)" );
RegisterSemanticName( Sem_RTBones, "RTJoint" ); // Synonym
RegisterSemanticName( Sem_BonesPerVertex, "BonesPerVertex", "Max. number of bones per vertex (int)" );
RegisterSemanticName( Sem_BonesPerVertex, "JointPerVertex" ); // Synonym
RegisterSemanticName( Sem_ViewportPixelSize, "ViewportPixelSize", "" );
RegisterSemanticName( Sem_TexelSize, "TexelSize", "Texel size of the last texture parsed in the shader (float2)" );
RegisterSemanticName( Sem_TextureSize, "TextureSize", "Texture size of the last texture parsed in the shader (float2)" );
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
RegisterSemanticName( Sem_NearestLight, "NearestLight", "Nearest light\n (float = range, float3 = position, float4 = color, float4x4 = matrix)" );
RegisterSemanticName( Sem_LightCount, "LightCount", "Number of active lights in the scene (int)" );
RegisterSemanticName( Sem_GlobalAmbient, "GlobalAmbient", "Global ambient color (float4)" );
#endif
#if defined(_XBOX) && (_XBOX_VER<200) || defined(macintosh)
RegisterSemanticName( Sem_TexelSize0, "TexelSize0", "Texel size of the last texture parsed in the shader (float2)" );
RegisterSemanticName( Sem_TexelSize1, "TexelSize1", "Texel size of the last texture parsed in the shader (float2)" );
RegisterSemanticName( Sem_TexelSize2, "TexelSize2", "Texel size of the last texture parsed in the shader (float2)" );
RegisterSemanticName( Sem_TexelSize3, "TexelSize3", "Texel size of the last texture parsed in the shader (float2)" );
RegisterSemanticName( Sem_BonesIndexConstant, "Bones Index Constant", "Constant used to convert floats to Vertex Shader Constants Index" );
#endif
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
//--- Register All Annotations Names
RegisterAnnotationName( Annot_Name, "Name" );
RegisterAnnotationName( Annot_Normalize, "Normalize" );
RegisterAnnotationName( Annot_Object, "Object" );
RegisterAnnotationName( Annot_Semantic, "Semantic" );
RegisterAnnotationName( Annot_SemanticType, "SemanticType" );
RegisterAnnotationName( Annot_Space, "Space" );
RegisterAnnotationName( Annot_Units, "Units" );
RegisterAnnotationName( Annot_Usage, "Usage" );
RegisterAnnotationName( Annot_Dimensions, "Dimensions" );
RegisterAnnotationName( Annot_Discardable, "Discardable" );
RegisterAnnotationName( Annot_Format, "Format" );
RegisterAnnotationName( Annot_Function, "Function" );
RegisterAnnotationName( Annot_MIPLevels, "MipLevels" );
RegisterAnnotationName( Annot_ResourceName, "ResourceName" );
RegisterAnnotationName( Annot_ResourceType, "ResourceType" );
RegisterAnnotationName( Annot_TargetPS, "TargetPS" );
RegisterAnnotationName( Annot_TargetVS, "TargetVS" );
RegisterAnnotationName( Annot_Target, "Target" );
RegisterAnnotationName( Annot_ViewportRatio,"ViewportRatio" );
RegisterAnnotationName( Annot_UIHelp, "UIHelp" );
RegisterAnnotationName( Annot_UIMax, "UIMax" );
RegisterAnnotationName( Annot_UIMin, "UIMin" );
RegisterAnnotationName( Annot_UIName, "UIName" );
RegisterAnnotationName( Annot_UIObject, "UIObject" );
RegisterAnnotationName( Annot_UIStep, "UIStep" );
RegisterAnnotationName( Annot_UIStepPower, "UIStepPower" );
RegisterAnnotationName( Annot_UIWidget, "UIWidget" );
RegisterAnnotationName( Annot_Script, "Script" );
RegisterAnnotationName( Annot_ScriptClass, "ScriptClass" );
RegisterAnnotationName( Annot_ScriptOrder, "ScriptOrder" );
RegisterAnnotationName( Annot_ScriptOutput, "ScriptOutput" );
RegisterAnnotationName( Annot_IsTexelSize, "IsTexelSize" );
RegisterAnnotationName( Annot_Name, "Name" );
RegisterAnnotationName( Annot_Target, "Target" );
RegisterAnnotationName( Annot_Width, "Width" );
RegisterAnnotationName( Annot_Height, "Height" );
RegisterAnnotationName( Annot_Depth, "Depth" );
RegisterAnnotationName( Annot_Type, "Type" );
RegisterAnnotationName( Annot_NeedTangentSpace, "NeedTangentSpace" );
RegisterAnnotationName( Annot_NeedColorAndNormal, "NeedColorAndNormal" );
RegisterAnnotationName( Annot_DirectionalLightHack, "ProcessDirectionalLights" );
RegisterAnnotationName( Annot_Nearest, "Nearest" );
RegisterAnnotationName( Annot_Sort, "Sort" );
RegisterAnnotationName( Annot_Default, "Default" );
//--- Register All Annotations String Values
RegisterAnnotationStringValues( AnnotStr_Volume, "Volume" );
RegisterAnnotationStringValues( AnnotStr_3d, "3D" );
RegisterAnnotationStringValues( AnnotStr_2d, "2D" );
RegisterAnnotationStringValues( AnnotStr_Cube, "Cube" );
RegisterAnnotationStringValues( AnnotStr_Entity3D, "Entity3D" );
RegisterAnnotationStringValues( AnnotStr_Entity3D, "3DEntity" );
RegisterAnnotationStringValues( AnnotStr_Entity3D, "Geometry" );
RegisterAnnotationStringValues( AnnotStr_Vector, "Vector" );
RegisterAnnotationStringValues( AnnotStr_Light, "Light" );
RegisterAnnotationStringValues( AnnotStr_Light, "TargetLight" ); //--- Used in 3dsMax
RegisterAnnotationStringValues( AnnotStr_Light, "PointLight" ); //--- Used in FX Composer
RegisterAnnotationStringValues( AnnotStr_Camera, "Camera" );
RegisterAnnotationStringValues( AnnotStr_Local, "Local" );
RegisterAnnotationStringValues( AnnotStr_World, "World" );
#endif
//--- Register All Meanings Instanciators For Functions
RegisterMeaningForFctCG( FctMeaning );
//--- Register All Meanings Instanciators For Techniques
RegisterMeaningForTechCG( TechMeaning );
//--- Register All Meanings Instanciators For Passes
RegisterMeaningForPassCG( PassMeaning );
//--- Register All Meanings Instanciators For Params Referenced by a Semantic
for( int s=0 ; s<SemCount ; ++s ){
RegisterMeaningBySemanticCG( s, ExposedParamMeaning );
}
RegisterMeaningBySemanticCG( Sem_Ambient, ParamMeaning_Ambient );
RegisterMeaningBySemanticCG( Sem_Emissive, ParamMeaning_Emissive );
RegisterMeaningBySemanticCG( Sem_Diffuse, ParamMeaning_Diffuse );
RegisterMeaningBySemanticCG( Sem_Specular, ParamMeaning_Specular );
RegisterMeaningBySemanticCG( Sem_SpecularPower, ParamMeaning_Power );
RegisterMeaningBySemanticCG( Sem_AlphaTestEnable, ParamMeaning_AlphaTestEnable );
RegisterMeaningBySemanticCG( Sem_AlphaBlendEnable, ParamMeaning_AlphaBlendEnable );
RegisterMeaningBySemanticCG( Sem_AlphaFunc, ParamMeaning_AlphaFunc );
RegisterMeaningBySemanticCG( Sem_AlphaRef, ParamMeaning_AlphaRef );
RegisterMeaningBySemanticCG( Sem_SingleSided, ParamMeaning_SingleSided );
RegisterMeaningBySemanticCG( Sem_DoubleSided, ParamMeaning_DoubleSided );
for( int channelIndex = Sem_Texture ; channelIndex<=Sem_Texture7 ; ++channelIndex ){
RegisterMeaningBySemanticCG( channelIndex, ParamMeaning_Texture );
}
RegisterMeaningBySemanticCG( Sem_BoundingBoxMax, ParamMeaning_BBoxMax );
RegisterMeaningBySemanticCG( Sem_BoundingBoxMin, ParamMeaning_BBoxMin );
RegisterMeaningBySemanticCG( Sem_BoundingBoxSize, ParamMeaning_BBoxSize );
RegisterMeaningBySemanticCG( Sem_BoundingCenter, ParamMeaning_BBoxCenter );
RegisterMeaningBySemanticCG( Sem_BoundingSphereSize, ParamMeaning_BoundingSphereRadius );
RegisterMeaningBySemanticCG( Sem_BoundingSphereMax, ParamMeaning_BoundingSphereMax );
RegisterMeaningBySemanticCG( Sem_BoundingSphereMin, ParamMeaning_BoundingSphereMin );
RegisterMeaningBySemanticCG( Sem_EyePos, ParamMeaning_EyePos );
RegisterMeaningBySemanticCG( Sem_Position, ParamMeaning_ObjectPos );
RegisterMeaningBySemanticCG( Sem_World, ParamMeaning_World );
RegisterMeaningBySemanticCG( Sem_WorldTranspose, ParamMeaning_WorldTranspose );
RegisterMeaningBySemanticCG( Sem_WorldInverse, ParamMeaning_WorldInverse );
RegisterMeaningBySemanticCG( Sem_WorldInverseTranspose, ParamMeaning_WorldInverseTranspose );
RegisterMeaningBySemanticCG( Sem_View, ParamMeaning_View );
RegisterMeaningBySemanticCG( Sem_ViewTranspose, ParamMeaning_ViewTranspose );
RegisterMeaningBySemanticCG( Sem_ViewInverse, ParamMeaning_ViewInverse );
RegisterMeaningBySemanticCG( Sem_ViewInverseTranspose, ParamMeaning_ViewInverseTranspose );
RegisterMeaningBySemanticCG( Sem_Projection, ParamMeaning_Projection );
RegisterMeaningBySemanticCG( Sem_ProjectionTranspose, ParamMeaning_ProjectionTranspose );
RegisterMeaningBySemanticCG( Sem_ProjectionInverse, ParamMeaning_ProjectionInverse );
RegisterMeaningBySemanticCG( Sem_ProjectionInverseTranspose, ParamMeaning_ProjectionInverseTranspose );
RegisterMeaningBySemanticCG( Sem_WorldView, ParamMeaning_WorldView );
RegisterMeaningBySemanticCG( Sem_WorldViewTranspose, ParamMeaning_WorldViewTranspose );
RegisterMeaningBySemanticCG( Sem_WorldViewInverse, ParamMeaning_WorldViewInverse );
RegisterMeaningBySemanticCG( Sem_WorldViewInverseTranspose, ParamMeaning_WorldViewInverseTranspose );
RegisterMeaningBySemanticCG( Sem_ViewProjection, ParamMeaning_ViewProjection );
RegisterMeaningBySemanticCG( Sem_ViewProjectionTranspose, ParamMeaning_ViewProjectionTranspose );
RegisterMeaningBySemanticCG( Sem_ViewProjectionInverse, ParamMeaning_ViewProjectionInverse );
RegisterMeaningBySemanticCG( Sem_ViewProjectionInverseTranspose, ParamMeaning_ViewProjectionInverseTranspose );
RegisterMeaningBySemanticCG( Sem_WorldViewProjection, ParamMeaning_WorldViewProjection );
RegisterMeaningBySemanticCG( Sem_WorldViewProjectionTranspose, ParamMeaning_WorldViewProjectionTranspose );
RegisterMeaningBySemanticCG( Sem_WorldViewProjectionInverse, ParamMeaning_WorldViewProjectionInverse );
RegisterMeaningBySemanticCG( Sem_WorldViewProjectionInverseTranspose, ParamMeaning_WorldViewProjectionInverseTranspose );
RegisterMeaningBySemanticCG( Sem_Time, ParamMeaning_Time );
RegisterMeaningBySemanticCG( Sem_ElapsedTime, ParamMeaning_ElapsedTime );
RegisterMeaningBySemanticCG( Sem_LastTime, ParamMeaning_LastTime );
RegisterMeaningBySemanticCG( Sem_ViewportPixelSize, ParamMeaning_ViewportPixelSize );
RegisterMeaningBySemanticCG( Sem_Random, ParamMeaning_Random );
RegisterMeaningBySemanticCG( Sem_BonesPerVertex, ParamMeaning_BonesPerVertex );
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
RegisterMeaningBySemanticCG( Sem_Bones, ParamMeaning_Bones );
RegisterMeaningBySemanticCG( Sem_TBones, ParamMeaning_TBones );
#endif
// RegisterMeaningBySemanticCG( Sem_RBones, ParamMeaning_RBones );
// RegisterMeaningBySemanticCG( Sem_RTBones, ParamMeaning_RTBones );
RegisterMeaningBySemanticCG( Sem_PassCount, ParamMeaning_PassCount );
RegisterMeaningBySemanticCG( Sem_PassIndex, ParamMeaning_PassIndex );
RegisterMeaningBySemanticCG( Sem_TexelSize, ParamMeaning_TexelSize );
RegisterMeaningBySemanticCG( Sem_TextureSize, ParamMeaning_TextureSize );
#if DIRECT3D_VERSION>=0x0900 || defined(macintosh)
RegisterMeaningBySemanticCG( Sem_NearestLight, ParamMeaning_NearestLight );
RegisterMeaningBySemanticCG( Sem_LightCount, ParamMeaning_LightCount );
RegisterMeaningBySemanticCG( Sem_GlobalAmbient, ParamMeaning_GlobalAmbient );
#endif
#if DIRECT3D_VERSION<0x0900 && !defined(macintosh)
RegisterMeaningBySemanticCG( Sem_TexelSize0, ParamMeaning_TexelSize );
RegisterMeaningBySemanticCG( Sem_TexelSize1, ParamMeaning_TexelSize );
RegisterMeaningBySemanticCG( Sem_TexelSize2, ParamMeaning_TexelSize );
RegisterMeaningBySemanticCG( Sem_TexelSize3, ParamMeaning_TexelSize );
RegisterMeaningBySemanticCG( Sem_BonesIndexConstant, ParamMeaning_BonesIndexConstant );
#endif
//--- Register All Meanings Instanciators For Params Not Referenced by a Semantic
//#if DIRECT3D_VERSION<0x0900
// for( int typ=0 ; typ<ParamTypeCount ; ++typ ){
// RegisterMeaningByTypeCG( typ, ExposedParamMeaning );
// }
//#else
for( int clas=0 ; clas<ParamClassCount ; ++clas ){
for( int typ=0 ; typ<ParamTypeCount ; ++typ ){
RegisterMeaningByClassAndTypeCG( clas, typ, ExposedParamMeaning );
}
}
//#endif
}
/***************************************************************************
____ _ _
/ ___|___ _ ____ _____ _ __ (_) ___ _ __ | |_
| | / _ \| '_ \ \ / / _ \ '_ \| |/ _ \ '_ \| __|
| |__| (_) | | | \ V / __/ | | | | __/ | | | |_
\____\___/|_| |_|\_/ \___|_| |_|_|\___|_| |_|\__|
| ___| _ _ __ ___| |_(_) ___ _ __ ___
| |_ | | | | '_ \ / __| __| |/ _ \| '_ \/ __|
| _|| |_| | | | | (__| |_| | (_) | | | \__ \
|_| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/
***************************************************************************/
//--------------------------------------------------------------------------
struct FMTINFO
{
GLint fmt;
const char* strName;
};
//static const TCHAR* TYPE_UNSIGNED = TEXT("Unsigned");
//static const TCHAR* TYPE_SIGNED = TEXT("Signed");
//static const TCHAR* TYPE_MIXED = TEXT("Mixed");
//static const TCHAR* TYPE_FOUR_CC = TEXT("Four CC");
//static const TCHAR* TYPE_FLOAT = TEXT("Floating-Point");
//static const TCHAR* TYPE_IEEE = TEXT("IEEE Floating-Point");
//#if DIRECT3D_VERSION>=0x0900
const FMTINFO fmtInfoArray[] =
{
/*D3DFMT_A8B8G8R8*/GL_RGBA8, TEXT("A8B8G8R8"),
/*D3DFMT_A8R8G8B8*/GL_RGBA8, TEXT("A8R8G8B8"),
// D3DFMT_X8B8G8R8, TEXT("X8B8G8R8"),
// D3DFMT_X8R8G8B8, TEXT("X8R8G8B8"),
// D3DFMT_A16B16G16R16, TEXT("A16B16G16R16"),
//
// D3DFMT_A1R5G5B5, TEXT("A1R5G5B5"),
// D3DFMT_A4R4G4B4, TEXT("A4R4G4B4"),
//
// D3DFMT_R5G6B5, TEXT("R5G6B5"),
// D3DFMT_X1R5G5B5, TEXT("X1R5G5B5"),
//
// D3DFMT_R16F, TEXT("R16F"),
// D3DFMT_G16R16F, TEXT("G16R16F"),
GL_RGBA16F_ARB, TEXT("A16B16G16R16F"),
//
// D3DFMT_R32F, TEXT("R32F"),
// D3DFMT_G32R32F, TEXT("G32R32F"),
GL_RGBA32F_ARB, TEXT("A32B32G32R32F"),
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, TEXT("DXT1"),
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, TEXT("DXT3"),
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, TEXT("DXT5"),
//
// D3DFMT_UYVY, TEXT("UYVY"),
// D3DFMT_YUY2, TEXT("YUY2"),
//#ifdef D3DFMT_A4L4
// D3DFMT_A4L4, TEXT("A4L4"),
//#endif
// D3DFMT_A8, TEXT("A8"),
// D3DFMT_L8, TEXT("L8"),
//#ifdef D3DFMT_P8
// D3DFMT_P8, TEXT("P8"),
//#endif
//#ifdef D3DFMT_R3G3B2
// D3DFMT_R3G3B2, TEXT("R3G3B2"),
//#endif
// D3DFMT_A8L8, TEXT("A8L8"),
//#ifdef D3DFMT_A8P8
// D3DFMT_A8P8, TEXT("A8P8"),
//#endif
//#ifdef D3DFMT_A8R3G3B2
// D3DFMT_A8R3G3B2, TEXT("A8R3G3B2"),
//#endif
// D3DFMT_L16, TEXT("L16"),
//
// D3DFMT_X4R4G4B4, TEXT("X4R4G4B4"),
//#ifdef D3DFMT_R8G8B8
// D3DFMT_R8G8B8, TEXT("R8G8B8"),
//#endif
// D3DFMT_A2B10G10R10, TEXT("A2B10G10R10"),
// D3DFMT_A2R10G10B10, TEXT("A2R10G10B10"),
//
// D3DFMT_G16R16, TEXT("G16R16"),
//
//#ifdef D3DFMT_CxV8U8
// D3DFMT_CxV8U8, TEXT("CxV8U8"),
//#endif
// D3DFMT_V8U8, TEXT("V8U8"),
// D3DFMT_Q8W8V8U8, TEXT("Q8W8V8U8"),
// D3DFMT_V16U16, TEXT("V16U16"),
// D3DFMT_Q16W16V16U16, TEXT("Q16W16V16U16"),
//
// D3DFMT_L6V5U5, TEXT("L6V5U5"),
// D3DFMT_A2W10V10U10, TEXT("A2W10V10U10"),
// D3DFMT_X8L8V8U8, TEXT("X8L8V8U8"),
//
// D3DFMT_G8R8_G8B8, TEXT("G8R8_G8B8"),
// D3DFMT_R8G8_B8G8, TEXT("R8G8_B8G8"),
};
const int fmtInfoArraySize = sizeof(fmtInfoArray) / sizeof(fmtInfoArray[0]);
GLint StringToGLFormat(const char* pstrFormat){
for(int i=0;i<fmtInfoArraySize;i++){
if(0==_strcmpi(pstrFormat,fmtInfoArray[i].strName))
return fmtInfoArray[i].fmt;
}
return GL_RGBA8;
}
//#else
//
//DWORD g_SemanticEnumToFourCC[SemCount] = {
// '____', // Sem_Unknown = 0,
// 'vAMB', // Sem_Ambient,
// 'fATT', // Sem_Attenuation,
// 'vBMA', // Sem_BoundingBoxMax,
// 'vBMI', // Sem_BoundingBoxMin,
// 'vBSZ', // Sem_BoundingBoxSize,
// 'vBCE', // Sem_BoundingCenter,
// 'vBSS', // Sem_BoundingSphereSize,
// 'vBSI', // Sem_BoundingSphereMin,
// 'vBSA', // Sem_BoundingSphereMax,
// 'vDIF', // Sem_Diffuse,
// 'fETI', // Sem_ElapsedTime,
// 'vEMI', // Sem_Emissive,
// 'tENV', // Sem_EnvironmentNormal,
// 'fHEI', // Sem_Height,
// 'vJOI', // Sem_Joint,
// 'JWOR', // Sem_JointWorld,
// 'JWIN', // Sem_JointWorldInverse,
// 'JWIT', // Sem_JointWorldInverseTranspose,
// 'JWOV', // Sem_JointWorldView,
// 'JWVI', // Sem_JointWorldViewInverse,
// 'JWVY', // Sem_JointWorldViewInverseTranspose,
// 'JWVP', // Sem_JointWorldViewProjection,
// 'JTIN', // Sem_JointWorldViewProjectionInverse,
// 'JTIT', // Sem_JointWorldViewProjectionInverseTranspose,
// 'fLAS', // Sem_LastTime,
// 'vNOR', // Sem_Normal,
// 'vOPA', // Sem_Opacity,
// 'vPOS', // Sem_Position,
// 'mPRO', // Sem_Projection,
// 'mPIN', // Sem_ProjectionInverse,
// 'mPIT', // Sem_ProjectionInverseTranspose,
// 'fRAN', // Sem_Random,
// 'vREF', // Sem_Refraction,
// 'tREN', // Sem_RenderColorTarget,
// 'tSTE', // Sem_RenderDepthStencilTarget,
// 'vCLI', // Sem_RenderTargetClipping,
// 'vRTD', // Sem_RenderTargetDimensions,
// 'vSPE', // Sem_Specular,
// 'fPOW', // Sem_SpecularPower,
// '____', // Sem_StandardsGlobal,
// 'mTEX', // Sem_TextureMatrix,
// 'fTIM', // Sem_Time,
// 'fSCA', // Sem_UnitsScale,
// 'mVIE', // Sem_View,
// 'mVIN', // Sem_ViewInverse,
// 'mVIT', // Sem_ViewInverseTranspose,
// 'mVPR', // Sem_ViewProjection,
// 'mVPI', // Sem_ViewProjectionInverse,
// 'VPIT', // Sem_ViewProjectionInverseTranspose,
// 'mWOR', // Sem_World,
// 'mWIN', // Sem_WorldInverse,
// 'mWIT', // Sem_WorldInverseTranspose,
// 'mWVI', // Sem_WorldView,
// 'WVIN', // Sem_WorldViewInverse,
// 'WVIT', // Sem_WorldViewInverseTranspose,
// 'mWVP', // Sem_WorldViewProjection,
// 'WVPI', // Sem_WorldViewProjectionInverse,
// 'WVPY', // Sem_WorldViewProjectionInverseTranspose,
// 'WVPT', // Sem_WorldViewProjectionTranspose,
// 'mWOT', // Sem_WorldTranspose,
// 'mVTR', // Sem_ViewTranspose,
// 'mPRT', // Sem_ProjectionTranspose,
// 'mWVT', // Sem_WorldViewTranspose,
// 'mVPT', // Sem_ViewProjectionTranspose,
// 'vEPO', // Sem_EyePos,
// 'tTEX', // Sem_Texture,
// 'TEX0', // Sem_Texture0,
// 'TEX1', // Sem_Texture1,
// 'TEX2', // Sem_Texture2,
// 'TEX3', // Sem_Texture3,
// 'TEX4', // Sem_Texture4,
// 'TEX5', // Sem_Texture5,
// 'TEX6', // Sem_Texture6,
// 'TEX7', // Sem_Texture7,
// 'PASC', // Sem_PassCount,
// 'PASI', // Sem_PassIndex,
// '____', // Sem_Bones,
// '____', // Sem_TBones,
// 'mBON', // Sem_RBones,
// 'mTBO', // Sem_RTBones,
// 'iBPV', // Sem_BonesPerVertex,
// 'vVPS', // Sem_ViewportPixelSize,
// 'tSIZ', // Sem_TexelSize,
// 'SIZ0', // Sem_TexelSize0,
// 'SIZ1', // Sem_TexelSize1,
// 'SIZ2', // Sem_TexelSize2,
// 'SIZ3', // Sem_TexelSize3,
// 'vBIC' // Sem_BonesIndexConstant
//};
//
//DWORD SemanticEnumToFourCC(DWORD iSem){
// DWORD d = g_SemanticEnumToFourCC[iSem];
// DWORD s = ntohl(d);
// return s;
//}
//
//#endif
//--------------------------------------------------------------------------------
void ParamMeaning::TouchDependentRenderStates(const MeaningProcessingInfo& iMPI)
{
static volatile bool bypass = false;
if (bypass) return;
TechniqueConstantSetupInfo &tech = m_PerTechniquePerPassConstantSetup[iMPI.techniqueIndex];
int currPassIndex = ((RCKShaderCG *) iMPI.shader->GetCKShader())->GetCurrentPassIndex();
for (XArray<CachedRenderStateBase *>::Iterator it = tech.m_DependentRenderStates.Begin(); it != tech.m_DependentRenderStates.End(); ++it)
{
CachedRenderStateBase &crs = **it;
if (!crs.NeedReeval) // already added ?
{
if (crs.ShaderManager)
{
crs.ShaderManager->AddPassModifiedRenderState(currPassIndex, &crs); // render state will be evaluated again at CommitChanges time.
}
crs.NeedReeval = true;
}
}
}
//--------------------------------------------------------------------------------
void ShaderCG::DetectShaderConstantOverlap(ParamMeaning &param, int techniqueIndex, int passIndex, int domain, XArray<bool> &usedCst)
{
if (!param.m_PerTechniquePerPassConstantSetup[techniqueIndex].m_ForceUseCGSetParameter)
{
const ParamMeaning::ConstantSetupInfo &csi = param.m_PerTechniquePerPassConstantSetup[techniqueIndex].m_PerPassConstantSetup[passIndex];
if (csi.m_ConstantIndex[domain] >= 0)
{
int lastCst = csi.m_ConstantIndex[domain] + csi.m_RowCount[domain];
while (lastCst > usedCst.Size())
{
usedCst.PushBack(false);
}
for (int index = csi.m_ConstantIndex[domain]; index < lastCst; ++index)
{
XASSERT(!usedCst[index]); // do not want overlap with another constant
usedCst[index] = true; // signal this constant as used
}
}
}
}
//--------------------------------------------------------------------------------
void ShaderCG::CheckConstantSetupInfoValid(int techniqueIndex, int passIndex)
{
// check that there are no register overlaps
for (int domain = 0; domain < NUMBER_OF_CG_DOMAIN; ++domain)
{
XArray<bool> usedCst;
for (XArray<ParamMeaning*>::Iterator it = m_Params.Begin(); it != m_Params.End(); ++it)
{
DetectShaderConstantOverlap(**it, techniqueIndex, passIndex, domain, usedCst);
}
for (XArray<ParamMeaning*>::Iterator it = m_ParamsPerPass.Begin(); it != m_ParamsPerPass.End(); ++it)
{
DetectShaderConstantOverlap(**it, techniqueIndex, passIndex, domain, usedCst);
}
for (XArray<ExposedParamMeaning*>::Iterator it = m_ExposedParams.Begin(); it != m_ExposedParams.End(); ++it)
{
DetectShaderConstantOverlap(**it, techniqueIndex, passIndex, domain, usedCst);
}
}
}
//--------------------------------------------------------------------------------
void ShaderCG::InitConstantSetupInfo(int techniqueIndex, int passIndex, const char *programString[NUMBER_OF_CG_DOMAIN], ShaderConstantStore *cstStore[NUMBER_OF_CG_DOMAIN])
{
for (XArray<ParamMeaning*>::Iterator it = m_Params.Begin(); it != m_Params.End(); ++it)
{
(*it)->InitConstantSetupInfo(techniqueIndex, passIndex, programString, cstStore);
}
for (XArray<ParamMeaning*>::Iterator it = m_ParamsPerPass.Begin(); it != m_ParamsPerPass.End(); ++it)
{
(*it)->InitConstantSetupInfo(techniqueIndex, passIndex, programString, cstStore);
}
for (XArray<ExposedParamMeaning*>::Iterator it = m_ExposedParams.Begin(); it != m_ExposedParams.End(); ++it)
{
(*it)->InitConstantSetupInfo(techniqueIndex, passIndex, programString, cstStore);
}
/*
#ifdef _DEBUG
CheckConstantSetupInfoValid(techniqueIndex, passIndex);
#endif
*/
}
//--------------------------------------------------------------------------------
void ShaderCG::DisableProgramConstantsWrapping(int techIndex)
{
for (XArray<ParamMeaning*>::Iterator it = m_Params.Begin(); it != m_Params.End(); ++it)
{
(*it)->DisableProgramConstantsWrapping(techIndex);
}
for (XArray<ParamMeaning*>::Iterator it = m_ParamsPerPass.Begin(); it != m_ParamsPerPass.End(); ++it)
{
(*it)->DisableProgramConstantsWrapping(techIndex);
}
for (XArray<ExposedParamMeaning*>::Iterator it = m_ExposedParams.Begin(); it != m_ExposedParams.End(); ++it)
{
(*it)->DisableProgramConstantsWrapping(techIndex);
}
}
//--------------------------------------------------------------------------------
int ShaderCG::ComputeMaxParamMeaningCstIndex(int techIndex, int passIndex, CGdomain domain)
{
int maxCstIndex = -1;
for (XArray<ParamMeaning*>::Iterator it = m_Params.Begin(); it != m_Params.End(); ++it)
{
maxCstIndex = XMax(maxCstIndex, (*it)->GetMaxCstIndex(techIndex, passIndex, domain));
}
for (XArray<ParamMeaning*>::Iterator it = m_ParamsPerPass.Begin(); it != m_ParamsPerPass.End(); ++it)
{
maxCstIndex = XMax(maxCstIndex, (*it)->GetMaxCstIndex(techIndex, passIndex, domain));
}
for (XArray<ExposedParamMeaning*>::Iterator it = m_ExposedParams.Begin(); it != m_ExposedParams.End(); ++it)
{
maxCstIndex = XMax(maxCstIndex, (*it)->GetMaxCstIndex(techIndex, passIndex, domain));
}
return maxCstIndex;
}
}