1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version.  The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * OpenSceneGraph Public License for more details.
12 */
13 #include <osg/TexGen>
14 #include <osg/Notify>
15 #include <osg/io_utils>
16 
17 using namespace osg;
18 
TexGen()19 TexGen::TexGen()
20 {
21     _mode = OBJECT_LINEAR;
22     _plane_s.set(1.0f, 0.0f, 0.0f, 0.0f);
23     _plane_t.set(0.0f, 1.0f, 0.0f, 0.0f);
24     _plane_r.set(0.0f, 0.0f, 1.0f, 0.0f);
25     _plane_q.set(0.0f, 0.0f, 0.0f, 1.0f);
26 }
27 
28 
~TexGen()29 TexGen::~TexGen()
30 {
31 }
32 
33 
setPlane(Coord which,const Plane & plane)34 void TexGen::setPlane(Coord which, const Plane& plane)
35 {
36     switch( which )
37     {
38         case S : _plane_s = plane; break;
39         case T : _plane_t = plane; break;
40         case R : _plane_r = plane; break;
41         case Q : _plane_q = plane; break;
42         default : OSG_WARN<<"Error: invalid 'which' passed TexGen::setPlane("<<(unsigned int)which<<","<<plane<<")"<<std::endl; break;
43     }
44 }
45 
getPlane(Coord which) const46 const Plane& TexGen::getPlane(Coord which) const
47 {
48     switch( which )
49     {
50         case S : return _plane_s;
51         case T : return _plane_t;
52         case R : return _plane_r;
53         case Q : return _plane_q;
54         default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r;
55     }
56 }
57 
getPlane(Coord which)58 Plane& TexGen::getPlane(Coord which)
59 {
60     switch( which )
61     {
62         case S : return _plane_s;
63         case T : return _plane_t;
64         case R : return _plane_r;
65         case Q : return _plane_q;
66         default : OSG_WARN<<"Error: invalid 'which' passed TexGen::getPlane(which)"<<std::endl; return _plane_r;
67     }
68 }
69 
setPlanesFromMatrix(const Matrixd & matrix)70 void TexGen::setPlanesFromMatrix(const Matrixd& matrix)
71 {
72     _plane_s.set(matrix(0,0),matrix(1,0),matrix(2,0),matrix(3,0));
73     _plane_t.set(matrix(0,1),matrix(1,1),matrix(2,1),matrix(3,1));
74     _plane_r.set(matrix(0,2),matrix(1,2),matrix(2,2),matrix(3,2));
75     _plane_q.set(matrix(0,3),matrix(1,3),matrix(2,3),matrix(3,3));
76 }
77 
apply(State &) const78 void TexGen::apply(State&) const
79 {
80 #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE)
81     if (_mode == OBJECT_LINEAR || _mode == EYE_LINEAR)
82     {
83         GLenum glmode = _mode == OBJECT_LINEAR ? GL_OBJECT_PLANE : GL_EYE_PLANE;
84 
85         if (sizeof(_plane_s[0])==sizeof(GLfloat))
86         {
87             glTexGenfv(GL_S, glmode, (const GLfloat*)_plane_s.ptr());
88             glTexGenfv(GL_T, glmode, (const GLfloat*)_plane_t.ptr());
89             glTexGenfv(GL_R, glmode, (const GLfloat*)_plane_r.ptr());
90             glTexGenfv(GL_Q, glmode, (const GLfloat*)_plane_q.ptr());
91         }
92         else
93         {
94             glTexGendv(GL_S, glmode, (const GLdouble*)_plane_s.ptr());
95             glTexGendv(GL_T, glmode, (const GLdouble*)_plane_t.ptr());
96             glTexGendv(GL_R, glmode, (const GLdouble*)_plane_r.ptr());
97             glTexGendv(GL_Q, glmode, (const GLdouble*)_plane_q.ptr());
98         }
99 
100         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
101         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
102         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
103         glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
104 
105     }
106     else if (_mode == NORMAL_MAP)
107     {
108         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
109         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
110         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
111 //      glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
112     }
113     else if (_mode == REFLECTION_MAP)
114     {
115         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
116         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
117         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
118 //      glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
119     }
120     else                         // SPHERE_MAP
121     {
122         // Also don't set the mode of GL_R & GL_Q as these will generate
123         // GL_INVALID_ENUM (See OpenGL Reference Guide, glTexGEn.)
124 
125         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
126         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
127     }
128 #else
129     OSG_NOTICE<<"Warning: TexGen::apply(State&) - not supported."<<std::endl;
130 #endif
131 }
132