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 <OSGGL.h>
00049 #include <OSGGLU.h>
00050
00051 #include "OSGDrawActionBase.h"
00052
00053 #include "OSGTextureChunk.h"
00054
00055 #include "OSGTexGenChunk.h"
00056 #include "OSGCamera.h"
00057 #include "OSGViewport.h"
00058
00059 OSG_USING_NAMESPACE
00060
00061
00062
00063
00064
00081
00082
00083
00084
00085 StateChunkClass TexGenChunk::_class("TexGen", osgMaxTexCoords);
00086
00087
00088
00089
00090
00091 void TexGenChunk::initMethod (void)
00092 {
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 TexGenChunk::TexGenChunk(void) :
00104 Inherited()
00105 {
00106 }
00107
00108 TexGenChunk::TexGenChunk(const TexGenChunk &source) :
00109 Inherited(source)
00110 {
00111 }
00112
00113 TexGenChunk::~TexGenChunk(void)
00114 {
00115 }
00116
00117
00118
00119 const StateChunkClass *TexGenChunk::getClass(void) const
00120 {
00121 return &_class;
00122 }
00123
00124
00125
00126 void TexGenChunk::changed(BitVector whichField, UInt32 origin)
00127 {
00128 Inherited::changed(whichField, origin);
00129 }
00130
00131
00132
00133 void TexGenChunk::dump( UInt32 ,
00134 const BitVector ) const
00135 {
00136 SLOG << "Dump TexGenChunk NI" << std::endl;
00137 }
00138
00139
00140
00141
00142 static inline void setGenFunc(GLenum coord, GLenum gen, GLenum func,
00143 Vec4f &plane, NodePtr beacon, Matrix &cameraMat)
00144 {
00145 if(beacon != NullFC)
00146 {
00147 Matrix beaconMat;
00148 beacon->getToWorld(beaconMat);
00149 beaconMat.multLeft(cameraMat);
00150 glPushMatrix();
00151 glLoadMatrixf(beaconMat.getValues());
00152 glTexGenfv(coord, GL_EYE_PLANE, (GLfloat*)plane.getValues());
00153 glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00154 glPopMatrix();
00155 glEnable(gen);
00156 }
00157 else if(func == GL_EYE_LINEAR)
00158 {
00159 glPushMatrix();
00160 glLoadIdentity();
00161 glTexGenfv(coord, GL_EYE_PLANE, (GLfloat*)plane.getValues());
00162 glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00163 glPopMatrix();
00164 glEnable(gen);
00165 }
00166 else if(func != GL_NONE)
00167 {
00168 glTexGeni(coord, GL_TEXTURE_GEN_MODE, func);
00169
00170 if(func == GL_OBJECT_LINEAR)
00171 glTexGenfv(coord, GL_OBJECT_PLANE, (GLfloat*)plane.getValues());
00172 else if(func == GL_EYE_LINEAR)
00173 glTexGenfv(coord, GL_EYE_PLANE, (GLfloat*)plane.getValues());
00174
00175 glEnable(gen);
00176 }
00177 }
00178
00179 void TexGenChunk::activate(DrawActionBase *action, UInt32 idx )
00180 {
00181 glErr("TexGenChunk::activate precheck");
00182
00183 Window *win = action->getWindow();
00184
00185 Real32 ntexcoords;
00186 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
00187 Window::unknownConstant
00188 )
00189 {
00190 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
00191
00192 if(ntexcoords == Window::unknownConstant)
00193 ntexcoords = 1.0f;
00194 }
00195
00196 if(idx >= static_cast<UInt32>(ntexcoords))
00197 {
00198 #ifdef OSG_DEBUG
00199 FWARNING(("TexGenChunk::activate: Trying to bind texcoord unit %d,"
00200 " but Window %p only supports %d!\n",
00201 idx, win, ntexcoords));
00202 #endif
00203 return;
00204 }
00205
00206 TextureChunk::activateTexture(win, idx);
00207
00208 FDEBUG(("TexGenChunk::activate\n"));
00209
00210 Matrix cameraMat;
00211 Viewport *vp = action->getViewport();
00212 if(vp != NULL)
00213 {
00214 action->getCamera()->getViewing(cameraMat, vp->getPixelWidth(),
00215 vp->getPixelHeight());
00216 }
00217
00218
00219 setGenFunc(GL_S, GL_TEXTURE_GEN_S, getGenFuncS(), getGenFuncSPlane(),
00220 getSBeacon(), cameraMat);
00221 glErr("TexGenChunk::activateS");
00222 setGenFunc(GL_T, GL_TEXTURE_GEN_T, getGenFuncT(), getGenFuncTPlane(),
00223 getTBeacon(), cameraMat);
00224 glErr("TexGenChunk::activateT");
00225 setGenFunc(GL_R, GL_TEXTURE_GEN_R, getGenFuncR(), getGenFuncRPlane(),
00226 getRBeacon(), cameraMat);
00227 glErr("TexGenChunk::activateR");
00228 setGenFunc(GL_Q, GL_TEXTURE_GEN_Q, getGenFuncQ(), getGenFuncQPlane(),
00229 getQBeacon(), cameraMat);
00230 glErr("TexGenChunk::activateQ");
00231 }
00232
00233
00234 static inline void changeGenFunc(GLenum oldfunc, NodePtr oldbeacon,
00235 GLenum coord, GLenum gen,
00236 GLenum func, Vec4f &plane, NodePtr beacon, Matrix &cameraMat)
00237 {
00238 if(beacon != NullFC)
00239 {
00240 Matrix beaconMat;
00241 beacon->getToWorld(beaconMat);
00242 beaconMat.multLeft(cameraMat);
00243 glPushMatrix();
00244 glLoadMatrixf(beaconMat.getValues());
00245 glTexGenfv(coord, GL_EYE_PLANE, (GLfloat*)plane.getValues());
00246 glTexGeni(coord, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
00247 glPopMatrix();
00248 if(oldfunc == GL_NONE && oldbeacon == NullFC)
00249 glEnable(gen);
00250 }
00251 else if(func != GL_NONE)
00252 {
00253 glTexGeni(coord, GL_TEXTURE_GEN_MODE, func);
00254
00255 if(func == GL_OBJECT_LINEAR)
00256 glTexGenfv(coord, GL_OBJECT_PLANE, (GLfloat*)plane.getValues());
00257 else if(func == GL_EYE_LINEAR)
00258 glTexGenfv(coord, GL_EYE_PLANE, (GLfloat*)plane.getValues());
00259
00260 if(oldfunc == GL_NONE && oldbeacon == NullFC)
00261 glEnable(gen);
00262 }
00263 else if(oldfunc != GL_NONE || oldbeacon != NullFC)
00264 glDisable(gen);
00265 }
00266
00267 void TexGenChunk::changeFrom( DrawActionBase *action,
00268 StateChunk *old ,
00269 UInt32 idx)
00270 {
00271
00272
00273
00274
00275
00276
00277
00278
00279 TexGenChunk *oldp = dynamic_cast<TexGenChunk *>(old);
00280
00281
00282
00283 if(!oldp)
00284 {
00285 old->deactivate(action, idx);
00286 activate(action, idx);
00287 return;
00288 }
00289
00290 glErr("TexGenChunk::changeFrom precheck");
00291
00292 Window *win = action->getWindow();
00293
00294 Real32 ntexcoords;
00295 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
00296 Window::unknownConstant
00297 )
00298 {
00299 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
00300
00301 if(ntexcoords == Window::unknownConstant)
00302 ntexcoords = 1.0f;
00303 }
00304
00305 if(idx >= static_cast<UInt32>(ntexcoords))
00306 {
00307 #ifdef OSG_DEBUG
00308 FWARNING(("TexGenChunk::changeFrom: Trying to bind texcoord unit "
00309 "%d, but Window %p only supports %d!\n",
00310 idx, win, ntexcoords));
00311 #endif
00312 return;
00313 }
00314
00315 Matrix cameraMat;
00316 Viewport *vp = action->getViewport();
00317 if(vp != NULL)
00318 {
00319 action->getCamera()->getViewing(cameraMat, vp->getPixelWidth(),
00320 vp->getPixelHeight());
00321 }
00322
00323 TextureChunk::activateTexture(win, idx);
00324
00325 changeGenFunc(oldp->getGenFuncS(), oldp->getSBeacon(), GL_S,
00326 GL_TEXTURE_GEN_S,
00327 getGenFuncS(), getGenFuncSPlane(), getSBeacon(), cameraMat);
00328 changeGenFunc(oldp->getGenFuncT(), oldp->getTBeacon(), GL_T,
00329 GL_TEXTURE_GEN_T,
00330 getGenFuncT(), getGenFuncTPlane(), getTBeacon(), cameraMat);
00331 changeGenFunc(oldp->getGenFuncR(), oldp->getRBeacon(), GL_R,
00332 GL_TEXTURE_GEN_R,
00333 getGenFuncR(), getGenFuncRPlane(), getRBeacon(), cameraMat);
00334 changeGenFunc(oldp->getGenFuncQ(), oldp->getQBeacon(), GL_Q,
00335 GL_TEXTURE_GEN_Q,
00336 getGenFuncQ(), getGenFuncQPlane(), getQBeacon(), cameraMat);
00337
00338 glErr("TexGenChunk::changeFrom");
00339 }
00340
00341 void TexGenChunk::deactivate(DrawActionBase *action, UInt32 idx)
00342 {
00343 glErr("TexGenChunk::deactivate precheck");
00344
00345 Window *win = action->getWindow();
00346
00347 Real32 ntexcoords;
00348 if((ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_COORDS_ARB)) ==
00349 Window::unknownConstant
00350 )
00351 {
00352 ntexcoords = win->getConstantValue(GL_MAX_TEXTURE_UNITS_ARB);
00353
00354 if(ntexcoords == Window::unknownConstant)
00355 ntexcoords = 1.0f;
00356 }
00357
00358 if(idx >= static_cast<UInt32>(ntexcoords))
00359 {
00360 #ifdef OSG_DEBUG
00361 FWARNING(("TexGenChunk::deactivate: Trying to bind texcoord unit %d,"
00362 " but Window %p only supports %d!\n",
00363 idx, win, ntexcoords));
00364 #endif
00365 return;
00366 }
00367
00368 TextureChunk::activateTexture(win, idx);
00369
00370 if(getGenFuncS() != GL_NONE || getSBeacon() != NullFC)
00371 glDisable(GL_TEXTURE_GEN_S);
00372
00373 if(getGenFuncT() != GL_NONE || getTBeacon() != NullFC)
00374 glDisable(GL_TEXTURE_GEN_T);
00375
00376 if(getGenFuncR() != GL_NONE || getRBeacon() != NullFC)
00377 glDisable(GL_TEXTURE_GEN_R);
00378
00379 if(getGenFuncQ() != GL_NONE || getQBeacon() != NullFC)
00380 glDisable(GL_TEXTURE_GEN_Q);
00381
00382 glErr("TexGenChunk::deactivate");
00383 }
00384
00385
00386
00387 Real32 TexGenChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
00388 {
00389 return 0;
00390 }
00391
00392 bool TexGenChunk::operator < (const StateChunk &other) const
00393 {
00394 return this < &other;
00395 }
00396
00397 bool TexGenChunk::operator == (const StateChunk &other) const
00398 {
00399 TexGenChunk const *tother = dynamic_cast<TexGenChunk const*>(&other);
00400
00401 if(!tother)
00402 return false;
00403
00404 if(tother == this)
00405 return true;
00406
00407 return getGenFuncS() == tother->getGenFuncS() &&
00408 getGenFuncT() == tother->getGenFuncT() &&
00409 getGenFuncR() == tother->getGenFuncR() &&
00410 getGenFuncQ() == tother->getGenFuncQ() &&
00411
00412 getGenFuncSPlane() == tother->getGenFuncSPlane() &&
00413 getGenFuncTPlane() == tother->getGenFuncTPlane() &&
00414 getGenFuncRPlane() == tother->getGenFuncRPlane() &&
00415 getGenFuncQPlane() == tother->getGenFuncQPlane() ;
00416 }
00417
00418 bool TexGenChunk::operator != (const StateChunk &other) const
00419 {
00420 return ! (*this == other);
00421 }
00422
00423
00424 #ifdef __sgi
00425 #pragma set woff 1174
00426 #endif
00427
00428 #ifdef OSG_LINUX_ICC
00429 #pragma warning( disable : 177 )
00430 #endif
00431
00432 namespace
00433 {
00434 static Char8 cvsid_cpp[] = "@(#)$Id: $";
00435 static Char8 cvsid_hpp[] = OSGTEXGENCHUNK_HEADER_CVSID;
00436 static Char8 cvsid_inl[] = OSGTEXGENCHUNK_INLINE_CVSID;
00437
00438 static Char8 cvsid_fields_hpp[] = OSGTEXGENCHUNKFIELDS_HEADER_CVSID;
00439 }
00440
00441 #ifdef __sgi
00442 #pragma reset woff 1174
00443 #endif
00444