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 <OSGGeometry.h>
00049 #include <OSGCamera.h>
00050 #include <OSGTextureChunk.h>
00051 #include <OSGWindow.h>
00052
00053 #include "OSGPhongMaterial.h"
00054
00055 OSG_USING_NAMESPACE
00056
00061
00062 static std::string _phong_vp_prg =
00063 "!!ARBvp1.0\n"
00064 "OPTION ARB_position_invariant;\n"
00065 "\n"
00066 "PARAM lightPos = state.light[0].position;\n"
00067 "# using now -m[3] for camera position.\n"
00068 "#PARAM cameraPos = program.local[0];\n"
00069 "PARAM m[4]={state.matrix.modelview};\n"
00070 "PARAM mvinv[4]={state.matrix.modelview.invtrans};\n"
00071 "\n"
00072 "TEMP EyeCamPos, EyeNormal, EyeVertex;\n"
00073 "\n"
00074 "#Vertex position in eye space...\n"
00075 "DP4 EyeVertex.x, m[0], vertex.position;\n"
00076 "DP4 EyeVertex.y, m[1], vertex.position;\n"
00077 "DP4 EyeVertex.z, m[2], vertex.position;\n"
00078 "\n"
00079 "#Transform the camera pos to eye space.\n"
00080 "DP4 EyeCamPos.x, m[0], -m[3];\n"
00081 "DP4 EyeCamPos.y, m[1], -m[3];\n"
00082 "DP4 EyeCamPos.z, m[2], -m[3];\n"
00083 "\n"
00084 "#Transform the normal to eye space.\n"
00085 "DP3 EyeNormal.x, mvinv[0], vertex.normal;\n"
00086 "DP3 EyeNormal.y, mvinv[1], vertex.normal;\n"
00087 "DP3 EyeNormal.z, mvinv[2], vertex.normal;\n"
00088 "\n"
00089 "#Normalize\n"
00090 "DP3 EyeNormal.w, EyeNormal, EyeNormal;\n"
00091 "RSQ EyeNormal.w, EyeNormal.w;\n"
00092 "MUL EyeNormal, EyeNormal, EyeNormal.w;\n"
00093 "\n"
00094 "MOV result.texcoord[0], vertex.texcoord[0];\n"
00095 "SUB result.texcoord[1], state.light[0].position, EyeVertex;\n"
00096 "SUB result.texcoord[2], EyeCamPos, EyeVertex;\n"
00097 "MOV result.texcoord[3], EyeNormal;\n"
00098 "END\n";
00099
00100 static std::string _phong_fp_begin_prg =
00101 "!!ARBfp1.0\n"
00102 "TEMP lightVec, viewVec, reflVec, normal, attenuation, Len, finalCol, lightContrib, tex;\n"
00103 "PARAM two = {2.0, 2.0, 2.0, 2.0};\n"
00104 "PARAM m_one = {-1.0, -1.0, -1.0, -1.0};\n"
00105 "\n"
00106 "TEX tex, fragment.texcoord[0], texture[0], 2D;\n"
00107 "\n"
00108 "#Normalize normal, lightvec and viewvec.\n"
00109 "DP3 Len.w, fragment.texcoord[1], fragment.texcoord[1];\n"
00110 "RSQ lightVec.w, Len.w;\n"
00111 "MUL lightVec.xyz, fragment.texcoord[1], lightVec.w;\n"
00112 "\n"
00113 "DP3 viewVec.w, fragment.texcoord[2], fragment.texcoord[2];\n"
00114 "RSQ viewVec.w, viewVec.w;\n"
00115 "MUL viewVec.xyz, fragment.texcoord[2], viewVec.w;\n"
00116 "\n"
00117 "DP3 normal.w, fragment.texcoord[3], fragment.texcoord[3];\n"
00118 "RSQ normal.w, normal.w;\n"
00119 "MUL normal.xyz, fragment.texcoord[3], normal.w;\n"
00120 "\n"
00121 "#Calculate attenuation.\n"
00122 "MAD attenuation, state.light[0].attenuation.z, Len.w, state.light[0].attenuation.x;\n"
00123 "RCP Len, lightVec.w;\n"
00124 "MAD attenuation, Len.w, state.light[0].attenuation.y, attenuation.x;\n"
00125 "RCP attenuation.x, attenuation.x;\n"
00126 "\n"
00127 "#Diffuse\n"
00128 "DP3_SAT lightContrib.x, normal, lightVec;\n"
00129 "\n"
00130 "#Specular\n"
00131 "# Phong:\n"
00132 "DP3 reflVec, lightVec, normal;\n"
00133 "MUL reflVec, reflVec, two;\n"
00134 "MAD reflVec, reflVec, normal, -lightVec;\n"
00135 "\n"
00136 "DP3_SAT lightContrib.y, reflVec, viewVec;\n"
00137 "\n"
00138 "# Blinn:\n"
00139 "# ADD reflVec, lightVec, viewVec; # reflVec == Half-angle.\n"
00140 "# DP3 reflVec.w, reflVec, reflVec;\n"
00141 "# RSQ reflVec.w, reflVec.w;\n"
00142 "# MUL reflVec.xyz, reflVec, reflVec.w;\n"
00143 "# DP3 lightContrib.y, reflVec, normal;\n"
00144 "\n"
00145 "MOV lightContrib.w, state.material.shininess.x;\n"
00146 "\n"
00147 "#Accelerates lighting computations\n"
00148 "LIT_SAT lightContrib, lightContrib;\n"
00149 "\n"
00150 "MAD finalCol, lightContrib.y, state.lightprod[0].diffuse, state.lightprod[0].ambient;\n"
00151 "\n"
00152 "# Enable this line for textured models\n";
00153 static std::string _phong_fp_tex_prg =
00154 "MUL finalCol, finalCol, tex; # Texture?\n";
00155
00156 static std::string _phong_fp_end_prg =
00157 "MAD finalCol, lightContrib.z, state.lightprod[0].specular, finalCol;\n"
00158 "MAD finalCol, finalCol, attenuation.x, state.material.emission;\n"
00159 "ADD result.color.xyz, finalCol, state.lightmodel.scenecolor;\n"
00160 "MOV result.color.w, state.material.diffuse.w;\n"
00161 "END\n";
00162
00163
00164
00165
00166
00167
00168 UInt32 PhongMaterial::_arbFragmentProgram;
00169
00170
00171
00172
00173
00174 void PhongMaterial::initMethod (void)
00175 {
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 PhongMaterial::PhongMaterial(void) :
00190 Inherited(),
00191 _materialChunk(NullFC),
00192 _blendChunk(NullFC),
00193 _vpChunk(NullFC),
00194 _fpChunk(NullFC)
00195 {
00196 }
00197
00198 PhongMaterial::PhongMaterial(const PhongMaterial &source) :
00199 Inherited(source),
00200 _materialChunk(source._materialChunk),
00201 _blendChunk(source._blendChunk),
00202 _vpChunk(source._vpChunk),
00203 _fpChunk(source._fpChunk)
00204 {
00205 _arbFragmentProgram = Window::registerExtension("GL_ARB_fragment_program");
00206 }
00207
00208 PhongMaterial::~PhongMaterial(void)
00209 {
00210 subRefCP(_materialChunk);
00211 subRefCP(_blendChunk);
00212 subRefCP(_vpChunk);
00213 subRefCP(_fpChunk);
00214 }
00215
00216 void PhongMaterial::prepareLocalChunks(void)
00217 {
00218 if(_materialChunk != NullFC)
00219 return;
00220
00221 _materialChunk = MaterialChunk::create();
00222 addRefCP(_materialChunk);
00223
00224 _blendChunk = BlendChunk::create();
00225 addRefCP(_blendChunk);
00226 beginEditCP(_blendChunk);
00227 _blendChunk->setSrcFactor (GL_SRC_ALPHA);
00228 _blendChunk->setDestFactor(GL_ONE_MINUS_SRC_ALPHA);
00229 endEditCP (_blendChunk);
00230
00231
00232
00233
00234
00235
00236 if(Window::hasCommonExtension(_arbFragmentProgram))
00237 {
00238 _vpChunk = VertexProgramChunk::create();
00239 addRefCP(_vpChunk);
00240 beginEditCP(_vpChunk);
00241 _vpChunk->setProgram(_phong_vp_prg);
00242 endEditCP(_vpChunk);
00243
00244 _fpChunk = FragmentProgramChunk::create();
00245 addRefCP(_fpChunk);
00246 createFragmentProgram();
00247 }
00248 }
00249
00250 void PhongMaterial::createFragmentProgram(void)
00251 {
00252 if(_fpChunk == NullFC)
00253 return;
00254
00255 bool has_tex_chunk = false;
00256 for(MFStateChunkPtr::iterator i = _mfChunks.begin();
00257 i != _mfChunks.end();
00258 ++i)
00259 {
00260 if(TextureChunkPtr::dcast(*i) != NullFC)
00261 {
00262 has_tex_chunk = true;
00263 break;
00264 }
00265 }
00266
00267 std::string phong_fp_prg;
00268 beginEditCP(_fpChunk);
00269 if(has_tex_chunk)
00270 phong_fp_prg = _phong_fp_begin_prg + _phong_fp_tex_prg + _phong_fp_end_prg;
00271 else
00272 phong_fp_prg = _phong_fp_begin_prg + _phong_fp_end_prg;
00273 _fpChunk->setProgram(phong_fp_prg);
00274 endEditCP(_fpChunk);
00275 }
00276
00277
00278
00279 void PhongMaterial::changed(BitVector whichField, UInt32 origin)
00280 {
00281 Inherited::changed(whichField, origin);
00282 }
00283
00284 void PhongMaterial::dump( UInt32 ,
00285 const BitVector ) const
00286 {
00287 SLOG << "Dump PhongMaterial NI" << std::endl;
00288 }
00289
00290 StatePtr PhongMaterial::makeState(void)
00291 {
00292 StatePtr state = State::create();
00293
00294 prepareLocalChunks();
00295
00296 Color3f v3;
00297 Color4f v4;
00298 float alpha = 1.f - getTransparency();
00299
00300 prepareLocalChunks();
00301
00302 beginEditCP(_materialChunk);
00303 v3 = getAmbient();
00304 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00305 _materialChunk->setAmbient(v4);
00306
00307 v3 = getDiffuse();
00308 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00309 _materialChunk->setDiffuse(v4);
00310
00311 v3 = getSpecular();
00312 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00313 _materialChunk->setSpecular(v4);
00314
00315 _materialChunk->setShininess(getShininess());
00316
00317 v3 = getEmission();
00318 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00319 _materialChunk->setEmission(v4);
00320
00321 _materialChunk->setLit(getLit());
00322 _materialChunk->setColorMaterial(getColorMaterial());
00323 endEditCP (_materialChunk);
00324 state->addChunk(_materialChunk);
00325
00326 if(isTransparent())
00327 state->addChunk(_blendChunk);
00328
00329 if(_vpChunk != NullFC)
00330 state->addChunk(_vpChunk);
00331
00332 createFragmentProgram();
00333
00334 if(_fpChunk != NullFC)
00335 state->addChunk(_fpChunk);
00336
00337 for(MFStateChunkPtr::iterator i = _mfChunks.begin();
00338 i != _mfChunks.end();
00339 ++i)
00340 {
00341 state->addChunk(*i);
00342 }
00343
00344 return state;
00345 }
00346
00347 void PhongMaterial::rebuildState(void)
00348 {
00349 if(_pState != NullFC)
00350 {
00351 _pState->clearChunks();
00352 }
00353 else
00354 {
00355 _pState = State::create();
00356
00357 addRefCP(_pState);
00358 }
00359
00360 prepareLocalChunks();
00361
00362 Color3f v3;
00363 Color4f v4;
00364 float alpha = 1.f - getTransparency();
00365
00366 beginEditCP(_materialChunk);
00367 v3 = getAmbient();
00368 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00369 _materialChunk->setAmbient(v4);
00370
00371 v3 = getDiffuse();
00372 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00373 _materialChunk->setDiffuse(v4);
00374
00375 v3 = getSpecular();
00376 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00377 _materialChunk->setSpecular(v4);
00378
00379 _materialChunk->setShininess(getShininess());
00380
00381 v3 = getEmission();
00382 v4.setValuesRGBA(v3[0], v3[1], v3[2], alpha);
00383 _materialChunk->setEmission(v4);
00384
00385 _materialChunk->setLit(getLit());
00386 _materialChunk->setColorMaterial(getColorMaterial());
00387 endEditCP(_materialChunk);
00388 _pState->addChunk(_materialChunk);
00389
00390 if(isTransparent())
00391 _pState->addChunk(_blendChunk);
00392
00393 if(_vpChunk != NullFC)
00394 _pState->addChunk(_vpChunk);
00395
00396 createFragmentProgram();
00397
00398 if(_fpChunk != NullFC)
00399 _pState->addChunk(_fpChunk);
00400
00401 for(MFStateChunkPtr::iterator i = _mfChunks.begin();
00402 i != _mfChunks.end();
00403 ++i)
00404 {
00405 _pState->addChunk(*i);
00406 }
00407 }
00408
00409 bool PhongMaterial::isTransparent(void) const
00410 {
00411 return ((getTransparency() > Eps) || (Inherited::isTransparent()));
00412 }
00413
00414 ChunkMaterialPtr PhongMaterial::createChunkMaterial(void)
00415 {
00416 _arbFragmentProgram = Window::registerExtension("GL_ARB_fragment_program");
00417
00418 ChunkMaterialPtr cmat = ChunkMaterial::create();
00419
00420 MaterialChunkPtr matc = MaterialChunk::create();
00421 beginEditCP(matc);
00422 matc->setAmbient(Color4f(0.1, 0.1, 0.2, 1.0));
00423 matc->setDiffuse(Color4f(0.2, 0.2, 0.8, 1.0));
00424 matc->setSpecular(Color4f(0.8, 0.8, 0.8, 1.0));
00425 matc->setShininess(100);
00426 endEditCP(matc);
00427
00428 beginEditCP(cmat, ChunksFieldMask);
00429 cmat->addChunk(matc);
00430 endEditCP(cmat, ChunksFieldMask);
00431
00432
00433
00434 if(Window::hasCommonExtension(_arbFragmentProgram))
00435 {
00436 VertexProgramChunkPtr vpc = VertexProgramChunk::create();
00437 beginEditCP(vpc);
00438 vpc->setProgram(_phong_vp_prg);
00439 endEditCP(vpc);
00440
00441 FragmentProgramChunkPtr fpc = FragmentProgramChunk::create();
00442 std::string phong_fp_prg = _phong_fp_begin_prg + _phong_fp_end_prg;
00443 beginEditCP(fpc);
00444 fpc->setProgram(phong_fp_prg);
00445 endEditCP(fpc);
00446
00447 beginEditCP(cmat, ChunksFieldMask);
00448 cmat->addChunk(vpc);
00449 cmat->addChunk(fpc);
00450 endEditCP(cmat, ChunksFieldMask);
00451 }
00452 return cmat;
00453 }
00454
00455
00456
00457
00458 #ifdef OSG_SGI_CC
00459 #pragma set woff 1174
00460 #endif
00461
00462 #ifdef OSG_LINUX_ICC
00463 #pragma warning( disable : 177 )
00464 #endif
00465
00466 namespace
00467 {
00468 static Char8 cvsid_cpp [] = "@(#)$Id: OSGPhongMaterial.cpp,v 1.7 2003/10/17 16:02:46 a-m-z Exp $";
00469 static Char8 cvsid_hpp [] = OSGPHONGMATERIAL_HEADER_CVSID;
00470 static Char8 cvsid_inl [] = OSGPHONGMATERIAL_INLINE_CVSID;
00471
00472 static Char8 cvsid_fields_hpp[] = OSGPHONGMATERIALFIELDS_HEADER_CVSID;
00473 }
00474
00475 #ifdef __sgi
00476 #pragma reset woff 1174
00477 #endif