fixed: compile issue
[opensg.git] / Source / Contrib / CgFXMaterial / OSGCgFXMaterial.cpp
blobe1662f4e777e81a1eadc219e6fefdc11f9b4355f
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <stdlib.h>
44 #include <stdio.h>
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"
69 OSG_BEGIN_NAMESPACE
71 /*! \class osg::CGFXMaterial
74 /***************************************************************************\
75 * Class variables *
76 \***************************************************************************/
78 const std::string CgFXMaterial::FALBACK_MATERIAL_TECHNIQUE_NAME =
79 std::string("FALBACK_MATERIAL");
81 /***************************************************************************\
82 * Class methods *
83 \***************************************************************************/
85 void CgFXMaterial::initMethod(InitPhase ePhase)
87 Inherited::initMethod(ePhase);
90 void CgFXMaterial::resolveLinks(void)
92 Inherited::resolveLinks();
95 /***************************************************************************\
96 * Instance methods *
97 \***************************************************************************/
99 /*-------------------------------------------------------------------------*\
100 - private -
101 \*-------------------------------------------------------------------------*/
103 /*----------------------- constructors & destructors ----------------------*/
105 CgFXMaterial::CgFXMaterial(void) :
106 Inherited ( ),
107 _pCGcontext (NULL ),
108 _pCGeffect (NULL ),
109 _pTechIdx ( 0),
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) :
120 Inherited (source ),
121 _pCGcontext (NULL ),
122 _pCGeffect (NULL ),
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)
142 return;
144 setGLId(Window::registerGLObject(
145 boost::bind(&CgFXMaterial::handleGL,
146 CgFXMaterialMTUncountedPtr(this),
147 _1, _2, _3, _4),
148 &CgFXMaterial::handleDestroyGL));
151 void CgFXMaterial::onDestroy(UInt32 uiContainerId)
153 if(getGLId() > 0)
154 Window::destroyGLObject(getGLId(), 1);
156 Inherited::onDestroy(uiContainerId);
159 bool CgFXMaterial::isTransparent(void) const
161 // not sure, CHECK_TOOLBOX_MERGE
162 //return true;
164 return false;
167 UInt32 CgFXMaterial::handleGL(DrawEnv *pEnv,
168 UInt32 osgId,
169 Window::GLObjectStatusE mode,
170 UInt64 uiOptions)
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",
182 glId,
183 _pCGcontext);
184 #endif
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",
199 //oldGlId,
200 //pOldCGcontext);
201 //#endif
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",
212 //glId,
213 //_pCGcontext);
214 //#endif
217 return 0;
220 void CgFXMaterial::handleDestroyGL(DrawEnv *pEnv,
221 UInt32 osgId,
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",
233 glId);
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,
249 UInt32 origin,
250 BitVector detail)
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))
274 if(detail != 0x0001)
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)
309 TechniqueKey =
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,
328 Window *pWin )
330 PrimeMaterial *returnValue = NULL;
332 if(pWin == NULL)
333 return returnValue;
335 if(_bForceUseFallback == true)
336 return getFallbackMaterial();
338 DrawEnv oEnv;
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)))
351 return returnValue;
354 else
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
364 // does
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)
372 returnValue = *tIt;
374 break;
378 return returnValue;
381 /*---------------------------------- Access -------------------------------*/
384 /*------------------------------------ Set --------------------------------*/
386 bool CgFXMaterial::checkForCgError(const Char8 *szSituation,
387 CGcontext pCGcontext )
389 CGerror error;
391 //Get the last error string and value
392 const Char8 *string = cgGetLastErrorString(&error);
394 //Was there an error
395 if(error != CG_NO_ERROR)
397 //Log the 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;
407 //Clear the error
408 cgGetError();
410 return true;
413 return false;
416 /*------------------------------------ Get --------------------------------*/
418 void CgFXMaterial::readEffectFile(void)
421 if(_sfEffectFile.getValue().empty() == true)
422 return;
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());
441 szFullFilePath =
442 pPathHandler->findFile(_sfEffectFile.getValue().c_str());
444 pPathHandler->popState();
446 else
448 szFullFilePath = _sfEffectFile.getValue();
451 #if 0
452 fprintf(stderr, "Read effect from %s\n",
453 szFullFilePath.c_str());
454 #endif
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);
465 if(szPath.empty())
466 szPath = ".";
468 #if 0
469 fprintf(stderr, "use path %s\n", szPath.c_str());
470 #endif
472 FILE *pFile = fopen(szFullFilePath.c_str(), "rb");
474 if(pFile == NULL)
475 return;
477 fseek(pFile, 0, SEEK_END);
479 long lFileSize = ftell(pFile);
481 fseek(pFile, 0, SEEK_SET);
483 std::string &szData = editEffectString();
485 szData.erase();
486 szData.resize(lFileSize);
488 fread(&(szData[0]), 1, lFileSize, pFile);
490 fclose(pFile);
493 void CgFXMaterial::initContext(void)
495 checkForCgError("precheck", _pCGcontext);
497 if(_pCGcontext != NULL)
499 //Already initialized
500 return;
503 _pCGcontext = cgCreateContext();
505 if( checkForCgError("Creating Cg Context", _pCGcontext) == true ||
506 _pCGcontext == NULL )
508 return;
511 cgGLRegisterStates (_pCGcontext );
512 cgGLSetManageTextureParameters(_pCGcontext, CG_TRUE);
514 if(checkForCgError("Registering GL States", _pCGcontext) == true)
516 return;
519 #if 0
520 #if CG_VERSION_NUM >= 2100
521 registerIncludeCallback( (OSGCGcontext)context, this );
522 cgSetCompilerIncludeCallback( context,
523 CgFXMaterial::checkForCgError("",
524 _pCGcontext);
525 (CGIncludeCallbackFunc)cgIncludeCallback );
526 #endif
527 #endif
530 void CgFXMaterial::processEffectString(void)
532 checkForCgError("precheck", _pCGcontext);
534 if(_sfEffectString.getValue().empty() == true)
535 return;
537 initContext();
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)
552 //Destroy the effect
553 cgDestroyEffect(_pCGeffect);
555 if( checkForCgError("Destroying Cg Effect", _pCGcontext) == true ||
556 _pCGeffect == NULL )
558 return;
562 _pCGeffect = cgCreateEffect(_pCGcontext,
563 _sfEffectString.getValue().c_str(),
564 pRawOptions );
566 if( checkForCgError("Creating Cg Effect", _pCGcontext) == true ||
567 _pCGeffect == NULL )
569 return;
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)
585 return;
587 CGannotation pVarAnno =
588 cgGetNamedTechniqueAnnotation(pFirstTechnique,
589 "treatTechniqueAsVariant");
591 CgFXMaterial::checkForCgError("cgGetNamedTechniqueAnnotation", _pCGcontext);
593 if(pVarAnno != NULL)
595 #if 0
596 fprintf(stderr, "got var anno\n");
597 #endif
599 int iNVals = 0;
601 const int *pTechVar = cgGetBooleanAnnotationValues( pVarAnno,
602 &iNVals );
604 CgFXMaterial::checkForCgError("cgGetBooleanAnnotationValues",
605 _pCGcontext);
607 if(pTechVar != NULL)
609 #if 0
610 fprintf(stderr, "got tech var : %d\n", *pTechVar);
611 #endif
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
619 extractParameters();
621 CGtechnique pCGTech = cgGetFirstTechnique(_pCGeffect);
623 CgFXMaterial::checkForCgError("cgGetFirstTechnique", _pCGcontext);
625 //Remove previous techniques
626 clearTechniques();
628 while(pCGTech != NULL)
630 #if 0
631 SLOG << "add Technique : "
632 << cgGetTechniqueName(pCGTech) << std::endl;
633 #endif
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);
656 if(tech != NULL)
658 for(UInt32 i = 0; i < _mfTechniques.size(); ++i)
660 if(tech == getTechniques(i)->_pCGTechnique)
662 return getTechniques(i);
667 return NULL;
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);
683 if(pTech != NULL)
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;
691 return true;
695 _bForceUseFallback = false;
697 return 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;
706 return false;
708 else
710 // if the technique name wasn't valid, we just use
711 // the default behavior (use the first valid technique)
713 _bForceUseFallback = false;
715 return false;
720 * Function to get the names of all of the available techniques for this
721 * material.
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);
739 return techNames;
742 void CgFXMaterial::extractParameters(void)
745 #if OSG_CGFX_DUMP_DEBUG
746 checkForCgError("extract precheck", _pCGcontext);
747 #endif
749 CGparameter pParam = cgGetFirstEffectParameter(_pCGeffect);
751 CgFXMaterial::checkForCgError("cgGetFirstEffectParameter", _pCGcontext);
753 if(pParam != NULL)
756 #if OSG_CGFX_DUMP_DEBUG
757 fprintf(stderr, "Effect parameter : \n");
758 #endif
760 editStateVariables() = 0x0000;
763 while(pParam)
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;
819 // -------------
820 // World
821 // -------------
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;
866 // -------------
867 // Model
868 // -------------
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;
913 // -------------
914 // WorldView
915 // -------------
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(),
925 "WORLDVIEWI" ) == 0)
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;
962 // -------------
963 // ModelView
964 // -------------
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(),
974 "ModelVIEWI" ) == 0)
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;
1011 // -------------
1012 // View
1013 // -------------
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;
1067 // -------------
1068 // Time / Timer
1069 // -------------
1070 else if(osgStringCaseCmp(szParamSemantic.c_str(),
1071 "TIME" ) == 0)
1073 editStateVariables() |= CgTimeMask;
1075 _vStateVarNames[CgTime] = szParamName;
1077 bFoundSemanticParam = true;
1080 if(bFoundSemanticParam == true)
1082 pParam = cgGetNextParameter(pParam);
1084 CgFXMaterial::checkForCgError("cgGetNextParameter",
1085 _pCGcontext);
1086 continue;
1090 switch(oParamType)
1092 case CG_BOOL:
1094 Int32 val;
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
1102 Int32 tmp;
1104 if(this->getUniformVariable(szParamName.c_str(), tmp))
1105 { // if it is, set the variable to value we already
1106 // have for it.
1107 cgSetParameterValueir( pParam,
1108 uiNumComponents,
1109 &tmp);
1111 CgFXMaterial::checkForCgError(
1112 "cgSetParameterValueir", _pCGcontext);
1114 } // otherwise use the default value
1115 else
1117 this->addUniformVariable(szParamName.c_str(),
1118 (val > 0) );
1121 else // use default value from .cgfx file
1123 this->addUniformVariable(szParamName.c_str(),
1124 (val > 0) );
1128 break;
1130 case CG_INT:
1132 Int32 val;
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
1139 Int32 tmp;
1140 if(this->getUniformVariable(szParamName.c_str(), tmp))
1141 { // if it is, set the variable to value we already
1142 // have for it.
1143 cgSetParameterValueir( pParam,
1144 uiNumComponents,
1145 &tmp);
1147 CgFXMaterial::checkForCgError(
1148 "cgSetParameterValueir", _pCGcontext);
1150 } // otherwise use the default value
1151 else
1153 this->addUniformVariable(szParamName.c_str(),
1154 val );
1157 else // use default value from .cgfx file
1159 this->addUniformVariable(szParamName.c_str(), val);
1163 break;
1165 case CG_FLOAT:
1166 case CG_FLOAT2:
1167 case CG_FLOAT3:
1168 case CG_FLOAT4:
1169 case CG_FLOAT4x4:
1171 switch(uiNumComponents)
1173 case 1:
1175 Real32 val;
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
1182 Real32 tmp;
1184 if(this->getUniformVariable(
1185 szParamName.c_str(),
1186 tmp ))
1187 { // if it is, set the variable to value we
1188 // already have for it.
1189 cgSetParameterValuefr( pParam,
1190 uiNumComponents,
1191 &tmp);
1193 CgFXMaterial::checkForCgError(
1194 "cgSetParameterValuefr", _pCGcontext);
1195 } // otherwise use the default value
1196 else
1198 this->addUniformVariable(
1199 szParamName.c_str(),
1200 val ) ;
1203 else // use default value from .cgfx file
1205 this->addUniformVariable(szParamName.c_str(),
1206 val );
1210 break;
1212 case 2:
1214 Vec2f val;
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
1223 Vec2f tmp;
1224 if(this->getUniformVariable(
1225 szParamName.c_str(),
1226 tmp ))
1227 { // if it is, set the variable to value we
1228 // already have for it.
1229 cgSetParameterValuefr(pParam,
1230 uiNumComponents,
1231 tmp.getValues());
1233 CgFXMaterial::checkForCgError(
1234 "cgSetParameterValuefr", _pCGcontext);
1235 } // otherwise use the default value
1236 else
1238 this->addUniformVariable(
1239 szParamName.c_str(),
1240 val );
1243 else // use default value from .cgfx file
1245 this->addUniformVariable(szParamName.c_str(),
1246 val );
1250 break;
1252 case 3:
1254 Vec3f val;
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
1263 Vec3f tmp;
1264 if(this->getUniformVariable(
1265 szParamName.c_str(),
1266 tmp ))
1267 { // if it is, set the variable to value we
1268 // already have for it.
1269 cgSetParameterValuefr(pParam,
1270 uiNumComponents,
1271 tmp.getValues());
1273 CgFXMaterial::checkForCgError(
1274 "cgSetParameterValuefr", _pCGcontext);
1275 } // otherwise use the default value
1276 else
1278 this->addUniformVariable(
1279 szParamName.c_str(),
1280 val );
1283 else // use default value from .cgfx file
1285 this->addUniformVariable(szParamName.c_str(),
1286 val );
1290 break;
1292 case 4:
1294 Vec4f val;
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
1303 Vec4f tmp;
1304 if(this->getUniformVariable(
1305 szParamName.c_str(),
1306 tmp ))
1307 { // if it is, set the variable to value we
1308 // already have for it.
1309 cgSetParameterValuefr(pParam,
1310 uiNumComponents,
1311 tmp.getValues());
1313 CgFXMaterial::checkForCgError(
1314 "cgSetParameterValuefr", _pCGcontext);
1315 } // otherwise use the default value
1316 else
1318 this->addUniformVariable(
1319 szParamName.c_str(),
1320 val );
1323 else // use default value from .cgfx file
1325 this->addUniformVariable(szParamName.c_str(),
1326 val );
1330 break;
1332 case 16:
1334 // CHECK cgSetParameterValuefr or cgSetParameterValuefc
1335 Matrix val;
1337 if(cgGetParameterValuefr(pParam,
1338 16,
1339 val.getValues()) == 16)
1341 val.transpose();
1342 // check where what values we should be using
1343 if(this->getParameterValueSource() == CURRENT)
1344 { // check if this is already a variable
1345 Vec4f tmp;
1346 if(this->getUniformVariable(
1347 szParamName.c_str(),
1348 tmp ))
1349 { // if it is, set the variable to value we
1350 // already have for it.
1351 cgSetParameterValuefr(pParam,
1352 uiNumComponents,
1353 tmp.getValues());
1355 CgFXMaterial::checkForCgError(
1356 "cgSetParameterValuefr", _pCGcontext);
1357 } // otherwise use the default value
1358 else
1360 this->addUniformVariable(
1361 szParamName.c_str(),
1362 val );
1365 else // use default value from .cgfx file
1367 this->addUniformVariable(szParamName.c_str(),
1368 val );
1372 break;
1375 break;
1377 case CG_TEXTURE:
1378 break;
1380 case CG_SAMPLER1D:
1381 case CG_SAMPLER2D:
1382 case CG_SAMPLER3D:
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
1395 szFilename =
1396 dynamic_cast<const CgFXVariableTexObj *>(
1397 this->getVariable(
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.
1408 readFile = false;
1409 break;
1415 if(szFilename.empty())
1417 CGannotation pAnno = cgGetNamedParameterAnnotation(pParam,
1418 "File");
1420 CgFXMaterial::checkForCgError(
1421 "cgGetNamedParameterAnnotation", _pCGcontext);
1423 if(pAnno == NULL)
1425 pAnno = cgGetNamedParameterAnnotation(pParam,
1426 "ResourceName");
1428 CgFXMaterial::checkForCgError(
1429 "cgGetNamedParameterAnnotation", _pCGcontext);
1432 if(pAnno != NULL)
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);
1458 if(pTParam != NULL)
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,
1471 "File");
1473 CgFXMaterial::checkForCgError(
1474 "cgGetNamedParameterAnnotation",
1475 _pCGcontext);
1477 if(pAnno == NULL)
1479 pAnno =
1480 cgGetNamedParameterAnnotation(
1481 pTParam,
1482 "ResourceName");
1484 CgFXMaterial::checkForCgError(
1485 "cgGetNamedParameterAnnotation",
1486 _pCGcontext);
1489 if(pAnno != NULL)
1491 szFilename =
1492 cgGetStringAnnotationValue(pAnno);
1494 CgFXMaterial::checkForCgError(
1495 "cgGetStringAnnotationValue",
1496 _pCGcontext);
1503 if(readFile)
1505 Int32 uiSamplerId = -1;
1507 ImageUnrecPtr pImg =
1508 ImageFileHandler::the()->read(szFilename.c_str());
1510 if(pImg != NULL)
1512 TextureObjChunkUnrecPtr pTexO =
1513 TextureObjChunk::create();
1515 setName(pTexO, szParamName);
1517 pTexO->setImage(pImg);
1519 this->pushToTextures(pTexO);
1521 else
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();
1531 break;
1536 if(pImg != NULL && varIsInitialized == false)
1538 pVar = CgFXVariableTexObj::create();
1540 pVar->setName (szParamName);
1541 this->addVariable(pVar );
1542 pVar->setValue (uiSamplerId);
1546 break;
1548 case CG_ARRAY:
1551 break;
1553 case CG_STRUCT:
1556 break;
1558 case CG_STRING:
1561 break;
1563 default:
1565 FWARNING(("CgFXMaterial : Unsupported parameter (%s) type "
1566 "(%d)!\n",
1567 szParamName.c_str(),
1568 oParamType));
1570 break;
1573 pParam = cgGetNextParameter(pParam);
1574 CgFXMaterial::checkForCgError("cgGetNextParameter", _pCGcontext);
1577 #if OSG_CGFX_DUMP_DEBUG
1578 checkForCgError("extract postcheck", _pCGcontext);
1579 #endif
1582 void CgFXMaterial::updateUniformVariables(void)
1584 #if OSG_CGFX_DUMP_DEBUG
1585 checkForCgError("update precheck", _pCGcontext);
1586 #endif
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)
1602 return;
1605 OSG_ASSERT(pMFVars->size() == pMFVarChg->size());
1607 ShaderProgramVariables::MFVariablesType::const_iterator mVarIt =
1608 pMFVars->begin();
1609 ShaderProgramVariables::MFVariablesType::const_iterator mVarEnd =
1610 pMFVars->end ();
1612 ShaderProgramVariables::MFVariableChangedType::iterator mVarChgIt =
1613 pMFVarChg->begin();
1615 for(; mVarIt != mVarEnd; ++mVarIt, ++mVarChgIt)
1617 ShaderVariable *pVar = *mVarIt;
1619 if(pVar == NULL)
1620 continue;
1622 if(*mVarChgIt == false)
1623 continue;
1625 *mVarChgIt = false;
1627 CGparameter pParam =
1628 cgGetNamedEffectParameter(_pCGeffect,
1629 pVar->getName().c_str());
1631 CgFXMaterial::checkForCgError("cgGetNamedEffectParameter",
1632 _pCGcontext);
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);
1645 break;
1647 case ShaderVariable::SHVTypeInt:
1649 ShaderVariableInt *p =
1650 dynamic_cast<ShaderVariableInt *>(pVar);
1652 cgSetParameter1i(pParam, p->getValue());
1654 CgFXMaterial::checkForCgError("cgSetParameter1i", _pCGcontext);
1656 break;
1658 case ShaderVariable::SHVTypeReal:
1660 ShaderVariableReal *p =
1661 dynamic_cast<ShaderVariableReal *>(pVar);
1663 cgSetParameter1f(pParam, p->getValue());
1665 CgFXMaterial::checkForCgError("cgSetParameter1f", _pCGcontext);
1667 break;
1669 case ShaderVariable::SHVTypeVec2f:
1671 ShaderVariableVec2f *p =
1672 dynamic_cast<ShaderVariableVec2f *>(pVar);
1674 cgSetParameter2fv(pParam, p->getValue().getValues());
1676 CgFXMaterial::checkForCgError("cgSetParameter2fv", _pCGcontext);
1678 break;
1680 case ShaderVariable::SHVTypeVec3f:
1682 ShaderVariableVec3f *p =
1683 dynamic_cast<ShaderVariableVec3f *>(pVar);
1685 cgSetParameter3fv(pParam, p->getValue().getValues());
1687 CgFXMaterial::checkForCgError("cgSetParameter3fv", _pCGcontext);
1689 break;
1691 case ShaderVariable::SHVTypeVec4f:
1693 ShaderVariableVec4f *p =
1694 dynamic_cast<ShaderVariableVec4f *>(pVar);
1696 cgSetParameter4fv(pParam, p->getValue().getValues());
1698 CgFXMaterial::checkForCgError("cgSetParameter4fv", _pCGcontext);
1700 break;
1702 case ShaderVariable::SHVTypeMatrix:
1704 ShaderVariableMatrix *p =
1705 dynamic_cast<ShaderVariableMatrix *>(pVar);
1707 cgSetMatrixParameterfr(pParam, p->getValue().getValues());
1709 CgFXMaterial::checkForCgError("cgSetMatrixParameterfr",
1710 _pCGcontext);
1712 break;
1714 default:
1715 break;
1719 #if OSG_CGFX_DUMP_DEBUG
1720 checkForCgError("update postcheck", _pCGcontext);
1721 #endif
1724 OSG_END_NAMESPACE