1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include "OSGConfig.h"
48 #include "OSGCgFXMaterial.h"
49 #include "OSGCgFXTechnique.h"
51 #include "OSGSceneFileHandler.h"
52 #include "OSGFileSystem.h"
53 #include "OSGImageFileHandler.h"
54 #include "OSGNameAttachment.h"
55 #include "OSGTextureObjChunk.h"
57 #include "OSGShaderVariableBool.h"
58 #include "OSGShaderVariableInt.h"
59 #include "OSGShaderVariableReal.h"
61 #include "OSGShaderVariableVec2f.h"
62 #include "OSGShaderVariableVec3f.h"
63 #include "OSGShaderVariableVec4f.h"
65 #include "OSGShaderVariableMatrix.h"
67 #include "OSGCgFXVariableTexObj.h"
71 /*! \class osg::CGFXMaterial
74 /***************************************************************************\
76 \***************************************************************************/
78 const std::string
CgFXMaterial::FALBACK_MATERIAL_TECHNIQUE_NAME
=
79 std::string("FALBACK_MATERIAL");
81 /***************************************************************************\
83 \***************************************************************************/
85 void CgFXMaterial::initMethod(InitPhase ePhase
)
87 Inherited::initMethod(ePhase
);
90 void CgFXMaterial::resolveLinks(void)
92 Inherited::resolveLinks();
95 /***************************************************************************\
97 \***************************************************************************/
99 /*-------------------------------------------------------------------------*\
101 \*-------------------------------------------------------------------------*/
103 /*----------------------- constructors & destructors ----------------------*/
105 CgFXMaterial::CgFXMaterial(void) :
110 _mDelayTextureExtraction(false),
111 _bForceUseFallback (false)
113 this->markFieldsThreadLocal ((Self::MapCacheFieldMask
|
114 Self::FallbackMaterialFieldMask
));
115 this->markFieldsClusterLocal((Self::MapCacheFieldMask
|
116 Self::FallbackMaterialFieldMask
));
119 CgFXMaterial::CgFXMaterial(const CgFXMaterial
&source
) :
123 _pTechIdx (source
._pTechIdx
),
124 _mDelayTextureExtraction(source
._mDelayTextureExtraction
),
125 _bForceUseFallback (source
._bForceUseFallback
)
127 this->markFieldsThreadLocal ((Self::MapCacheFieldMask
|
128 Self::FallbackMaterialFieldMask
));
129 this->markFieldsClusterLocal((Self::MapCacheFieldMask
|
130 Self::FallbackMaterialFieldMask
));
133 CgFXMaterial::~CgFXMaterial(void)
137 void CgFXMaterial::onCreate (const CgFXMaterial
*source
)
139 Inherited::onCreate(source
);
141 if(GlobalSystemState
== Startup
)
144 setGLId(Window::registerGLObject(
145 boost::bind(&CgFXMaterial::handleGL
,
146 CgFXMaterialMTUncountedPtr(this),
148 &CgFXMaterial::handleDestroyGL
));
151 void CgFXMaterial::onDestroy(UInt32 uiContainerId
)
154 Window::destroyGLObject(getGLId(), 1);
156 Inherited::onDestroy(uiContainerId
);
159 bool CgFXMaterial::isTransparent(void) const
161 // not sure, CHECK_TOOLBOX_MERGE
167 UInt32
CgFXMaterial::handleGL(DrawEnv
*pEnv
,
169 Window::GLObjectStatusE mode
,
173 if(mode
== Window::initialize
)
175 Window::GLObjectId glId
=
176 reinterpret_cast<Window::GLObjectId
>(_pCGcontext
);
178 pEnv
->getWindow()->setGLObjectId(osgId
, glId
);
180 #if OSG_CGFX_DUMP_DEBUG
181 fprintf( stderr
, "setting gl id %" PRIUSize
" | %p\n",
186 else if(mode
== Window::reinitialize
)
188 //Window::GLObjectId oldGlId = pEnv->getWindow()->getGLObjectId(osgId);
190 //Window::GLObjectId glId =
191 //reinterpret_cast<Window::GLObjectId>(_pCGcontext);
193 //OSG_ASSERT(oldGlId != glId);
195 //CGcontext pOldCGcontext = reinterpret_cast<CGcontext>(oldGlId);
197 //#if OSG_CGFX_DUMP_DEBUG
198 //fprintf(stderr, "destroying gl id %"PRIUSize" | %p\n",
203 //if(pOldCGcontext != NULL)
205 //cgDestroyContext(pOldCGcontext);
208 //pEnv->getWindow()->setGLObjectId(osgId, glId);
210 //#if OSG_CGFX_DUMP_DEBUG
211 //fprintf(stderr, "setting gl id %"PRIUSize" | %p\n",
220 void CgFXMaterial::handleDestroyGL(DrawEnv
*pEnv
,
222 Window::GLObjectStatusE mode
)
224 Window
* win
= pEnv
->getWindow();
226 if(mode
== Window::destroy
)
228 Window::GLObjectId glId
= win
->getGLObjectId(osgId
);
230 CGcontext pCGcontext
= reinterpret_cast<CGcontext
>(glId
);
232 fprintf(stderr
, "destroying gl id %" PRIUSize
"\n",
235 if(pCGcontext
!= NULL
)
237 cgDestroyContext(pCGcontext
);
239 CgFXMaterial::checkForCgError("cgDestroyContext", NULL
);
242 win
->setGLObjectId(osgId
, 0);
246 /*----------------------------- class specific ----------------------------*/
248 void CgFXMaterial::changed(ConstFieldMaskArg whichField
,
253 if(0x0000 != (whichField
& EffectFileFieldMask
))
255 this->readEffectFile();
258 if(0x0000 != (whichField
& SelectedTechniqueFieldMask
))
260 this->setActiveTechnique(getSelectedTechnique());
263 if(0x0000 != (whichField
& EffectStringFieldMask
))
265 //Inherited::resolveLinks();
267 this->processEffectString();
269 Window::reinitializeGLObject(getGLId());
272 if(0x0000 != (whichField
& VariablesFieldMask
))
276 updateUniformVariables();
280 if(0x0000 != (whichField
& TechniquesFieldMask
) ||
281 0x0000 != (whichField
& SortKeyFieldMask
))
283 //Update the sort key of all the techniques
284 MFTechniquesType::const_iterator tIt
= _mfTechniques
.begin();
285 MFTechniquesType::const_iterator tEnd
= _mfTechniques
.end ();
287 for(; tIt
!= tEnd
; ++tIt
)
289 (*tIt
)->setSortKey(getSortKey());
293 if(0x0000 != (whichField
& (TreatTechniquesAsVariantsFieldMask
|
294 TechniquesFieldMask
)))
296 Inherited::clearElements();
298 if(getTreatTechniquesAsVariants() == true)
300 Inherited::addElement(getFallbackMaterial(),
301 RenderPropertiesPool::the()->getDefault());
303 MaterialMapKey TechniqueKey
;
305 std::vector
<std::string
> TechNames
= getAvailableTechniques();
307 for(UInt32 i
= 0; i
< TechNames
.size(); ++i
)
310 RenderPropertiesPool::the()->getFrom1(TechNames
[i
].c_str());
312 Inherited::addElement(getTechnique(TechNames
[i
]), TechniqueKey
);
317 Inherited::changed(whichField
, origin
, detail
);
320 void CgFXMaterial::dump( UInt32
,
321 const BitVector
) const
323 SLOG
<< "Dump CgFXMaterial NI" << std::endl
;
326 PrimeMaterial
*CgFXMaterial::finalize( MaterialMapKey oKey
,
327 const StateOverride
*pOverrides
,
330 PrimeMaterial
*returnValue
= NULL
;
335 if(_bForceUseFallback
== true)
336 return getFallbackMaterial();
340 oEnv
.setWindow(pWin
);
342 pWin
->validateGLObject(getGLId(), &oEnv
);
344 if(getTreatTechniquesAsVariants() == true)
346 returnValue
= Inherited::finalize(oKey
, pOverrides
, pWin
);
348 if((dynamic_cast<CgFXTechnique
*>(returnValue
) == NULL
) ||
349 (dynamic_cast<CgFXTechnique
*>(returnValue
)->validate(this, &oEnv
)))
356 if(_pTechIdx
< _mfTechniques
.size() &&
357 _mfTechniques
[_pTechIdx
]->validate(this, &oEnv
) == true)
359 return _mfTechniques
[_pTechIdx
];
363 // If the selected technique did not validate, pick the first one that
365 MFTechniquesType::const_iterator tIt
= _mfTechniques
.begin();
366 MFTechniquesType::const_iterator tEnd
= _mfTechniques
.end ();
368 for(; tIt
!= tEnd
; ++tIt
)
370 if((*tIt
)->validate(this, &oEnv
) == true)
381 /*---------------------------------- Access -------------------------------*/
384 /*------------------------------------ Set --------------------------------*/
386 bool CgFXMaterial::checkForCgError(const Char8
*szSituation
,
387 CGcontext pCGcontext
)
391 //Get the last error string and value
392 const Char8
*string
= cgGetLastErrorString(&error
);
395 if(error
!= CG_NO_ERROR
)
398 SWARNING
<< "CgfxMaterial Cgfx Error: " << szSituation
<< ": "
399 << string
<< std::endl
;
401 //Give more detailed informatino if there was a compile error
402 if(error
== CG_COMPILER_ERROR
)
404 SWARNING
<< cgGetLastListing(pCGcontext
) << std::endl
;
416 /*------------------------------------ Get --------------------------------*/
418 void CgFXMaterial::readEffectFile(void)
421 if(_sfEffectFile
.getValue().empty() == true)
424 const Char8
*szTmpCurrentDir
= Directory::getCurrent();
426 std::string szCurrentDir
= szTmpCurrentDir
;
428 delete [] szTmpCurrentDir
;
430 PathHandler
*pPathHandler
= SceneFileHandler::the()->getPathHandler();
432 std::string szFullFilePath
;
434 if(pPathHandler
!= NULL
)
436 pPathHandler
->pushState();
438 pPathHandler
->push_backPath(".");
439 pPathHandler
->push_backPath(szCurrentDir
.c_str());
442 pPathHandler
->findFile(_sfEffectFile
.getValue().c_str());
444 pPathHandler
->popState();
448 szFullFilePath
= _sfEffectFile
.getValue();
452 fprintf(stderr
, "Read effect from %s\n",
453 szFullFilePath
.c_str());
456 std::string szPath
= szFullFilePath
;
458 while(szPath
.length() > 0 &&
459 szPath
[szPath
.length() - 1] != '/' &&
460 szPath
[szPath
.length() - 1] != '\\' )
462 szPath
.resize(szPath
.length() - 1);
469 fprintf(stderr
, "use path %s\n", szPath
.c_str());
472 FILE *pFile
= fopen(szFullFilePath
.c_str(), "rb");
477 fseek(pFile
, 0, SEEK_END
);
479 long lFileSize
= ftell(pFile
);
481 fseek(pFile
, 0, SEEK_SET
);
483 std::string
&szData
= editEffectString();
486 szData
.resize(lFileSize
);
488 fread(&(szData
[0]), 1, lFileSize
, pFile
);
493 void CgFXMaterial::initContext(void)
495 checkForCgError("precheck", _pCGcontext
);
497 if(_pCGcontext
!= NULL
)
499 //Already initialized
503 _pCGcontext
= cgCreateContext();
505 if( checkForCgError("Creating Cg Context", _pCGcontext
) == true ||
506 _pCGcontext
== NULL
)
511 cgGLRegisterStates (_pCGcontext
);
512 cgGLSetManageTextureParameters(_pCGcontext
, CG_TRUE
);
514 if(checkForCgError("Registering GL States", _pCGcontext
) == true)
520 #if CG_VERSION_NUM >= 2100
521 registerIncludeCallback( (OSGCGcontext
)context
, this );
522 cgSetCompilerIncludeCallback( context
,
523 CgFXMaterial::checkForCgError("",
525 (CGIncludeCallbackFunc
)cgIncludeCallback
);
530 void CgFXMaterial::processEffectString(void)
532 checkForCgError("precheck", _pCGcontext
);
534 if(_sfEffectString
.getValue().empty() == true)
539 // we have to transform _compilerOptions to an array of
540 // const char* to feed it to cgCreateEffect
541 std::vector
<const char *> vOptions(_mfCompilerOptions
.size());
543 for(UInt32 i
= 0; i
< _mfCompilerOptions
.size(); ++i
)
544 vOptions
[i
] = _mfCompilerOptions
[i
].c_str();
546 vOptions
.push_back(NULL
);
548 const char **pRawOptions
= &(vOptions
[0]);
550 if(_pCGeffect
!= NULL
)
553 cgDestroyEffect(_pCGeffect
);
555 if( checkForCgError("Destroying Cg Effect", _pCGcontext
) == true ||
562 _pCGeffect
= cgCreateEffect(_pCGcontext
,
563 _sfEffectString
.getValue().c_str(),
566 if( checkForCgError("Creating Cg Effect", _pCGcontext
) == true ||
572 //Any Compile warnings
573 const char *CompileWarnings
= cgGetLastListing(_pCGcontext
);
575 if(CompileWarnings
!= NULL
)
577 SWARNING
<< CompileWarnings
<< std::endl
;
580 CGtechnique pFirstTechnique
= cgGetFirstTechnique(_pCGeffect
);
582 CgFXMaterial::checkForCgError("pFirstTechnique", _pCGcontext
);
584 if(pFirstTechnique
== NULL
)
587 CGannotation pVarAnno
=
588 cgGetNamedTechniqueAnnotation(pFirstTechnique
,
589 "treatTechniqueAsVariant");
591 CgFXMaterial::checkForCgError("cgGetNamedTechniqueAnnotation", _pCGcontext
);
596 fprintf(stderr
, "got var anno\n");
601 const int *pTechVar
= cgGetBooleanAnnotationValues( pVarAnno
,
604 CgFXMaterial::checkForCgError("cgGetBooleanAnnotationValues",
610 fprintf(stderr
, "got tech var : %d\n", *pTechVar
);
613 setTreatTechniquesAsVariants((*pTechVar
) != 0);
617 // we might not want to extract the parameters just yet,
618 // check if this is the case and if so, skip parameter extraction
621 CGtechnique pCGTech
= cgGetFirstTechnique(_pCGeffect
);
623 CgFXMaterial::checkForCgError("cgGetFirstTechnique", _pCGcontext
);
625 //Remove previous techniques
628 while(pCGTech
!= NULL
)
631 SLOG
<< "add Technique : "
632 << cgGetTechniqueName(pCGTech
) << std::endl
;
635 CgFXTechniqueUnrecPtr pTechnique
= CgFXTechnique::create();
637 pTechnique
->setTechnique(pCGTech
);
639 this->pushToTechniques(pTechnique
);
641 pCGTech
= cgGetNextTechnique(pCGTech
);
643 CgFXMaterial::checkForCgError("cgGetNextTechnique", _pCGcontext
);
646 setActiveTechnique(getSelectedTechnique());
649 CgFXTechnique
*CgFXMaterial::getTechnique(
650 const std::string
& techniqueName
) const
652 CGtechnique tech
= cgGetNamedTechnique(_pCGeffect
, techniqueName
.c_str());
654 CgFXMaterial::checkForCgError("cgGetNamedTechnique", _pCGcontext
);
658 for(UInt32 i
= 0; i
< _mfTechniques
.size(); ++i
)
660 if(tech
== getTechniques(i
)->_pCGTechnique
)
662 return getTechniques(i
);
670 bool CgFXMaterial::setActiveTechnique(const std::string
&techniqueName
)
672 // if we don't have a valid effect yet, store the string and try
673 // again after the effect is loaded up.
674 if(_pCGeffect
== NULL
&& getSelectedTechnique() != techniqueName
)
676 editSelectedTechnique() = techniqueName
;
678 // is this a valid technique name?
679 CGtechnique pTech
= cgGetNamedTechnique(_pCGeffect
, techniqueName
.c_str());
681 CgFXMaterial::checkForCgError("cgGetNamedTechnique", _pCGcontext
);
684 { // if so, find the index of the technique to use for this material
685 for(_pTechIdx
= 0; _pTechIdx
< _mfTechniques
.size(); ++_pTechIdx
)
687 if(pTech
== _mfTechniques
[_pTechIdx
]->_pCGTechnique
)
689 _bForceUseFallback
= false;
695 _bForceUseFallback
= false;
699 else if(techniqueName
.compare(FALBACK_MATERIAL_TECHNIQUE_NAME
) == 0)
701 //Special case: if the Technique is the Fallback material technique
702 //name. Then disable CgFX and use the fallback material
704 _bForceUseFallback
= true;
710 // if the technique name wasn't valid, we just use
711 // the default behavior (use the first valid technique)
713 _bForceUseFallback
= false;
720 * Function to get the names of all of the available techniques for this
724 std::vector
<std::string
> CgFXMaterial::getAvailableTechniques(void) const
726 std::vector
<std::string
> techNames
;
728 for(UInt32 i
= 0; i
< _mfTechniques
.size(); ++i
)
730 std::string curTechName
=
731 cgGetTechniqueName(_mfTechniques
[i
]->_pCGTechnique
);
733 CgFXMaterial::checkForCgError("cgGetTechniqueName", _pCGcontext
);
735 if(curTechName
.compare("") != 0)
736 techNames
.push_back(curTechName
);
742 void CgFXMaterial::extractParameters(void)
745 #if OSG_CGFX_DUMP_DEBUG
746 checkForCgError("extract precheck", _pCGcontext
);
749 CGparameter pParam
= cgGetFirstEffectParameter(_pCGeffect
);
751 CgFXMaterial::checkForCgError("cgGetFirstEffectParameter", _pCGcontext
);
756 #if OSG_CGFX_DUMP_DEBUG
757 fprintf(stderr
, "Effect parameter : \n");
760 editStateVariables() = 0x0000;
765 CGtype oParamType
= cgGetParameterType (pParam
);
767 CgFXMaterial::checkForCgError("cgGetParameterType", _pCGcontext
);
769 UInt32 uiNumRows
= cgGetParameterRows (pParam
);
771 CgFXMaterial::checkForCgError("cgGetParameterRows", _pCGcontext
);
773 UInt32 uiNumCols
= cgGetParameterColumns(pParam
);
775 CgFXMaterial::checkForCgError("cgGetParameterColumns", _pCGcontext
);
777 UInt32 uiNumComponents
= uiNumRows
* uiNumCols
;
779 std::string szParamName
=
780 cgGetParameterName(pParam
) ? cgGetParameterName(pParam
) : "";
782 std::string szParamSemantic
=
783 cgGetParameterSemantic(pParam
) ? cgGetParameterSemantic(pParam
): "";
786 if(szParamSemantic
.empty() == false)
788 bool bFoundSemanticParam
= false;
790 if(osgStringCaseCmp(szParamSemantic
.c_str(), "PROJECTION") == 0)
792 editStateVariables() |= CgProjectionMask
;
794 _vStateVarNames
[CgProjection
] = szParamName
;
796 bFoundSemanticParam
= true;
799 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
800 "WORLDVIEWPROJECTION" ) == 0)
802 editStateVariables() |= CgModelViewProjectionMask
;
804 _vStateVarNames
[CgModelViewProjection
] = szParamName
;
806 bFoundSemanticParam
= true;
808 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
809 "MODELVIEWPROJECTION" ) == 0)
811 editStateVariables() |= CgModelViewProjectionMask
;
813 _vStateVarNames
[CgModelViewProjection
] = szParamName
;
815 bFoundSemanticParam
= true;
822 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "WORLD") == 0)
824 editStateVariables() |= CgModelMask
;
826 _vStateVarNames
[CgModel
] = szParamName
;
828 bFoundSemanticParam
= true;
830 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "WORLDI") == 0)
832 editStateVariables() |= CgModelIMask
;
834 _vStateVarNames
[CgModelI
] = szParamName
;
836 bFoundSemanticParam
= true;
838 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
839 "WORLDINVERSE") == 0 )
841 editStateVariables() |= CgModelIMask
;
843 _vStateVarNames
[CgModelI
] = szParamName
;
845 bFoundSemanticParam
= true;
847 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "WORLDIT") == 0)
849 editStateVariables() |= CgModelITMask
;
851 _vStateVarNames
[CgModelIT
] = szParamName
;
853 bFoundSemanticParam
= true;
855 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
856 "WORLDINVERSETRANSPOSE") == 0)
858 editStateVariables() |= CgModelITMask
;
860 _vStateVarNames
[CgModelIT
] = szParamName
;
862 bFoundSemanticParam
= true;
869 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "MODEL") == 0)
871 editStateVariables() |= CgModelMask
;
873 _vStateVarNames
[CgModel
] = szParamName
;
875 bFoundSemanticParam
= true;
877 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "MODELI") == 0)
879 editStateVariables() |= CgModelIMask
;
881 _vStateVarNames
[CgModelI
] = szParamName
;
883 bFoundSemanticParam
= true;
885 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
886 "MODELINVERSE" ) == 0)
888 editStateVariables() |= CgModelIMask
;
890 _vStateVarNames
[CgModelI
] = szParamName
;
892 bFoundSemanticParam
= true;
894 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "MODELIT") == 0)
896 editStateVariables() |= CgModelITMask
;
898 _vStateVarNames
[CgModelIT
] = szParamName
;
900 bFoundSemanticParam
= true;
902 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
903 "MODELINVERSERTRANSPOSE") == 0)
905 editStateVariables() |= CgModelITMask
;
907 _vStateVarNames
[CgModelIT
] = szParamName
;
909 bFoundSemanticParam
= true;
916 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "WORLDVIEW") == 0)
918 editStateVariables() |= CgModelViewMask
;
920 _vStateVarNames
[CgModelView
] = szParamName
;
922 bFoundSemanticParam
= true;
924 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
927 editStateVariables() |= CgModelViewIMask
;
929 _vStateVarNames
[CgModelViewI
] = szParamName
;
931 bFoundSemanticParam
= true;
933 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
934 "WORLDVIEWINVERSE" ) == 0)
936 editStateVariables() |= CgModelViewIMask
;
938 _vStateVarNames
[CgModelViewI
] = szParamName
;
940 bFoundSemanticParam
= true;
942 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
943 "WORLDVIEWIT" ) == 0)
945 editStateVariables() |= CgModelViewITMask
;
947 _vStateVarNames
[CgModelViewIT
] = szParamName
;
949 bFoundSemanticParam
= true;
951 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
952 "WORLDVIEWINVERSETRANSPOSE") == 0)
954 editStateVariables() |= CgModelViewITMask
;
956 _vStateVarNames
[CgModelViewIT
] = szParamName
;
958 bFoundSemanticParam
= true;
965 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "MODELVIEW") == 0)
967 editStateVariables() |= CgModelViewMask
;
969 _vStateVarNames
[CgModelView
] = szParamName
;
971 bFoundSemanticParam
= true;
973 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
976 editStateVariables() |= CgModelViewIMask
;
978 _vStateVarNames
[CgModelViewI
] = szParamName
;
980 bFoundSemanticParam
= true;
982 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
983 "MODELVIEWINVERSE" ) == 0)
985 editStateVariables() |= CgModelViewIMask
;
987 _vStateVarNames
[CgModelViewI
] = szParamName
;
989 bFoundSemanticParam
= true;
991 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
992 "MODELVIEWIT" ) == 0)
994 editStateVariables() |= CgModelViewITMask
;
996 _vStateVarNames
[CgModelViewIT
] = szParamName
;
998 bFoundSemanticParam
= true;
1000 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
1001 "MODELVIEWINVERSETRANSPOSE") == 0)
1003 editStateVariables() |= CgModelViewITMask
;
1005 _vStateVarNames
[CgModelViewIT
] = szParamName
;
1007 bFoundSemanticParam
= true;
1014 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "VIEW") == 0)
1016 editStateVariables() |= CgViewMask
;
1018 _vStateVarNames
[CgView
] = szParamName
;
1020 bFoundSemanticParam
= true;
1022 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "VIEWI") == 0)
1024 editStateVariables() |= CgViewIMask
;
1026 _vStateVarNames
[CgViewI
] = szParamName
;
1028 bFoundSemanticParam
= true;
1030 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
1031 "VIEWINVERSE" ) == 0)
1033 editStateVariables() |= CgViewIMask
;
1035 _vStateVarNames
[CgViewI
] = szParamName
;
1037 bFoundSemanticParam
= true;
1039 else if(osgStringCaseCmp(szParamSemantic
.c_str(), "VIEWIT") == 0)
1041 editStateVariables() |= CgViewITMask
;
1043 _vStateVarNames
[CgViewIT
] = szParamName
;
1045 bFoundSemanticParam
= true;
1047 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
1048 "VIEWINVERSETRANSPOSE" ) == 0)
1050 editStateVariables() |= CgViewITMask
;
1052 _vStateVarNames
[CgViewIT
] = szParamName
;
1054 bFoundSemanticParam
= true;
1057 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
1058 "VIEWPROJECTION" ) == 0)
1060 editStateVariables() |= CgViewProjectionMask
;
1062 _vStateVarNames
[CgViewProjection
] = szParamName
;
1064 bFoundSemanticParam
= true;
1070 else if(osgStringCaseCmp(szParamSemantic
.c_str(),
1073 editStateVariables() |= CgTimeMask
;
1075 _vStateVarNames
[CgTime
] = szParamName
;
1077 bFoundSemanticParam
= true;
1080 if(bFoundSemanticParam
== true)
1082 pParam
= cgGetNextParameter(pParam
);
1084 CgFXMaterial::checkForCgError("cgGetNextParameter",
1096 if(cgGetParameterValueir(pParam
, 1, &val
) == 1)
1098 // check where what values we should be using
1099 if(this->getParameterValueSource() == CURRENT
)
1100 { // check if this is already a variable
1104 if(this->getUniformVariable(szParamName
.c_str(), tmp
))
1105 { // if it is, set the variable to value we already
1107 cgSetParameterValueir( pParam
,
1111 CgFXMaterial::checkForCgError(
1112 "cgSetParameterValueir", _pCGcontext
);
1114 } // otherwise use the default value
1117 this->addUniformVariable(szParamName
.c_str(),
1121 else // use default value from .cgfx file
1123 this->addUniformVariable(szParamName
.c_str(),
1134 if(cgGetParameterValueir(pParam
, 1, &val
) == 1)
1136 // check where what values we should be using
1137 if(this->getParameterValueSource() == CURRENT
)
1138 { // check if this is already a variable
1140 if(this->getUniformVariable(szParamName
.c_str(), tmp
))
1141 { // if it is, set the variable to value we already
1143 cgSetParameterValueir( pParam
,
1147 CgFXMaterial::checkForCgError(
1148 "cgSetParameterValueir", _pCGcontext
);
1150 } // otherwise use the default value
1153 this->addUniformVariable(szParamName
.c_str(),
1157 else // use default value from .cgfx file
1159 this->addUniformVariable(szParamName
.c_str(), val
);
1171 switch(uiNumComponents
)
1177 if(cgGetParameterValuefr(pParam
, 1, &val
) == 1)
1179 // check where what values we should be using
1180 if(this->getParameterValueSource() == CURRENT
)
1181 { // check if this is already a variable
1184 if(this->getUniformVariable(
1185 szParamName
.c_str(),
1187 { // if it is, set the variable to value we
1188 // already have for it.
1189 cgSetParameterValuefr( pParam
,
1193 CgFXMaterial::checkForCgError(
1194 "cgSetParameterValuefr", _pCGcontext
);
1195 } // otherwise use the default value
1198 this->addUniformVariable(
1199 szParamName
.c_str(),
1203 else // use default value from .cgfx file
1205 this->addUniformVariable(szParamName
.c_str(),
1216 if(cgGetParameterValuefr(pParam
,
1218 val
.getValues()) == 2)
1220 // check where what values we should be using
1221 if(this->getParameterValueSource() == CURRENT
)
1222 { // check if this is already a variable
1224 if(this->getUniformVariable(
1225 szParamName
.c_str(),
1227 { // if it is, set the variable to value we
1228 // already have for it.
1229 cgSetParameterValuefr(pParam
,
1233 CgFXMaterial::checkForCgError(
1234 "cgSetParameterValuefr", _pCGcontext
);
1235 } // otherwise use the default value
1238 this->addUniformVariable(
1239 szParamName
.c_str(),
1243 else // use default value from .cgfx file
1245 this->addUniformVariable(szParamName
.c_str(),
1256 if(cgGetParameterValuefr(pParam
,
1258 val
.getValues()) == 3)
1260 // check where what values we should be using
1261 if(this->getParameterValueSource() == CURRENT
)
1262 { // check if this is already a variable
1264 if(this->getUniformVariable(
1265 szParamName
.c_str(),
1267 { // if it is, set the variable to value we
1268 // already have for it.
1269 cgSetParameterValuefr(pParam
,
1273 CgFXMaterial::checkForCgError(
1274 "cgSetParameterValuefr", _pCGcontext
);
1275 } // otherwise use the default value
1278 this->addUniformVariable(
1279 szParamName
.c_str(),
1283 else // use default value from .cgfx file
1285 this->addUniformVariable(szParamName
.c_str(),
1296 if(cgGetParameterValuefr(pParam
,
1298 val
.getValues()) == 4)
1300 // check where what values we should be using
1301 if(this->getParameterValueSource() == CURRENT
)
1302 { // check if this is already a variable
1304 if(this->getUniformVariable(
1305 szParamName
.c_str(),
1307 { // if it is, set the variable to value we
1308 // already have for it.
1309 cgSetParameterValuefr(pParam
,
1313 CgFXMaterial::checkForCgError(
1314 "cgSetParameterValuefr", _pCGcontext
);
1315 } // otherwise use the default value
1318 this->addUniformVariable(
1319 szParamName
.c_str(),
1323 else // use default value from .cgfx file
1325 this->addUniformVariable(szParamName
.c_str(),
1334 // CHECK cgSetParameterValuefr or cgSetParameterValuefc
1337 if(cgGetParameterValuefr(pParam
,
1339 val
.getValues()) == 16)
1342 // check where what values we should be using
1343 if(this->getParameterValueSource() == CURRENT
)
1344 { // check if this is already a variable
1346 if(this->getUniformVariable(
1347 szParamName
.c_str(),
1349 { // if it is, set the variable to value we
1350 // already have for it.
1351 cgSetParameterValuefr(pParam
,
1355 CgFXMaterial::checkForCgError(
1356 "cgSetParameterValuefr", _pCGcontext
);
1357 } // otherwise use the default value
1360 this->addUniformVariable(
1361 szParamName
.c_str(),
1365 else // use default value from .cgfx file
1367 this->addUniformVariable(szParamName
.c_str(),
1383 case CG_SAMPLERRECT
:
1384 case CG_SAMPLERCUBE
:
1386 CgFXVariableTexObjUnrecPtr pVar
;
1387 std::string szFilename
;
1388 bool varIsInitialized
= false;
1389 bool readFile
= true;
1391 if(this->getParameterValueSource() == CURRENT
)
1393 if(this->getVariable(szParamName
.c_str()) != NULL
)
1394 { // use the specified texture
1396 dynamic_cast<const CgFXVariableTexObj
*>(
1398 szParamName
.c_str()))->getFilePath();
1400 varIsInitialized
= true;
1402 for(UInt32 i
= 0; i
< getMFTextures()->size(); ++i
)
1404 if(szParamName
.compare(
1405 getName(getTextures(i
))) == 0)
1406 { // image file is already loaded and ready to
1407 // use, so skip reading it again.
1415 if(szFilename
.empty())
1417 CGannotation pAnno
= cgGetNamedParameterAnnotation(pParam
,
1420 CgFXMaterial::checkForCgError(
1421 "cgGetNamedParameterAnnotation", _pCGcontext
);
1425 pAnno
= cgGetNamedParameterAnnotation(pParam
,
1428 CgFXMaterial::checkForCgError(
1429 "cgGetNamedParameterAnnotation", _pCGcontext
);
1434 szFilename
= cgGetStringAnnotationValue(pAnno
);
1436 CgFXMaterial::checkForCgError(
1437 "cgGetStringAnnotationValue", _pCGcontext
);
1441 if(szFilename
.empty())
1443 CGstateassignment pSamplerState
=
1444 cgGetFirstSamplerStateAssignment(pParam
);
1446 CgFXMaterial::checkForCgError(
1447 "cgGetFirstSamplerStateAssignment", _pCGcontext
);
1449 if(pSamplerState
!= NULL
)
1451 // cgGetSamplerStateAssignmentValue
1452 CGparameter pTParam
=
1453 cgGetTextureStateAssignmentValue(pSamplerState
);
1455 CgFXMaterial::checkForCgError(
1456 "cgGetTextureStateAssignmentValue", _pCGcontext
);
1460 CGtype pTParamType
= cgGetParameterType(pTParam
);
1462 CgFXMaterial::checkForCgError(
1463 "cgGetParameterType", _pCGcontext
);
1465 // get tweakable parameters
1466 if(cgGetFirstParameterAnnotation(pTParam
) != NULL
&&
1467 pTParamType
== CG_TEXTURE
)
1469 CGannotation pAnno
=
1470 cgGetNamedParameterAnnotation(pTParam
,
1473 CgFXMaterial::checkForCgError(
1474 "cgGetNamedParameterAnnotation",
1480 cgGetNamedParameterAnnotation(
1484 CgFXMaterial::checkForCgError(
1485 "cgGetNamedParameterAnnotation",
1492 cgGetStringAnnotationValue(pAnno
);
1494 CgFXMaterial::checkForCgError(
1495 "cgGetStringAnnotationValue",
1505 Int32 uiSamplerId
= -1;
1507 ImageUnrecPtr pImg
=
1508 ImageFileHandler::the()->read(szFilename
.c_str());
1512 TextureObjChunkUnrecPtr pTexO
=
1513 TextureObjChunk::create();
1515 setName(pTexO
, szParamName
);
1517 pTexO
->setImage(pImg
);
1519 this->pushToTextures(pTexO
);
1523 MFTexturesType::const_iterator TexIt
=
1524 this->getMFTextures()->begin();
1526 for(; TexIt
!= getMFTextures()->end(); ++TexIt
)
1528 if(szParamName
.compare(getName(*TexIt
)) == 0)
1530 pImg
= (*TexIt
)->getImage();
1536 if(pImg
!= NULL
&& varIsInitialized
== false)
1538 pVar
= CgFXVariableTexObj::create();
1540 pVar
->setName (szParamName
);
1541 this->addVariable(pVar
);
1542 pVar
->setValue (uiSamplerId
);
1565 FWARNING(("CgFXMaterial : Unsupported parameter (%s) type "
1567 szParamName
.c_str(),
1573 pParam
= cgGetNextParameter(pParam
);
1574 CgFXMaterial::checkForCgError("cgGetNextParameter", _pCGcontext
);
1577 #if OSG_CGFX_DUMP_DEBUG
1578 checkForCgError("extract postcheck", _pCGcontext
);
1582 void CgFXMaterial::updateUniformVariables(void)
1584 #if OSG_CGFX_DUMP_DEBUG
1585 checkForCgError("update precheck", _pCGcontext
);
1588 if(_pCGeffect
== NULL
)
1589 return; // can't update variables w/out a program.
1591 const ShaderProgramVariables::MFVariablesType
*pMFVars
= NULL
;
1592 ShaderProgramVariables::MFVariableChangedType
*pMFVarChg
= NULL
;
1594 if(_sfVariables
.getValue() != NULL
)
1596 pMFVars
= _sfVariables
.getValue()->getMFVariables ();
1597 pMFVarChg
= _sfVariables
.getValue()->editMFVariableChanged();
1600 if(pMFVars
== NULL
|| pMFVars
->size() == 0 || pMFVarChg
== NULL
)
1605 OSG_ASSERT(pMFVars
->size() == pMFVarChg
->size());
1607 ShaderProgramVariables::MFVariablesType::const_iterator mVarIt
=
1609 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd
=
1612 ShaderProgramVariables::MFVariableChangedType::iterator mVarChgIt
=
1615 for(; mVarIt
!= mVarEnd
; ++mVarIt
, ++mVarChgIt
)
1617 ShaderVariable
*pVar
= *mVarIt
;
1622 if(*mVarChgIt
== false)
1627 CGparameter pParam
=
1628 cgGetNamedEffectParameter(_pCGeffect
,
1629 pVar
->getName().c_str());
1631 CgFXMaterial::checkForCgError("cgGetNamedEffectParameter",
1634 switch(pVar
->getTypeId())
1636 case ShaderVariable::SHVTypeBool
:
1638 ShaderVariableBool
*p
=
1639 dynamic_cast<ShaderVariableBool
*>(pVar
);
1641 cgSetParameter1i(pParam
, p
->getValue() ? 1 : 0);
1643 CgFXMaterial::checkForCgError("cgSetParameter1i", _pCGcontext
);
1647 case ShaderVariable::SHVTypeInt
:
1649 ShaderVariableInt
*p
=
1650 dynamic_cast<ShaderVariableInt
*>(pVar
);
1652 cgSetParameter1i(pParam
, p
->getValue());
1654 CgFXMaterial::checkForCgError("cgSetParameter1i", _pCGcontext
);
1658 case ShaderVariable::SHVTypeReal
:
1660 ShaderVariableReal
*p
=
1661 dynamic_cast<ShaderVariableReal
*>(pVar
);
1663 cgSetParameter1f(pParam
, p
->getValue());
1665 CgFXMaterial::checkForCgError("cgSetParameter1f", _pCGcontext
);
1669 case ShaderVariable::SHVTypeVec2f
:
1671 ShaderVariableVec2f
*p
=
1672 dynamic_cast<ShaderVariableVec2f
*>(pVar
);
1674 cgSetParameter2fv(pParam
, p
->getValue().getValues());
1676 CgFXMaterial::checkForCgError("cgSetParameter2fv", _pCGcontext
);
1680 case ShaderVariable::SHVTypeVec3f
:
1682 ShaderVariableVec3f
*p
=
1683 dynamic_cast<ShaderVariableVec3f
*>(pVar
);
1685 cgSetParameter3fv(pParam
, p
->getValue().getValues());
1687 CgFXMaterial::checkForCgError("cgSetParameter3fv", _pCGcontext
);
1691 case ShaderVariable::SHVTypeVec4f
:
1693 ShaderVariableVec4f
*p
=
1694 dynamic_cast<ShaderVariableVec4f
*>(pVar
);
1696 cgSetParameter4fv(pParam
, p
->getValue().getValues());
1698 CgFXMaterial::checkForCgError("cgSetParameter4fv", _pCGcontext
);
1702 case ShaderVariable::SHVTypeMatrix
:
1704 ShaderVariableMatrix
*p
=
1705 dynamic_cast<ShaderVariableMatrix
*>(pVar
);
1707 cgSetMatrixParameterfr(pParam
, p
->getValue().getValues());
1709 CgFXMaterial::checkForCgError("cgSetMatrixParameterfr",
1719 #if OSG_CGFX_DUMP_DEBUG
1720 checkForCgError("update postcheck", _pCGcontext
);