6529 lines
233 KiB
C++
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, ¶mPtr->x);
|
|
cgGLGetParameter1f(m_ParamDesc,¶mPtr->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 ¶m, 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;
|
|
}
|
|
|
|
|
|
|
|
}
|