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 <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047
00048 #include "OSGGL.h"
00049 #include "OSGGLU.h"
00050
00051 #include "OSGDrawEnv.h"
00052
00053 #include "OSGTextureBaseChunk.h"
00054
00055 #include "OSGTexGenChunk.h"
00056 #include "OSGCamera.h"
00057 #include "OSGViewport.h"
00058
00059 OSG_USING_NAMESPACE
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 StateChunkClass TexGenChunk::_class("TexGen", osgMaxTexCoords, 20);
00071
00072
00073
00074
00075
00076 void TexGenChunk::initMethod(InitPhase ePhase)
00077 {
00078 Inherited::initMethod(ePhase);
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 TexGenChunk::TexGenChunk(void) :
00090 Inherited()
00091 {
00092 _sfEyeModelViewMatrix.getValue().setIdentity();
00093 }
00094
00095 TexGenChunk::TexGenChunk(const TexGenChunk &source) :
00096 Inherited(source)
00097 {
00098 }
00099
00100 TexGenChunk::~TexGenChunk(void)
00101 {
00102 }
00103
00104
00105
00106 const StateChunkClass *TexGenChunk::getClass(void) const
00107 {
00108 return &_class;
00109 }
00110
00111
00112
00113 void TexGenChunk::changed(ConstFieldMaskArg whichField,
00114 UInt32 origin,
00115 BitVector details)
00116 {
00117 Inherited::changed(whichField, origin, details);
00118 }
00119
00120
00121
00122 void TexGenChunk::dump( UInt32 ,
00123 const BitVector ) const
00124 {
00125 SLOG << "Dump TexGenChunk NI" << std::endl;
00126 }
00127
00128
00129
00130
00131 static inline void setGenFunc( GLenum coord,
00132 GLenum gen,
00133 GLenum func,
00134 const Vec4f &plane,
00135 Node *beacon,
00136 Matrix &cameraMat,
00137 UInt32 eyeMode,
00138 Matrix &eyeMatrix)
00139 {
00140 #ifndef OSG_EMBEDDED
00141 if(beacon != NULL)
00142 {
00143 Matrixr beaconMat;
00144 beacon->getToWorld(beaconMat);
00145 beaconMat.multLeft(cameraMat);
00146 glPushMatrix();
00147 glLoadMatrixf(beaconMat.getValues());
00148 glTexGenfv(coord,
00149 GL_EYE_PLANE,
00150 const_cast<GLfloat *>(plane.getValues()));
00151 glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00152 glPopMatrix();
00153 glEnable(gen);
00154 }
00155 else if(func == GL_EYE_LINEAR)
00156 {
00157 glPushMatrix();
00158
00159 switch(eyeMode)
00160 {
00161 case TexGenChunk::EyeModelViewIdentity:
00162 glLoadIdentity();
00163 break;
00164
00165 case TexGenChunk::EyeModelViewStored:
00166 glLoadMatrixf(eyeMatrix.getValues());
00167 break;
00168
00169 case TexGenChunk::EyeModelViewCamera:
00170 glLoadMatrixf(cameraMat.getValues());
00171 break;
00172
00173 default:
00174 break;
00175 }
00176
00177 glTexGenfv(coord,
00178 GL_EYE_PLANE,
00179 const_cast<GLfloat *>(plane.getValues()));
00180
00181 glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00182
00183 glPopMatrix();
00184
00185 glEnable(gen);
00186 }
00187 else if(func != GL_NONE)
00188 {
00189 glTexGeni(coord, GL_TEXTURE_GEN_MODE, func);
00190
00191 if(func == GL_OBJECT_LINEAR)
00192 {
00193 glTexGenfv(coord,
00194 GL_OBJECT_PLANE,
00195 const_cast<GLfloat *>(plane.getValues()));
00196 }
00197
00198 glEnable(gen);
00199 }
00200 #endif
00201 }
00202
00203 void TexGenChunk::activate(DrawEnv *pEnv, UInt32 idx)
00204 {
00205 glErr("TexGenChunk::activate precheck");
00206
00207 #ifndef OSG_EMBEDDED
00208 Window *win = pEnv->getWindow();
00209
00210 Real32 ntexcoords;
00211 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
00212 Window::unknownConstant
00213 )
00214 {
00215 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
00216
00217 if(ntexcoords == Window::unknownConstant)
00218 ntexcoords = 1.0f;
00219 }
00220
00221 if(idx >= static_cast<UInt32>(ntexcoords))
00222 {
00223 #ifdef OSG_DEBUG
00224 FWARNING(("TexGenChunk::activate: Trying to bind texcoord unit %d,"
00225 " but Window %p only supports %lf!\n",
00226 idx, win, ntexcoords));
00227 #endif
00228 return;
00229 }
00230
00231 TextureBaseChunk::activateTexture(win, idx);
00232
00233 FDEBUG(("TexGenChunk::activate\n"));
00234
00235 Matrix cameraMat = pEnv->getCameraViewing();
00236
00237 #if OLD_DA
00238 Viewport *vp = pEnv->getViewport();
00239 if(vp != NULL)
00240 {
00241 pEnv->getCamera()->getViewing(cameraMat,
00242 vp->getPixelWidth(),
00243 vp->getPixelHeight());
00244 }
00245 #endif
00246
00247
00248 setGenFunc(GL_S, GL_TEXTURE_GEN_S, getGenFuncS(), getGenFuncSPlane(),
00249 getSBeacon(), cameraMat, _sfEyeModelViewMode.getValue(),
00250 _sfEyeModelViewMatrix.getValue());
00251 glErr("TexGenChunk::activateS");
00252 setGenFunc(GL_T, GL_TEXTURE_GEN_T, getGenFuncT(), getGenFuncTPlane(),
00253 getTBeacon(), cameraMat, _sfEyeModelViewMode.getValue(),
00254 _sfEyeModelViewMatrix.getValue());
00255 glErr("TexGenChunk::activateT");
00256 setGenFunc(GL_R, GL_TEXTURE_GEN_R, getGenFuncR(), getGenFuncRPlane(),
00257 getRBeacon(), cameraMat, _sfEyeModelViewMode.getValue(),
00258 _sfEyeModelViewMatrix.getValue());
00259 glErr("TexGenChunk::activateR");
00260 setGenFunc(GL_Q, GL_TEXTURE_GEN_Q, getGenFuncQ(), getGenFuncQPlane(),
00261 getQBeacon(), cameraMat, _sfEyeModelViewMode.getValue(),
00262 _sfEyeModelViewMatrix.getValue());
00263 glErr("TexGenChunk::activateQ");
00264 #endif
00265 }
00266
00267
00268 static inline void changeGenFunc( GLenum oldfunc,
00269 Node *oldbeacon,
00270 GLenum coord,
00271 GLenum gen,
00272 GLenum func,
00273 const Vec4f &plane,
00274 Node *beacon,
00275 Matrix &cameraMat,
00276 UInt32 eyeMode,
00277 Matrix &eyeMatrix)
00278 {
00279 #ifndef OSG_EMBEDDED
00280 if(beacon != NULL)
00281 {
00282 Matrix beaconMat;
00283 beacon->getToWorld(beaconMat);
00284 beaconMat.multLeft(cameraMat);
00285 glPushMatrix();
00286 glLoadMatrixf(beaconMat.getValues());
00287 glTexGenfv(coord,
00288 GL_EYE_PLANE,
00289 const_cast<GLfloat *>(plane.getValues()));
00290 glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00291 glPopMatrix();
00292 if(oldfunc == GL_NONE && oldbeacon == NULL)
00293 glEnable(gen);
00294 }
00295 else if(func == GL_EYE_LINEAR)
00296 {
00297 glPushMatrix();
00298
00299 switch(eyeMode)
00300 {
00301 case TexGenChunk::EyeModelViewIdentity:
00302 glLoadIdentity();
00303 break;
00304
00305 case TexGenChunk::EyeModelViewStored:
00306 glLoadMatrixf(eyeMatrix.getValues());
00307 break;
00308
00309 case TexGenChunk::EyeModelViewCamera:
00310 glLoadMatrixf(cameraMat.getValues());
00311 break;
00312
00313 default:
00314 break;
00315 }
00316
00317 glTexGenfv(coord,
00318 GL_EYE_PLANE,
00319 const_cast<GLfloat *>(plane.getValues()));
00320
00321 glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00322
00323 glPopMatrix();
00324
00325 if(oldfunc == GL_NONE && oldbeacon == NULL)
00326 glEnable(gen);
00327 }
00328 else if(func != GL_NONE)
00329 {
00330 glTexGeni(coord, GL_TEXTURE_GEN_MODE, func);
00331
00332 if(func == GL_OBJECT_LINEAR)
00333 {
00334 glTexGenfv(coord,
00335 GL_OBJECT_PLANE,
00336 const_cast<GLfloat *>(plane.getValues()));
00337 }
00338
00339 if(oldfunc == GL_NONE && oldbeacon == NULL)
00340 glEnable(gen);
00341 }
00342 else if(oldfunc != GL_NONE || oldbeacon != NULL)
00343 {
00344 glDisable(gen);
00345 }
00346 #endif
00347 }
00348
00349 void TexGenChunk::changeFrom(DrawEnv *pEnv,
00350 StateChunk *old ,
00351 UInt32 idx)
00352 {
00353
00354
00355
00356
00357
00358
00359
00360 #ifndef OSG_EMBEDDED
00361 TexGenChunk *oldp = dynamic_cast<TexGenChunk *>(old);
00362
00363
00364
00365 if(!oldp)
00366 {
00367 old->deactivate(pEnv, idx);
00368 activate(pEnv, idx);
00369 return;
00370 }
00371
00372 glErr("TexGenChunk::changeFrom precheck");
00373
00374 Window *win = pEnv->getWindow();
00375
00376 Real32 ntexcoords;
00377 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
00378 Window::unknownConstant
00379 )
00380 {
00381 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
00382
00383 if(ntexcoords == Window::unknownConstant)
00384 ntexcoords = 1.0f;
00385 }
00386
00387 if(idx >= static_cast<UInt32>(ntexcoords))
00388 {
00389 #ifdef OSG_DEBUG
00390 FWARNING(("TexGenChunk::changeFrom: Trying to bind texcoord unit "
00391 "%d, but Window %p only supports %lf!\n",
00392 idx, win, ntexcoords));
00393 #endif
00394 return;
00395 }
00396
00397 Matrix cameraMat = pEnv->getCameraViewing();
00398
00399 #ifdef OLD_DA
00400 Viewport *vp = pEnv->getViewport();
00401 if(vp != NULL)
00402 {
00403 pEnv->getCamera()->getViewing(cameraMat,
00404 vp->getPixelWidth(),
00405 vp->getPixelHeight());
00406 }
00407 #endif
00408
00409 TextureBaseChunk::activateTexture(win, idx);
00410
00411 changeGenFunc(oldp->getGenFuncS(),
00412 oldp->getSBeacon(),
00413 GL_S,
00414 GL_TEXTURE_GEN_S,
00415 getGenFuncS(),
00416 getGenFuncSPlane(),
00417 getSBeacon(),
00418 cameraMat,
00419 _sfEyeModelViewMode.getValue(),
00420 _sfEyeModelViewMatrix.getValue());
00421
00422 changeGenFunc(oldp->getGenFuncT(), oldp->getTBeacon(), GL_T,
00423 GL_TEXTURE_GEN_T,
00424 getGenFuncT(), getGenFuncTPlane(), getTBeacon(), cameraMat,
00425 _sfEyeModelViewMode.getValue(),
00426 _sfEyeModelViewMatrix.getValue());
00427
00428 changeGenFunc(oldp->getGenFuncR(), oldp->getRBeacon(), GL_R,
00429 GL_TEXTURE_GEN_R,
00430 getGenFuncR(), getGenFuncRPlane(), getRBeacon(), cameraMat,
00431 _sfEyeModelViewMode.getValue(),
00432 _sfEyeModelViewMatrix.getValue());
00433
00434 changeGenFunc(oldp->getGenFuncQ(), oldp->getQBeacon(), GL_Q,
00435 GL_TEXTURE_GEN_Q,
00436 getGenFuncQ(), getGenFuncQPlane(), getQBeacon(), cameraMat,
00437 _sfEyeModelViewMode.getValue(),
00438 _sfEyeModelViewMatrix.getValue());
00439
00440 #endif
00441 glErr("TexGenChunk::changeFrom");
00442 }
00443
00444 void TexGenChunk::deactivate(DrawEnv *pEnv, UInt32 idx)
00445 {
00446 glErr("TexGenChunk::deactivate precheck");
00447
00448 #ifndef OSG_EMBEDDED
00449 Window *win = pEnv->getWindow();
00450
00451 Real32 ntexcoords;
00452 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
00453 Window::unknownConstant
00454 )
00455 {
00456 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
00457
00458 if(ntexcoords == Window::unknownConstant)
00459 ntexcoords = 1.0f;
00460 }
00461
00462 if(idx >= static_cast<UInt32>(ntexcoords))
00463 {
00464 #ifdef OSG_DEBUG
00465 FWARNING(("TexGenChunk::deactivate: Trying to bind texcoord unit %d,"
00466 " but Window %p only supports %lf!\n",
00467 idx, win, ntexcoords));
00468 #endif
00469 return;
00470 }
00471
00472 TextureBaseChunk::activateTexture(win, idx);
00473
00474 if(getGenFuncS() != GL_NONE || getSBeacon() != NULL)
00475 glDisable(GL_TEXTURE_GEN_S);
00476
00477 if(getGenFuncT() != GL_NONE || getTBeacon() != NULL)
00478 glDisable(GL_TEXTURE_GEN_T);
00479
00480 if(getGenFuncR() != GL_NONE || getRBeacon() != NULL)
00481 glDisable(GL_TEXTURE_GEN_R);
00482
00483 if(getGenFuncQ() != GL_NONE || getQBeacon() != NULL)
00484 glDisable(GL_TEXTURE_GEN_Q);
00485
00486 glErr("TexGenChunk::deactivate");
00487 #endif
00488 }
00489
00490
00491
00492 Real32 TexGenChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
00493 {
00494 return 0;
00495 }
00496
00497 bool TexGenChunk::operator < (const StateChunk &other) const
00498 {
00499 return this < &other;
00500 }
00501
00502 bool TexGenChunk::operator == (const StateChunk &other) const
00503 {
00504 TexGenChunk const *tother = dynamic_cast<TexGenChunk const*>(&other);
00505
00506 if(!tother)
00507 return false;
00508
00509 if(tother == this)
00510 return true;
00511
00512 return getGenFuncS() == tother->getGenFuncS() &&
00513 getGenFuncT() == tother->getGenFuncT() &&
00514 getGenFuncR() == tother->getGenFuncR() &&
00515 getGenFuncQ() == tother->getGenFuncQ() &&
00516
00517 getGenFuncSPlane() == tother->getGenFuncSPlane() &&
00518 getGenFuncTPlane() == tother->getGenFuncTPlane() &&
00519 getGenFuncRPlane() == tother->getGenFuncRPlane() &&
00520 getGenFuncQPlane() == tother->getGenFuncQPlane() ;
00521 }
00522
00523 bool TexGenChunk::operator != (const StateChunk &other) const
00524 {
00525 return ! (*this == other);
00526 }
00527