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 subRefCP(_materialChunk);
00107 subRefCP(_textureChunk);
00108 subRefCP(_texGenChunk);
00109 subRefCP(_blendChunk);
00110 subRefCP(_img);
00111 }
00112
00113 void FresnelMaterial::prepareLocalChunks(void)
00114 {
00115 if(_textureChunk != NullFC)
00116 return;
00117
00118 _img = Image::create();
00119 addRefCP(_img);
00120
00121 UInt8 imgdata[] = { 255,0,0,128, 0,255,0,128, 0,0,255,255, 255,255,255,255 };
00122
00123 beginEditCP(_img);
00124 _img->set( Image::OSG_RGBA_PF, 2, 2, 1, 1, 1, 0, imgdata);
00125 endEditCP(_img);
00126
00127 _materialChunk = MaterialChunk::create();
00128 addRefCP(_materialChunk);
00129
00130 _textureChunk = TextureChunk::create();
00131 addRefCP(_textureChunk);
00132 beginEditCP(_textureChunk);
00133 _textureChunk->setEnvMode(GL_DECAL);
00134 _textureChunk->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
00135 _textureChunk->setMagFilter(GL_LINEAR);
00136 _textureChunk->setWrapS(GL_CLAMP);
00137 _textureChunk->setWrapT(GL_CLAMP);
00138 endEditCP (_textureChunk);
00139
00140 _texGenChunk = TexGenChunk::create();
00141 addRefCP(_texGenChunk);
00142 beginEditCP(_texGenChunk);
00143 _texGenChunk->setGenFuncS(GL_SPHERE_MAP);
00144 _texGenChunk->setGenFuncT(GL_SPHERE_MAP);
00145 endEditCP (_texGenChunk);
00146
00147 _blendChunk = BlendChunk::create();
00148 addRefCP(_blendChunk);
00149 beginEditCP(_blendChunk);
00150 _blendChunk->setSrcFactor (GL_SRC_ALPHA);
00151 _blendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
00152 endEditCP (_blendChunk);
00153 }
00154
00155 void FresnelMaterial::updateFresnel(void)
00156 {
00157 if(getImage() == NullFC)
00158 return;
00159
00160 if(getImage()->getPixelFormat() != Image::OSG_RGB_PF &&
00161 getImage()->getPixelFormat() != Image::OSG_RGBA_PF)
00162 {
00163 FWARNING(("FresnelMaterial::updateFresnel : pixelformat(%u) not supported\n", getImage()->getPixelFormat()));
00164 return;
00165 }
00166
00167 #if 0
00168
00169 beginEditCP(_img);
00170 bool ok = getImage()->reformat(Image::OSG_BGRA_PF, _img);
00171 endEditCP(_img);
00172
00173 beginEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00174 _textureChunk->setImage(_img);
00175 endEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00176 #endif
00177
00178
00179 UInt8 *src = getImage()->getData();
00180 UInt8 *dst = _img->getData();
00181
00182 beginEditCP(_img);
00183
00184 Real32 bias = getBias();
00185 Real32 offset = getIndex();
00186 Real32 expo = getScale();
00187 Int32 width = _img->getWidth();
00188 Int32 height = _img->getHeight();
00189 Int32 bpp = getImage()->getBpp();
00190 Int32 ws = width / 2;
00191 Int32 hs = height / 2;
00192
00193 for(Int32 y = -hs; y < hs; ++y)
00194 {
00195 for(Int32 x = -ws; x < ws; ++x)
00196 {
00197 Real32 xs = (Real32) x / (Real32) width;
00198 Real32 ys = (Real32) y / (Real32) height;
00199
00200 Real32 a = osgpow(osgsqrt(xs * xs + ys * ys), expo) * bias + offset;
00201 UInt32 ac = ((UInt32) (a * 255.0f)) & 0xff;
00202
00203
00204 UInt32 i = (x + ws) + ((y + hs) * width);
00205
00206 UInt32 si = i * bpp;
00207 UInt32 di = i * 4;
00208
00209 dst[di++] = src[si++];
00210 dst[di++] = src[si++];
00211 dst[di++] = src[si];
00212 dst[di] = ac;
00213 }
00214 }
00215
00216 endEditCP(_img);
00217
00218 beginEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00219 _textureChunk->imageContentChanged();
00220 endEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00221 }
00222
00223
00224
00225 void FresnelMaterial::changed(BitVector whichField, UInt32 origin)
00226 {
00227 prepareLocalChunks();
00228
00229 if(whichField & ImageFieldMask)
00230 {
00231 if(origin & ChangedOrigin::Abstract)
00232 {
00233 if(origin & ChangedOrigin::AbstrIncRefCount)
00234 {
00235 addRefCP(_sfImage.getValue());
00236 }
00237 else
00238 {
00239 ImagePtr pImage = _sfImage.getValue();
00240
00241 _sfImage.setValue(NullFC);
00242
00243 setImage(pImage);
00244 }
00245 }
00246
00247 if(getImage() != NullFC)
00248 {
00249 beginEditCP(_img);
00250 _img->set(Image::OSG_RGBA_PF, getImage()->getWidth(), getImage()->getHeight());
00251 endEditCP(_img);
00252
00253 beginEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00254 _textureChunk->setImage(_img);
00255 endEditCP(_textureChunk, TextureChunk::ImageFieldMask);
00256 }
00257 }
00258
00259 if((whichField & ImageFieldMask) ||
00260 (whichField & IndexFieldMask) ||
00261 (whichField & ScaleFieldMask) ||
00262 (whichField & BiasFieldMask))
00263 {
00264 updateFresnel();
00265 }
00266
00267 Inherited::changed(whichField, origin);
00268 }
00269
00270 void FresnelMaterial::dump( UInt32 ,
00271 const BitVector ) const
00272 {
00273 SLOG << "Dump FresnelMaterial NI" << std::endl;
00274 }
00275
00276 StatePtr FresnelMaterial::makeState(void)
00277 {
00278 StatePtr state = State::create();
00279
00280 Color3f v3;
00281 Color4f v4;
00282 float alpha = 1.f - getTransparency();
00283
00284 prepareLocalChunks();
00285
00286 beginEditCP(_materialChunk);
00287 v3 = getAmbient();
00288 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00289 _materialChunk->setAmbient(v4);
00290
00291 v3 = getDiffuse();
00292 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00293 _materialChunk->setDiffuse(v4);
00294
00295 v3 = getSpecular();
00296 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00297 _materialChunk->setSpecular(v4);
00298
00299 _materialChunk->setShininess(getShininess());
00300
00301 v3 = getEmission();
00302 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00303 _materialChunk->setEmission(v4);
00304
00305 _materialChunk->setLit(getLit());
00306 _materialChunk->setColorMaterial(getColorMaterial());
00307 endEditCP (_materialChunk);
00308
00309 state->addChunk(_materialChunk);
00310 state->addChunk(_textureChunk);
00311 state->addChunk(_texGenChunk);
00312
00313 if(isTransparent())
00314 state->addChunk(_blendChunk);
00315
00316 for(MFStateChunkPtr::iterator i = _mfChunks.begin();
00317 i != _mfChunks.end();
00318 ++i)
00319 {
00320 state->addChunk(*i);
00321 }
00322
00323 return state;
00324 }
00325
00326 void FresnelMaterial::rebuildState(void)
00327 {
00328 Color3f v3;
00329 Color4f v4;
00330 Real32 alpha = 1.f - getTransparency();
00331
00332 if(_pState != NullFC)
00333 {
00334 _pState->clearChunks();
00335 }
00336 else
00337 {
00338 _pState = State::create();
00339
00340 addRefCP(_pState);
00341 }
00342
00343 prepareLocalChunks();
00344
00345 beginEditCP(_materialChunk);
00346 v3 = getAmbient();
00347 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00348
00349 _materialChunk->setAmbient(v4);
00350
00351 v3 = getDiffuse();
00352 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00353
00354 _materialChunk->setDiffuse(v4);
00355
00356 v3 = getSpecular();
00357 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00358
00359 _materialChunk->setSpecular(v4);
00360
00361 _materialChunk->setShininess(getShininess());
00362
00363 v3 = getEmission();
00364 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00365
00366 _materialChunk->setEmission(v4);
00367
00368 _materialChunk->setLit(getLit());
00369 _materialChunk->setColorMaterial(getColorMaterial());
00370 endEditCP (_materialChunk);
00371
00372 _pState->addChunk(_materialChunk);
00373 _pState->addChunk(_textureChunk);
00374 _pState->addChunk(_texGenChunk);
00375
00376 if(isTransparent())
00377 _pState->addChunk(_blendChunk);
00378
00379 for(MFStateChunkPtr::iterator i = _mfChunks.begin();
00380 i != _mfChunks.end();
00381 ++i)
00382 {
00383 _pState->addChunk(*i);
00384 }
00385 }
00386
00387 bool FresnelMaterial::isTransparent(void) const
00388 {
00389 return ((getTransparency() > Eps) || (Inherited::isTransparent()));
00390 }
00391
00392
00393
00394
00395 #ifdef OSG_SGI_CC
00396 #pragma set woff 1174
00397 #endif
00398
00399 #ifdef OSG_LINUX_ICC
00400 #pragma warning( disable : 177 )
00401 #endif
00402
00403 namespace
00404 {
00405 static Char8 cvsid_cpp [] = "@(#)$Id: OSGFresnelMaterial.cpp,v 1.4 2005/06/29 11:41:13 a-m-z Exp $";
00406 static Char8 cvsid_hpp [] = OSGFRESNELMATERIAL_HEADER_CVSID;
00407 static Char8 cvsid_inl [] = OSGFRESNELMATERIAL_INLINE_CVSID;
00408
00409 static Char8 cvsid_fields_hpp[] = OSGFRESNELMATERIALFIELDS_HEADER_CVSID;
00410 }
00411
00412 #ifdef __sgi
00413 #pragma reset woff 1174
00414 #endif