00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include <OSGConfig.h>
00047
00048 #include <OSGBaseFunctions.h>
00049
00050 #include "OSGFresnelMaterial.h"
00051
00052 OSG_USING_NAMESPACE
00053
00058
00059
00060
00061
00062
00063
00064
00065
00066 void FresnelMaterial::initMethod (void)
00067 {
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 FresnelMaterial::FresnelMaterial(void) :
00082 Inherited(),
00083 _materialChunk(NullFC),
00084 _textureChunk(NullFC),
00085 _texGenChunk(NullFC),
00086 _blendChunk(NullFC),
00087 _img(NullFC)
00088 {
00089 }
00090
00091 FresnelMaterial::FresnelMaterial(const FresnelMaterial &source) :
00092 Inherited(source),
00093 _materialChunk(source._materialChunk),
00094 _textureChunk(source._textureChunk),
00095 _texGenChunk(source._texGenChunk),
00096 _blendChunk(source._blendChunk),
00097 _img(source._img)
00098 {
00099 }
00100
00101 FresnelMaterial::~FresnelMaterial(void)
00102 {
00103 if(_sfImage.getValue() != NullFC)
00104 subRefCP(_sfImage.getValue());
00105
00106 if(_materialChunk != NullFC)
00107 subRefCP(_materialChunk);
00108
00109 if(_textureChunk != NullFC)
00110 subRefCP(_textureChunk);
00111
00112 if(_texGenChunk != NullFC)
00113 subRefCP(_texGenChunk);
00114
00115 if(_blendChunk != NullFC)
00116 subRefCP(_blendChunk);
00117
00118 if(_img != NullFC)
00119 subRefCP(_img);
00120 }
00121
00122 void FresnelMaterial::prepareLocalChunks(void)
00123 {
00124 if(_textureChunk != NullFC)
00125 return;
00126
00127 _img = Image::create();
00128 addRefCP(_img);
00129
00130 UInt8 imgdata[] = { 255,0,0,128, 0,255,0,128, 0,0,255,255, 255,255,255,255 };
00131
00132 beginEditCP(_img);
00133 _img->set( Image::OSG_RGBA_PF, 2, 2, 1, 1, 1, 0, imgdata);
00134 endEditCP(_img);
00135
00136 _materialChunk = MaterialChunk::create();
00137 addRefCP(_materialChunk);
00138
00139 _textureChunk = TextureChunk::create();
00140 addRefCP(_textureChunk);
00141 beginEditCP(_textureChunk);
00142 _textureChunk->setEnvMode(GL_DECAL);
00143 _textureChunk->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
00144 _textureChunk->setMagFilter(GL_LINEAR);
00145 _textureChunk->setWrapS(GL_CLAMP);
00146 _textureChunk->setWrapT(GL_CLAMP);
00147 endEditCP (_textureChunk);
00148
00149 _texGenChunk = TexGenChunk::create();
00150 addRefCP(_texGenChunk);
00151 beginEditCP(_texGenChunk);
00152 _texGenChunk->setGenFuncS(GL_SPHERE_MAP);
00153 _texGenChunk->setGenFuncT(GL_SPHERE_MAP);
00154 endEditCP (_texGenChunk);
00155
00156 _blendChunk = BlendChunk::create();
00157 addRefCP(_blendChunk);
00158 beginEditCP(_blendChunk);
00159 _blendChunk->setSrcFactor (GL_SRC_ALPHA);
00160 _blendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
00161 endEditCP (_blendChunk);
00162 }
00163
00164 void FresnelMaterial::updateFresnel(void)
00165 {
00166 if(getImage() == NullFC)
00167 return;
00168
00169 if(getImage()->getPixelFormat() != Image::OSG_RGB_PF &&
00170 getImage()->getPixelFormat() != Image::OSG_RGBA_PF)
00171 {
00172 FWARNING(("FresnelMaterial::updateFresnel : pixelformat(%u) not supported\n", getImage()->getPixelFormat()));
00173 return;
00174 }
00175
00176 if(_img->getPixelFormat() != getImage()->getPixelFormat() ||
00177 _img->getWidth() != getImage()->getWidth() ||
00178 _img->getHeight() != getImage()->getHeight())
00179 {
00180 beginEditCP(_img);
00181 _img->set(Image::OSG_RGBA_PF, getImage()->getWidth(), getImage()->getHeight());
00182 endEditCP(_img);
00183 }
00184
00185 if(_textureChunk->getImage() != _img)
00186 {
00187 beginEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00188 _textureChunk->setImage(_img);
00189 endEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00190 }
00191
00192
00193 UInt8 *src = getImage()->getData();
00194 UInt8 *dst = _img->getData();
00195
00196 beginEditCP(_img);
00197
00198 Real32 bias = getBias();
00199 Real32 offset = getIndex();
00200 Real32 expo = getScale();
00201 Int32 width = _img->getWidth();
00202 Int32 height = _img->getHeight();
00203 Int32 bpp = getImage()->getBpp();
00204 Int32 ws = width / 2;
00205 Int32 hs = height / 2;
00206
00207 for(Int32 y = -hs; y < hs; ++y)
00208 {
00209 for(Int32 x = -ws; x < ws; ++x)
00210 {
00211 Real32 xs = (Real32) x / (Real32) width;
00212 Real32 ys = (Real32) y / (Real32) height;
00213
00214 Real32 a = osgpow(osgsqrt(xs * xs + ys * ys), expo) * bias + offset;
00215 UInt32 ac = ((UInt32) (a * 255.0f)) & 0xff;
00216
00217
00218 UInt32 i = (x + ws) + ((y + hs) * width);
00219
00220 UInt32 si = i * bpp;
00221 UInt32 di = i * 4;
00222
00223 dst[di++] = src[si++];
00224 dst[di++] = src[si++];
00225 dst[di++] = src[si];
00226 dst[di] = ac;
00227 }
00228 }
00229
00230 endEditCP(_img);
00231
00232 beginEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00233 _textureChunk->imageContentChanged();
00234 endEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00235 }
00236
00237
00238
00239 void FresnelMaterial::changed(BitVector whichField, UInt32 origin)
00240 {
00241 prepareLocalChunks();
00242
00243 if(whichField & ImageFieldMask)
00244 {
00245 if(origin & ChangedOrigin::Abstract)
00246 {
00247 if(origin & ChangedOrigin::AbstrIncRefCount)
00248 {
00249 addRefCP(_sfImage.getValue());
00250 }
00251 else
00252 {
00253 ImagePtr pImage = _sfImage.getValue();
00254
00255 _sfImage.setValue(NullFC);
00256
00257 setImage(pImage);
00258 }
00259 }
00260
00261 if(getImage() != NullFC)
00262 {
00263 beginEditCP(_img);
00264 _img->set(Image::OSG_RGBA_PF, getImage()->getWidth(), getImage()->getHeight());
00265 endEditCP(_img);
00266
00267 beginEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00268 _textureChunk->setImage(_img);
00269 endEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00270 }
00271 }
00272
00273 if((whichField & ImageFieldMask) ||
00274 (whichField & IndexFieldMask) ||
00275 (whichField & ScaleFieldMask) ||
00276 (whichField & BiasFieldMask))
00277 {
00278 updateFresnel();
00279 }
00280
00281 Inherited::changed(whichField, origin);
00282 }
00283
00284 void FresnelMaterial::dump( UInt32 ,
00285 const BitVector ) const
00286 {
00287 SLOG << "Dump FresnelMaterial NI" << std::endl;
00288 }
00289
00290 StatePtr FresnelMaterial::makeState(void)
00291 {
00292 StatePtr state = State::create();
00293
00294 Color3f v3;
00295 Color4f v4;
00296 float alpha = 1.f - getTransparency();
00297
00298 prepareLocalChunks();
00299
00300 beginEditCP(_materialChunk);
00301 v3 = getAmbient();
00302 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00303 _materialChunk->setAmbient(v4);
00304
00305 v3 = getDiffuse();
00306 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00307 _materialChunk->setDiffuse(v4);
00308
00309 v3 = getSpecular();
00310 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00311 _materialChunk->setSpecular(v4);
00312
00313 _materialChunk->setShininess(getShininess());
00314
00315 v3 = getEmission();
00316 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00317 _materialChunk->setEmission(v4);
00318
00319 _materialChunk->setLit(getLit());
00320 _materialChunk->setColorMaterial(getColorMaterial());
00321 endEditCP (_materialChunk);
00322
00323 state->addChunk(_materialChunk);
00324 state->addChunk(_textureChunk);
00325 state->addChunk(_texGenChunk);
00326
00327 if(isTransparent())
00328 state->addChunk(_blendChunk);
00329
00330 for(MFStateChunkPtr::iterator i = _mfChunks.begin();
00331 i != _mfChunks.end();
00332 ++i)
00333 {
00334 state->addChunk(*i);
00335 }
00336
00337 return state;
00338 }
00339
00340 void FresnelMaterial::rebuildState(void)
00341 {
00342 Color3f v3;
00343 Color4f v4;
00344 Real32 alpha = 1.f - getTransparency();
00345
00346 if(_pState != NullFC)
00347 {
00348 _pState->clearChunks();
00349 }
00350 else
00351 {
00352 _pState = State::create();
00353
00354 addRefCP(_pState);
00355 }
00356
00357 prepareLocalChunks();
00358
00359 beginEditCP(_materialChunk);
00360 v3 = getAmbient();
00361 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00362
00363 _materialChunk->setAmbient(v4);
00364
00365 v3 = getDiffuse();
00366 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00367
00368 _materialChunk->setDiffuse(v4);
00369
00370 v3 = getSpecular();
00371 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00372
00373 _materialChunk->setSpecular(v4);
00374
00375 _materialChunk->setShininess(getShininess());
00376
00377 v3 = getEmission();
00378 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00379
00380 _materialChunk->setEmission(v4);
00381
00382 _materialChunk->setLit(getLit());
00383 _materialChunk->setColorMaterial(getColorMaterial());
00384 endEditCP (_materialChunk);
00385
00386 _pState->addChunk(_materialChunk);
00387 _pState->addChunk(_textureChunk);
00388 _pState->addChunk(_texGenChunk);
00389
00390 if(isTransparent())
00391 _pState->addChunk(_blendChunk);
00392
00393 for(MFStateChunkPtr::iterator i = _mfChunks.begin();
00394 i != _mfChunks.end();
00395 ++i)
00396 {
00397 _pState->addChunk(*i);
00398 }
00399 }
00400
00401 bool FresnelMaterial::isTransparent(void) const
00402 {
00403 return ((getTransparency() > Eps) || (Inherited::isTransparent()));
00404 }
00405
00406
00407
00408
00409 #ifdef OSG_SGI_CC
00410 #pragma set woff 1174
00411 #endif
00412
00413 #ifdef OSG_LINUX_ICC
00414 #pragma warning( disable : 177 )
00415 #endif
00416
00417 namespace
00418 {
00419 static Char8 cvsid_cpp [] = "@(#)$Id: OSGFresnelMaterial.cpp,v 1.5 2006/04/13 16:24:29 a-m-z Exp $";
00420 static Char8 cvsid_hpp [] = OSGFRESNELMATERIAL_HEADER_CVSID;
00421 static Char8 cvsid_inl [] = OSGFRESNELMATERIAL_INLINE_CVSID;
00422
00423 static Char8 cvsid_fields_hpp[] = OSGFRESNELMATERIALFIELDS_HEADER_CVSID;
00424 }
00425
00426 #ifdef __sgi
00427 #pragma reset woff 1174
00428 #endif