fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / State / Base / OSGMaterialChunk.cpp
blob4301a4d617420b70003ca0b31bfe5957ce056ca7
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 <cstdlib>
44 #include <cstdio>
46 #include "OSGConfig.h"
48 #include "OSGGL.h"
49 #include "OSGGLU.h"
51 #include "OSGMaterialChunk.h"
52 #include "OSGShaderAttribute.h"
53 #include "OSGDrawEnv.h"
55 OSG_USING_NAMESPACE
57 // Documentation for this class is emited in the
58 // OSGMaterialChunkBase.cpp file.
59 // To modify it, please change the .fcd file (OSGMaterialChunk.fcd) and
60 // regenerate the base file.
62 /***************************************************************************\
63 * Class variables *
64 \***************************************************************************/
66 StateChunkClass MaterialChunk::_class("Material", 1, 100);
68 volatile UInt16 MaterialChunk::_uiChunkCounter = 1;
70 /***************************************************************************\
71 * Class methods *
72 \***************************************************************************/
74 void MaterialChunk::initMethod(InitPhase ePhase)
76 Inherited::initMethod(ePhase);
79 /***************************************************************************\
80 * Instance methods *
81 \***************************************************************************/
83 /*-------------------------------------------------------------------------*\
84 - private -
85 \*-------------------------------------------------------------------------*/
87 MaterialChunk::MaterialChunk(void) :
88 Inherited( ),
89 _uiChunkId(0)
93 MaterialChunk::MaterialChunk(const MaterialChunk &source) :
94 Inherited(source),
95 _uiChunkId( 0)
99 MaterialChunk::~MaterialChunk(void)
104 void MaterialChunk::onCreate(const MaterialChunk *source)
106 Inherited::onCreate(source);
108 if(GlobalSystemState == Startup)
109 return;
111 _uiChunkId = _uiChunkCounter++;
114 void MaterialChunk::onCreateAspect(const MaterialChunk *createAspect,
115 const MaterialChunk *source )
117 Inherited::onCreateAspect(createAspect, source);
119 _uiChunkId = createAspect->_uiChunkId;
122 /*------------------------- Chunk Class Access ---------------------------*/
124 const StateChunkClass *MaterialChunk::getClass(void) const
126 return &_class;
129 /*------------------------------- Sync -----------------------------------*/
131 void MaterialChunk::changed(ConstFieldMaskArg whichField,
132 UInt32 origin,
133 BitVector details)
135 Inherited::changed(whichField, origin, details);
138 UInt16 MaterialChunk::getChunkId(void)
140 return _uiChunkId;
143 /*------------------------------ Output ----------------------------------*/
145 void MaterialChunk::dump( UInt32 uiIndent,
146 const BitVector bvFlags ) const
148 Inherited::dump(uiIndent, bvFlags);
150 if((bvFlags & DiffuseFieldMask) != 0)
152 indentLog(uiIndent, PLOG);
153 PLOG << "diffuse " << _sfDiffuse.getValue() << "\n";
156 if((bvFlags & AmbientFieldMask) != 0)
158 indentLog(uiIndent, PLOG);
159 PLOG << "ambient " << _sfAmbient.getValue() << "\n";
162 if((bvFlags & SpecularFieldMask) != 0)
164 indentLog(uiIndent, PLOG);
165 PLOG << "specular " << _sfSpecular.getValue() << "\n";
168 if((bvFlags & EmissionFieldMask) != 0)
170 indentLog(uiIndent, PLOG);
171 PLOG << "emission " << _sfEmission.getValue() << "\n";
174 if((bvFlags & ShininessFieldMask) != 0)
176 indentLog(uiIndent, PLOG);
177 PLOG << "shininess " << _sfShininess.getValue() << "\n";
180 if((bvFlags & LitFieldMask) != 0)
182 indentLog(uiIndent, PLOG);
183 PLOG << "lit " << _sfLit.getValue() << "\n";
186 if((bvFlags & ColorMaterialFieldMask) != 0)
188 indentLog(uiIndent, PLOG);
189 PLOG << "colorMaterial "
190 << GLDefineMapper::the()->toString(_sfColorMaterial.getValue())
191 << "\n";
194 if((bvFlags & BackMaterialFieldMask) != 0)
196 indentLog(uiIndent, PLOG);
197 PLOG << "backMaterial " << _sfBackMaterial.getValue() << "\n";
200 if((bvFlags & BackDiffuseFieldMask) != 0)
202 indentLog(uiIndent, PLOG);
203 PLOG << "backDiffuse " << _sfBackDiffuse.getValue() << "\n";
206 if((bvFlags & BackAmbientFieldMask) != 0)
208 indentLog(uiIndent, PLOG);
209 PLOG << "backAmbient " << _sfBackAmbient.getValue() << "\n";
212 if((bvFlags & BackSpecularFieldMask) != 0)
214 indentLog(uiIndent, PLOG);
215 PLOG << "backSpecular " << _sfBackSpecular.getValue() << "\n";
218 if((bvFlags & BackEmissionFieldMask) != 0)
220 indentLog(uiIndent, PLOG);
221 PLOG << "backEmission " << _sfBackEmission.getValue() << "\n";
224 if((bvFlags & BackShininessFieldMask) != 0)
226 indentLog(uiIndent, PLOG);
227 PLOG << "backShininess " << _sfBackShininess.getValue() << "\n";
231 /*------------------------------ State ------------------------------------*/
233 void MaterialChunk::activate(DrawEnv *pEnv, UInt32)
235 glErr("material:activate:precheck");
237 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
238 GLenum target;
240 pEnv->incNumChunkChanges();
242 if(getBackMaterial())
244 target = GL_FRONT;
246 if(getColorMaterial() == GL_NONE && getBackColorMaterial() == GL_NONE)
248 glDisable(GL_COLOR_MATERIAL);
250 else if(getColorMaterial() == GL_NONE)
252 glColorMaterial(GL_BACK, getBackColorMaterial());
253 glEnable(GL_COLOR_MATERIAL);
255 else if(getBackColorMaterial() == GL_NONE)
257 glColorMaterial(GL_FRONT, getColorMaterial());
258 glEnable(GL_COLOR_MATERIAL);
260 else if(getColorMaterial() != getBackColorMaterial())
262 FWARNING(("MaterialChunk::activate: can't have different "
263 "back and front colorMaterial types!\n"));
264 glEnable(GL_COLOR_MATERIAL);
266 else
268 glColorMaterial(GL_FRONT_AND_BACK, getColorMaterial());
269 glEnable(GL_COLOR_MATERIAL);
272 else
274 target = GL_FRONT_AND_BACK;
276 if(getColorMaterial() == GL_NONE)
278 glDisable(GL_COLOR_MATERIAL);
280 else
282 glColorMaterial(GL_FRONT_AND_BACK, getColorMaterial());
283 glEnable(GL_COLOR_MATERIAL);
287 glColor4fv(_sfDiffuse.getValue().getValuesRGBA());
289 if(getLit())
291 glMaterialfv(target, GL_DIFFUSE,
292 _sfDiffuse.getValue().getValuesRGBA());
293 glMaterialfv(target, GL_AMBIENT,
294 _sfAmbient.getValue().getValuesRGBA());
295 glMaterialfv(target, GL_SPECULAR,
296 _sfSpecular.getValue().getValuesRGBA());
297 glMaterialfv(target, GL_EMISSION,
298 _sfEmission.getValue().getValuesRGBA());
299 glMaterialf (target, GL_SHININESS, _sfShininess.getValue());
301 if(getBackMaterial())
303 glMaterialfv(GL_BACK, GL_DIFFUSE,
304 _sfBackDiffuse.getValue().getValuesRGBA());
305 glMaterialfv(GL_BACK, GL_AMBIENT,
306 _sfBackAmbient.getValue().getValuesRGBA());
307 glMaterialfv(GL_BACK, GL_SPECULAR,
308 _sfBackSpecular.getValue().getValuesRGBA());
309 glMaterialfv(GL_BACK, GL_EMISSION,
310 _sfBackEmission.getValue().getValuesRGBA());
311 glMaterialf (GL_BACK, GL_SHININESS, _sfBackShininess.getValue());
314 glEnable(GL_LIGHTING);
316 else
318 glDisable(GL_LIGHTING);
320 #else
321 glVertexAttrib4fv( ShaderConstants::Attribute3Index,
322 _sfDiffuse.getValue().getValuesRGBA());
324 // OSG_ASSERT(false);
325 #endif
327 glErr("material:activate:postcheck");
330 void MaterialChunk::changeFrom(DrawEnv *pEnv,
331 StateChunk *old_chunk,
332 UInt32 )
334 glErr("material:changed:precheck");
336 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
337 MaterialChunk const *old = dynamic_cast<MaterialChunk const*>(old_chunk);
339 // change from me to me?
340 // this assumes I haven't changed in the meantime. is that a valid
341 // assumption?
343 if(old == this)
345 // Reset it, as Geometry colors might have changed it
346 glColor4fv(_sfDiffuse.getValue().getValuesRGBA());
347 return;
350 pEnv->incNumChunkChanges();
352 if(getColorMaterial() != old->getColorMaterial () ||
353 getBackColorMaterial() != old->getBackColorMaterial() )
355 if(getBackMaterial())
357 if(getColorMaterial () == GL_NONE &&
358 getBackColorMaterial() == GL_NONE )
360 glDisable(GL_COLOR_MATERIAL);
362 else if(getColorMaterial() == GL_NONE)
364 glColorMaterial(GL_BACK, getBackColorMaterial());
365 glEnable(GL_COLOR_MATERIAL);
367 else if(getBackColorMaterial() == GL_NONE)
369 glColorMaterial(GL_FRONT, getColorMaterial());
370 glEnable(GL_COLOR_MATERIAL);
372 else if(getColorMaterial() != getBackColorMaterial())
374 FWARNING(("MaterialChunk::changeFrom: can't have different "
375 "back and front colorMaterial types!\n"));
376 glEnable(GL_COLOR_MATERIAL);
378 else
380 glColorMaterial(GL_FRONT_AND_BACK, getColorMaterial());
381 glEnable(GL_COLOR_MATERIAL);
384 else
386 if(getColorMaterial() == GL_NONE)
388 glDisable(GL_COLOR_MATERIAL);
390 else
392 glColorMaterial(GL_FRONT_AND_BACK, getColorMaterial());
393 glEnable(GL_COLOR_MATERIAL);
398 glColor4fv(_sfDiffuse.getValue().getValuesRGBA());
400 if(getLit() && ! old->getLit())
401 glEnable(GL_LIGHTING);
402 else if(! getLit() && old->getLit())
403 glDisable(GL_LIGHTING);
405 if(getLit())
407 GLenum target;
409 if(getBackMaterial())
411 target = GL_FRONT;
413 else
415 target = GL_FRONT_AND_BACK;
418 glMaterialfv(target, GL_DIFFUSE,
419 _sfDiffuse.getValue().getValuesRGBA());
420 glMaterialfv(target, GL_AMBIENT,
421 _sfAmbient.getValue().getValuesRGBA());
422 glMaterialfv(target, GL_SPECULAR,
423 _sfSpecular.getValue().getValuesRGBA());
424 glMaterialfv(target, GL_EMISSION,
425 _sfEmission.getValue().getValuesRGBA());
426 // adjust shininess only if it differs enough
427 if(osgAbs(_sfShininess.getValue() - old->getShininess()) > 1e-4)
428 glMaterialf(target, GL_SHININESS, _sfShininess.getValue());
430 if(getBackMaterial())
432 glMaterialfv(GL_BACK, GL_DIFFUSE,
433 _sfBackDiffuse.getValue().getValuesRGBA());
434 glMaterialfv(GL_BACK, GL_AMBIENT,
435 _sfBackAmbient.getValue().getValuesRGBA());
436 glMaterialfv(GL_BACK, GL_SPECULAR,
437 _sfBackSpecular.getValue().getValuesRGBA());
438 glMaterialfv(GL_BACK, GL_EMISSION,
439 _sfBackEmission.getValue().getValuesRGBA());
440 // adjust shininess only if it differs enough
441 if(osgAbs(_sfBackShininess.getValue() -
442 old->getBackShininess() ) > 1e-4)
444 glMaterialf(GL_BACK, GL_SHININESS,
445 _sfBackShininess.getValue());
449 #else
450 glVertexAttrib4fv( ShaderConstants::Attribute3Index,
451 _sfDiffuse.getValue().getValuesRGBA());
452 // OSG_ASSERT(false);
453 #endif
455 glErr("material:changed:postcheck");
458 void MaterialChunk::deactivate(DrawEnv *, UInt32)
460 #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY)
461 if(getLit())
462 glDisable(GL_LIGHTING);
464 if(getColorMaterial() != GL_NONE)
465 glDisable(GL_COLOR_MATERIAL);
466 #else
467 // OSG_ASSERT(false);
468 #endif
472 /*-------------------------- Comparison -----------------------------------*/
474 Real32 MaterialChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
476 return 0;
479 bool MaterialChunk::isTransparent(void) const
481 return(getDiffuse()[3] <(1.f - TypeTraits<Real32>::getDefaultEps()));
485 bool MaterialChunk::operator <(const StateChunk &other) const
487 return this < &other;
490 bool MaterialChunk::operator ==(const StateChunk &other) const
492 MaterialChunk const *tother = dynamic_cast<MaterialChunk const*>(&other);
494 if(!tother)
495 return false;
497 if(tother == this)
498 return true;
500 if(!getAmbient ().equals(tother->getAmbient (),
501 TypeTraits<Real32>::getDefaultEps()) ||
502 !getDiffuse ().equals(tother->getDiffuse (),
503 TypeTraits<Real32>::getDefaultEps()) ||
504 !getSpecular ().equals(tother->getSpecular (),
505 TypeTraits<Real32>::getDefaultEps()) ||
506 !getEmission ().equals(tother->getEmission (),
507 TypeTraits<Real32>::getDefaultEps()) ||
508 getShininess() != tother->getShininess() ||
509 getLit() != tother->getLit() ||
510 getColorMaterial() != tother->getColorMaterial()
512 return false;
514 return true;
517 bool MaterialChunk::operator !=(const StateChunk &other) const
519 return !(*this == other);