///////////////////////////////////////////////////// // 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 ; aGetCKShader(); // XArray& inputStreamFormats = ckShader->GetInputStreamFormat(); // int b; // const int biggerParamsCount = inputStreamFormats.Size(); // for( b=0 ; b0x0900 // } // 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 ; passIndexExpectingAnnotation( 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 ; passIndexProcessCallBack( 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 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 &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 &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. "; 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. "; 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 ; aGetColumnType(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;iGetElementValue(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;iGetElement(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;iGetElement(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;iGetElement(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;iGetElementValue(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 &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 PerPassSamplerStage; // for each pass -> a bitfield giving to what stage that texture is bound (possibly to several stage with fixed pipeline) }; XClassArray 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 ; iSetVertexShaderConstantF( 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 ; iSetVertexShaderConstantF( 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 ; aGetViewpoint()->GetWorldMatrix()[3]; if( m_Referential ) m_Referential->InverseTransform( &cameraPos, &cameraPos ); for( int a=0 ; aGetInverseWorldMatrix(), iMPI.rc->GetViewpoint()->GetWorldMatrix() ); } else { cameraMat = iMPI.rc->GetViewpoint()->GetWorldMatrix(); } for( int a=0 ; aGetInverseWorldMatrix(), 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 ; aExpectingAnnotation( 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 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::Iterator it = m_Textures.Begin(); XHashTable::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 ; paramIndexGetSemanticIndexFromString( 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 ; am_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 ; am_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 ; am_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 ; paramIndexProcessCallBack( iMPI ); } //--- Parse all Function Meanings #if DIRECT3D_VERSION>=0x0900 || defined(macintosh) const int fctCount = m_Functs.Size(); for( int fctIndex=0 ; fctIndexProcessCallBack( 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 ; paramIndexProcessCallBack( 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& 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& 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 ; aGetManagerByGuid( 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=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=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;iGetCKShader())->GetCurrentPassIndex(); for (XArray::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 &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 usedCst; for (XArray::Iterator it = m_Params.Begin(); it != m_Params.End(); ++it) { DetectShaderConstantOverlap(**it, techniqueIndex, passIndex, domain, usedCst); } for (XArray::Iterator it = m_ParamsPerPass.Begin(); it != m_ParamsPerPass.End(); ++it) { DetectShaderConstantOverlap(**it, techniqueIndex, passIndex, domain, usedCst); } for (XArray::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::Iterator it = m_Params.Begin(); it != m_Params.End(); ++it) { (*it)->InitConstantSetupInfo(techniqueIndex, passIndex, programString, cstStore); } for (XArray::Iterator it = m_ParamsPerPass.Begin(); it != m_ParamsPerPass.End(); ++it) { (*it)->InitConstantSetupInfo(techniqueIndex, passIndex, programString, cstStore); } for (XArray::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::Iterator it = m_Params.Begin(); it != m_Params.End(); ++it) { (*it)->DisableProgramConstantsWrapping(techIndex); } for (XArray::Iterator it = m_ParamsPerPass.Begin(); it != m_ParamsPerPass.End(); ++it) { (*it)->DisableProgramConstantsWrapping(techIndex); } for (XArray::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::Iterator it = m_Params.Begin(); it != m_Params.End(); ++it) { maxCstIndex = XMax(maxCstIndex, (*it)->GetMaxCstIndex(techIndex, passIndex, domain)); } for (XArray::Iterator it = m_ParamsPerPass.Begin(); it != m_ParamsPerPass.End(); ++it) { maxCstIndex = XMax(maxCstIndex, (*it)->GetMaxCstIndex(techIndex, passIndex, domain)); } for (XArray::Iterator it = m_ExposedParams.Begin(); it != m_ExposedParams.End(); ++it) { maxCstIndex = XMax(maxCstIndex, (*it)->GetMaxCstIndex(techIndex, passIndex, domain)); } return maxCstIndex; } }