OSGTexGenChunk.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 //---------------------------------------------------------------------------
00040 //  Includes
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 // Documentation for this class is emited in the
00062 // OSGTexGenChunkBase.cpp file.
00063 // To modify it, please change the .fcd file (OSGTexGenChunk.fcd) and
00064 // regenerate the base file.
00065
00066 /***************************************************************************\
00067  *                           Class variables                               *
00068 \***************************************************************************/
00069
00070 StateChunkClass TexGenChunk::_class("TexGen", osgMaxTexCoords, 20);
00071
00072 /***************************************************************************\
00073  *                           Class methods                                 *
00074 \***************************************************************************/
00075
00076 void TexGenChunk::initMethod(InitPhase ePhase)
00077 {
00078     Inherited::initMethod(ePhase);
00079 }
00080
00081 /***************************************************************************\
00082  *                           Instance methods                              *
00083 \***************************************************************************/
00084
00085 /*-------------------------------------------------------------------------*\
00086  -  private                                                                 -
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 /*------------------------- Chunk Class Access ---------------------------*/
00105
00106 const StateChunkClass *TexGenChunk::getClass(void) const
00107 {
00108     return &_class;
00109 }
00110
00111 /*------------------------------- Sync -----------------------------------*/
00112
00113 void TexGenChunk::changed(ConstFieldMaskArg whichField,
00114                           UInt32            origin,
00115                           BitVector         details)
00116 {
00117     Inherited::changed(whichField, origin, details);
00118 }
00119
00120 /*------------------------------ Output ----------------------------------*/
00121
00122 void TexGenChunk::dump(      UInt32    ,
00123                          const BitVector ) const
00124 {
00125     SLOG << "Dump TexGenChunk NI" << std::endl;
00126 }
00127
00128
00129 /*------------------------------ State ------------------------------------*/
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         // sgi doesn't support GL_MAX_TEXTURE_UNITS_ARB!
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     // genfuncs
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     // change from me to me?
00354     // this assumes I haven't changed in the meantime. 
00355     // is that a valid assumption?
00356     // No, for TexGen it's not, as TexGen depends on the current 
00357     // toWorld matrix!!!
00358     // if(old == this)
00359     //     return;
00360 #ifndef OSG_EMBEDDED
00361     TexGenChunk *oldp      = dynamic_cast<TexGenChunk *>(old);
00362
00363     // If the old one is not a texgen chunk, deactivate it and activate
00364     // ourselves
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         // sgi doesn't support GL_MAX_TEXTURE_UNITS_ARB!
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         // sgi doesn't support GL_MAX_TEXTURE_UNITS_ARB!
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 /*-------------------------- Comparison -----------------------------------*/
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             // not quite right. needs only to be tested for genfuncs using them
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