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
00044
00045
00046 #ifndef GLH_CUBE_MAP_H
00047 #define GLH_CUBE_MAP_H
00048
00049 #ifdef MACOS
00050 #include <OpenGL/gl.h>
00051 #else
00052 #include <GL/gl.h>
00053 #endif
00054
00055 #include <glh/glh_obs.h>
00056 #include <glh/glh_convenience.h>
00057 #include <glh/glh_linear.h>
00058
00059 namespace glh
00060 {
00061
00062 # ifdef GL_ARB_texture_cube_map
00063 # define GLH_CUBE_MAP_POSITIVE_X GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
00064 # define GLH_CUBE_MAP_POSITIVE_Y GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
00065 # define GLH_CUBE_MAP_POSITIVE_Z GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
00066 # define GLH_CUBE_MAP_NEGATIVE_X GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
00067 # define GLH_CUBE_MAP_NEGATIVE_Y GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
00068 # define GLH_CUBE_MAP_NEGATIVE_Z GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
00069 # elif GL_EXT_texture_cube_map
00070 # define GLH_CUBE_MAP_POSITIVE_X GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT
00071 # define GLH_CUBE_MAP_POSITIVE_Y GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT
00072 # define GLH_CUBE_MAP_POSITIVE_Z GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT
00073 # define GLH_CUBE_MAP_NEGATIVE_X GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT
00074 # define GLH_CUBE_MAP_NEGATIVE_Y GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT
00075 # define GLH_CUBE_MAP_NEGATIVE_Z GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT
00076 # endif
00077
00078 # if GL_EXT_texture_cube_map || GL_ARB_texture_cube_map
00079
00080 template <class FunctionOfDirection>
00081 void make_cube_map(FunctionOfDirection & f, GLenum internal_format,
00082 int size, int level = 0)
00083 {
00084 typedef typename FunctionOfDirection::Type Type;
00085 int components = f.components;
00086 GLenum type = f.type;
00087 GLenum format = f.format;
00088 Type * image = new Type[size*size*components];
00089 Type * ip;
00090
00091 float offset = .5;
00092 float delta = 1;
00093 float halfsize = size/2.f;
00094 vec3f v;
00095
00096
00097 {
00098 ip = image;
00099 for(int j = 0; j < size; j++)
00100 {
00101 for(int i=0; i < size; i++)
00102 {
00103 v[2] = -(i*delta + offset - halfsize);
00104 v[1] = -(j*delta + offset - halfsize);
00105 v[0] = halfsize;
00106 v.normalize();
00107 f(v, ip);
00108 ip += components;
00109 }
00110 }
00111 glTexImage2D(GLH_CUBE_MAP_POSITIVE_X,
00112 level, internal_format, size, size, 0, format, type, image);
00113 }
00114
00115 {
00116 ip = image;
00117 for(int j = 0; j < size; j++)
00118 {
00119 for(int i=0; i < size; i++)
00120 {
00121 v[2] = (i*delta + offset - halfsize);
00122 v[1] = -(j*delta + offset - halfsize);
00123 v[0] = -halfsize;
00124 v.normalize();
00125 f(v, ip);
00126 ip += components;
00127 }
00128 }
00129 glTexImage2D(GLH_CUBE_MAP_NEGATIVE_X,
00130 level, internal_format, size, size, 0, format, type, image);
00131 }
00132
00133
00134 {
00135 ip = image;
00136 for(int j = 0; j < size; j++)
00137 {
00138 for(int i=0; i < size; i++)
00139 {
00140 v[0] = (i*delta + offset - halfsize);
00141 v[2] = (j*delta + offset - halfsize);
00142 v[1] = halfsize;
00143 v.normalize();
00144 f(v, ip);
00145 ip += components;
00146 }
00147 }
00148 glTexImage2D(GLH_CUBE_MAP_POSITIVE_Y,
00149 level, internal_format, size, size, 0, format, type, image);
00150 }
00151
00152 {
00153 ip = image;
00154 for(int j = 0; j < size; j++)
00155 {
00156 for(int i=0; i < size; i++)
00157 {
00158 v[0] = (i*delta + offset - halfsize);
00159 v[2] = -(j*delta + offset - halfsize);
00160 v[1] = -halfsize;
00161 v.normalize();
00162 f(v, ip);
00163 ip += components;
00164 }
00165 }
00166 glTexImage2D(GLH_CUBE_MAP_NEGATIVE_Y,
00167 level, internal_format, size, size, 0, format, type, image);
00168 }
00169
00170
00171 {
00172 ip = image;
00173 for(int j = 0; j < size; j++)
00174 {
00175 for(int i=0; i < size; i++)
00176 {
00177 v[0] = (i*delta + offset - halfsize);
00178 v[1] = -(j*delta + offset - halfsize);
00179 v[2] = halfsize;
00180 v.normalize();
00181 f(v, ip);
00182 ip += components;
00183 }
00184 }
00185 glTexImage2D(GLH_CUBE_MAP_POSITIVE_Z,
00186 level, internal_format, size, size, 0, format, type, image);
00187 }
00188
00189 {
00190 ip = image;
00191 for(int j = 0; j < size; j++)
00192 {
00193 for(int i=0; i < size; i++)
00194 {
00195 v[0] = -(i*delta + offset - halfsize);
00196 v[1] = -(j*delta + offset - halfsize);
00197 v[2] = -halfsize;
00198 v.normalize();
00199 f(v, ip);
00200 ip += components;
00201 }
00202 }
00203 glTexImage2D(GLH_CUBE_MAP_NEGATIVE_Z,
00204 level, internal_format, size, size, 0, format, type, image);
00205 }
00206 delete [] image;
00207 }
00208 # endif
00209
00210 struct normalize_vector
00211 {
00212 typedef GLfloat Type;
00213 int components;
00214 GLenum type;
00215 GLenum format;
00216 normalize_vector() : components(3), type(GL_FLOAT), format(GL_RGB) {}
00217
00218 void operator() (const vec3f & v, Type * t)
00219 {
00220 vec3f v2 = v;
00221 v2 *= .5;
00222 v2 += .5;
00223 t[0] = v2[0];
00224 t[1] = v2[1];
00225 t[2] = v2[2];
00226 }
00227 };
00228
00229 struct cube_map_unextended
00230 {
00231 cube_map_unextended() :
00232 POSITIVE_X(0), NEGATIVE_X(1),
00233 POSITIVE_Y(2), NEGATIVE_Y(3),
00234 POSITIVE_Z(4), NEGATIVE_Z(5),
00235 lightnum(GL_LIGHT0), angle(90.0)
00236 {}
00237
00238
00239 void set_angle(GLint width)
00240 { angle = to_degrees((float)atan2(width/2.0f, width/2.0f-1.0f)) * 2.0f; }
00241
00242
00243 void cull_for_projection(int i)
00244 {
00245 GLfloat plane[6][4] =
00246 {
00247 { 1, 0, 0, 0 },
00248 {-1, 0, 0, 0 },
00249 { 0, 1, 0, 0 },
00250 { 0,-1, 0, 0 },
00251 { 0, 0, 1, 0 },
00252 { 0, 0,-1, 0 }
00253 };
00254
00255 glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 90);
00256 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, plane[i]);
00257 }
00258
00259 void cull_for_reflection(int i)
00260 {
00261 GLfloat dir[6][4] =
00262 {
00263 { 1, 0, 0, 0 },
00264 {-1, 0, 0, 0 },
00265 { 0, 1, 0, 0 },
00266 { 0,-1, 0, 0 },
00267 { 0, 0, 1, 0 },
00268 { 0, 0,-1, 0 }
00269 };
00270 glLightfv(GL_LIGHT0, GL_POSITION, dir[i]);
00271 }
00272
00273 matrix4f get_matrix(int cubeface)
00274 {
00275 matrix4f m;
00276 m = perspective((float)angle, 1.0f, 0.5f, 1.5f);
00277 switch(cubeface)
00278 {
00279 case 0:
00280 m *= camera_lookat(vec3f(0,0,0), vec3f( 1, 0, 0), vec3f(0,-1, 0));
00281 return m;
00282 case 1:
00283 m *= camera_lookat(vec3f(0,0,0), vec3f(-1, 0, 0), vec3f(0,-1, 0));
00284 return m;
00285 case 2:
00286 m *= camera_lookat(vec3f(0,0,0), vec3f( 0, 1, 0), vec3f(0, 0, 1));
00287 return m;
00288 case 3:
00289 m *= camera_lookat(vec3f(0,0,0), vec3f( 0,-1, 0), vec3f(0, 0,-1));
00290 return m;
00291 case 4:
00292 m *= camera_lookat(vec3f(0,0,0), vec3f( 0, 0, 1), vec3f(0,-1, 0));
00293 return m;
00294 case 5:
00295 m *= camera_lookat(vec3f(0,0,0), vec3f( 0, 0,-1), vec3f(0,-1, 0));
00296 return m;
00297 default:
00298 return matrix4f();
00299 }
00300 }
00301
00302 matrix4f get_matrix_inverse(int cubeface)
00303 {
00304 matrix4f m;
00305 switch(cubeface)
00306 {
00307 case 0:
00308 m = object_lookat(vec3f(0,0,0), vec3f( 1, 0, 0), vec3f(0,-1, 0));
00309 break;
00310 case 1:
00311 m = object_lookat(vec3f(0,0,0), vec3f(-1, 0, 0), vec3f(0,-1, 0));
00312 break;
00313 case 2:
00314 m = object_lookat(vec3f(0,0,0), vec3f( 0, 1, 0), vec3f(0, 0, 1));
00315 break;
00316 case 3:
00317 m = object_lookat(vec3f(0,0,0), vec3f( 0,-1, 0), vec3f(0, 0,-1));
00318 break;
00319 case 4:
00320 m = object_lookat(vec3f(0,0,0), vec3f( 0, 0, 1), vec3f(0,-1, 0));
00321 break;
00322 case 5:
00323 m = object_lookat(vec3f(0,0,0), vec3f( 0, 0,-1), vec3f(0,-1, 0));
00324 break;
00325 default:
00326 break;
00327 }
00328 return m * perspective_inverse((float)angle, 1.0f, 0.5f, 1.5f);
00329 }
00330 const int POSITIVE_X;
00331 const int NEGATIVE_X;
00332 const int POSITIVE_Y;
00333 const int NEGATIVE_Y;
00334 const int POSITIVE_Z;
00335 const int NEGATIVE_Z;
00336
00337 GLenum lightnum;
00338 tex_object_2D face[6];
00339 double angle;
00340
00341 matrix4f rotation;
00342
00343 };
00344
00345 }
00346 #endif
00347