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 \*---------------------------------------------------------------------------*/
42 #include "OSGConfig.h"
44 #include "OSGBaseFunctions.h"
45 #include "OSGFieldContainer.h"
46 #include "OSGStateOverride.h"
47 #include "OSGShaderProgramChunk.h"
48 #include "OSGShaderProgramVariableChunk.h"
49 #include "OSGSimpleSHLChunk.h"
53 /*! \class OSG::StateOverride
56 /*-------------------------------------------------------------------------*/
59 StateOverride::StateOverride(void) :
73 /*-------------------------------------------------------------------------*/
76 StateOverride::~StateOverride(void)
80 void StateOverride::rebuildSortKey(void)
85 void StateOverride::addOverride(UInt32 uiSlot
, ShaderProgramChunk
*pChunk
)
92 ShaderProgramChunk::MFVertexShaderType::const_iterator sIt
=
93 pChunk
->getMFVertexShader()->begin();
95 ShaderProgramChunk::MFVertexShaderType::const_iterator sEnd
=
96 pChunk
->getMFVertexShader()->end();
99 for(; sIt
!= sEnd
; ++sIt
)
101 UInt16 uiProgId
= (*sIt
)->getProgramId();
103 IdStoreIt iIt
= std::lower_bound(_vProgIds
.begin(),
107 if(iIt
== _vProgIds
.end())
109 _vProgIds
.push_back(uiProgId
);
111 else if(*iIt
!= (*sIt
)->getProgramId())
113 _vProgIds
.insert(iIt
, uiProgId
);
118 sIt
= pChunk
->getMFGeometryShader()->begin();
119 sEnd
= pChunk
->getMFGeometryShader()->end ();
121 for(; sIt
!= sEnd
; ++sIt
)
123 UInt16 uiProgId
= (*sIt
)->getProgramId();
125 IdStoreIt iIt
= std::lower_bound(_vProgIds
.begin(),
129 if(iIt
== _vProgIds
.end())
131 _vProgIds
.push_back(uiProgId
);
133 else if(*iIt
!= (*sIt
)->getProgramId())
135 _vProgIds
.insert(iIt
, uiProgId
);
139 sIt
= pChunk
->getMFFragmentShader()->begin();
140 sEnd
= pChunk
->getMFFragmentShader()->end ();
142 for(; sIt
!= sEnd
; ++sIt
)
144 UInt16 uiProgId
= (*sIt
)->getProgramId();
146 IdStoreIt iIt
= std::lower_bound(_vProgIds
.begin(),
150 if(iIt
== _vProgIds
.end())
152 _vProgIds
.push_back(uiProgId
);
154 else if(*iIt
!= (*sIt
)->getProgramId())
156 _vProgIds
.insert(iIt
, uiProgId
);
160 _vProgChunks
.push_back(pChunk
);
165 void StateOverride::addOverride(UInt32 uiSlot
,
166 ShaderProgramVariableChunk
*pChunk
)
173 UInt16 uiVarId
= pChunk
->getVariableId();
175 IdStoreIt iIt
= std::lower_bound(_vProgVarIds
.begin(),
179 if(iIt
== _vProgVarIds
.end())
181 _vProgVarIds
.push_back(uiVarId
);
183 else if(*iIt
!= uiVarId
)
185 _vProgVarIds
.insert(iIt
, uiVarId
);
188 _vProgVarChunks
.push_back(pChunk
);
193 void StateOverride::addOverride(UInt32 uiSlot
,
194 SimpleSHLChunk
*pChunk
)
196 insertOverride(uiSlot
, pChunk
);
199 void StateOverride::insertOverride(UInt32 uiSlot
,
202 ChunkElement
newElem(uiSlot
, pChunk
);
204 ChunkStoreIt cIt
= std::lower_bound(_vChunks
.begin(),
208 if(cIt
== _vChunks
.end())
210 _vChunks
.insert(cIt
, newElem
);
214 if(cIt
->first
== uiSlot
)
216 cIt
->second
= pChunk
;
220 _vChunks
.insert(cIt
, newElem
);
229 UInt32 uiKey1
= _uiKeyGen
& Key1Mask
;
230 UInt32 uiKey2
= (_uiKeyGen
& Key2Mask
) >> 10;
231 UInt32 uiKey3
= (_uiKeyGen
& Key3Mask
) >> 20;
233 if(uiKey1
!= InvalidKey
&& uiKey1
== uiSlot
)
236 (pChunk
->getIgnore() == false) ? pChunk
->getChunkId() : 0;
238 _uiKeyMask
&= ~Key1Mask
;
245 if(uiKey2
!= InvalidKey
&& uiKey2
== uiSlot
)
248 (pChunk
->getIgnore() == false) ? pChunk
->getChunkId() : 0;
250 _uiKeyMask
&= ~Key2Mask
;
257 if(uiKey3
!= InvalidKey
&& uiKey3
== uiSlot
)
260 (pChunk
->getIgnore() == false) ? pChunk
->getChunkId() : 0;
262 _uiKeyMask
&= ~Key3Mask
;
270 (uiKey1
& Key1Mask
) |
271 ((uiKey2
& Key1Mask
) << 10) |
272 ((uiKey3
& Key1Mask
) << 20);
275 void StateOverride::addOverride(UInt32 uiSlot
, StateChunk
*pChunk
)
277 ShaderProgramChunk
*pSPChunk
= dynamic_cast<ShaderProgramChunk
*>(pChunk
);
281 ShaderProgramVariableChunk
*pSPVChunk
=
282 dynamic_cast<ShaderProgramVariableChunk
*>(pChunk
);
284 if(pSPVChunk
== NULL
)
286 insertOverride(uiSlot
, pChunk
);
290 this->addOverride(uiSlot
, pSPVChunk
);
295 this->addOverride(uiSlot
, pSPChunk
);
299 void StateOverride::subOverride(UInt32 uiSlot
, ShaderProgramChunk
*pChunk
)
306 ShaderProgramChunk::MFVertexShaderType::const_iterator sIt
=
307 pChunk
->getMFVertexShader()->begin();
309 ShaderProgramChunk::MFVertexShaderType::const_iterator sEnd
=
310 pChunk
->getMFVertexShader()->end();
313 for(; sIt
!= sEnd
; ++sIt
)
315 UInt16 uiProgId
= (*sIt
)->getProgramId();
317 std::pair
<IdStoreIt
, IdStoreIt
> pairIt
318 = std::equal_range(_vProgIds
.begin(),
322 if(pairIt
.first
!= pairIt
.second
)
324 _vProgIds
.erase(pairIt
.first
);
328 sIt
= pChunk
->getMFGeometryShader()->begin();
329 sEnd
= pChunk
->getMFGeometryShader()->end ();
331 for(; sIt
!= sEnd
; ++sIt
)
333 UInt16 uiProgId
= (*sIt
)->getProgramId();
335 std::pair
<IdStoreIt
, IdStoreIt
> pairIt
336 = std::equal_range(_vProgIds
.begin(),
340 if(pairIt
.first
!= pairIt
.second
)
342 _vProgIds
.erase(pairIt
.first
);
346 sIt
= pChunk
->getMFFragmentShader()->begin();
347 sEnd
= pChunk
->getMFFragmentShader()->end ();
349 for(; sIt
!= sEnd
; ++sIt
)
351 UInt16 uiProgId
= (*sIt
)->getProgramId();
353 std::pair
<IdStoreIt
, IdStoreIt
> pairIt
354 = std::equal_range(_vProgIds
.begin(),
358 if(pairIt
.first
!= pairIt
.second
)
360 _vProgIds
.erase(pairIt
.first
);
364 ProgramChunkStore::iterator sIt2
365 = std::find(_vProgChunks
.begin(), _vProgChunks
.end(), pChunk
);
367 if(sIt2
!= _vProgChunks
.end())
368 _vProgChunks
.erase(sIt2
);
371 void StateOverride::subOverride(UInt32 uiSlot
,
372 ShaderProgramVariableChunk
*pChunk
)
379 UInt16 uiVarId
= pChunk
->getVariableId();
381 std::pair
<IdStoreIt
, IdStoreIt
> pairIt
382 = std::equal_range(_vProgVarIds
.begin(),
386 if(pairIt
.first
!= pairIt
.second
)
388 _vProgVarIds
.erase(pairIt
.first
);
391 ProgramVarChunkStore::iterator sIt2
392 = std::find(_vProgVarChunks
.begin(), _vProgVarChunks
.end(), pChunk
);
394 if(sIt2
!= _vProgVarChunks
.end())
395 _vProgVarChunks
.erase(sIt2
);
398 void StateOverride::subOverride(UInt32 uiSlot
,
399 SimpleSHLChunk
*pChunk
)
401 eraseOverride(uiSlot
, pChunk
);
404 void StateOverride::eraseOverride(UInt32 uiSlot
,
407 ChunkElement
newElem(uiSlot
, pChunk
);
409 std::pair
<ChunkStoreIt
, ChunkStoreIt
> pairIt
410 = std::equal_range(_vChunks
.begin(),
414 for(; pairIt
.first
!= pairIt
.second
; ++pairIt
.first
)
416 if(pairIt
.first
->first
== uiSlot
)
418 _vChunks
.erase(pairIt
.first
);
424 void StateOverride::subOverride(UInt32 uiSlot
, StateChunk
*pChunk
)
426 ShaderProgramChunk
*pSPChunk
= dynamic_cast<ShaderProgramChunk
*>(pChunk
);
430 ShaderProgramVariableChunk
*pSPVChunk
=
431 dynamic_cast<ShaderProgramVariableChunk
*>(pChunk
);
433 if(pSPVChunk
== NULL
)
435 eraseOverride(uiSlot
, pChunk
);
439 this->subOverride(uiSlot
, pSPVChunk
);
444 this->subOverride(uiSlot
, pSPChunk
);