00001 #include "Message.h"
00002 #include "Util.h"
00003
00004 namespace apig {
00005
00006
00007 template<class Color> const QString CubeMap<Color>::axisNames[3] = { "x", "y", "z" };
00008 template<class Color> const QString CubeMap<Color>::signNames[2] = { "neg", "pos" };
00009 template<class Color> const GLenum CubeMap<Color>::targetNames[6] = {
00010 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
00011 GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z
00012 };
00013
00014 template<class Color>
00015 CubeMap<Color>::CubeMap(QString dirName) {
00016 initialize(dirName);
00017 }
00018
00019 template<class Color>
00020 void CubeMap<Color>::initialize(QString dirName) {
00021 int w, h;
00022 for (int i=0; i<3; i++) for (int j=0; j<2; j++) {
00023 QString fileName = util::filePath(dirName, imageFileName(i,j));
00024 QImage image;
00025 if (!image.load(fileName)) {
00026 destroy();
00027 Message::error(QString("impossible de charger l'image '%1'").arg(fileName));
00028 return;
00029 }
00030
00031 if (i==0 && j==0) {
00032 w = image.width();
00033 h = image.height();
00034 }
00035
00036 if (image.width() != w || image.height() != h) {
00037 Message::error("les 6 faces d'une cube-map doivent avoir le même résolution");
00038 destroy();
00039 return;
00040 }
00041
00042 face[i][j].initialize(image);
00043 if (!face[i][j].loaded()) { destroy(); return; }
00044 }
00045
00046 loaded = true;
00047 }
00048
00049 template<class Color>
00050 void CubeMap<Color>::destroy() {
00051 if (loaded)
00052 for (int i=0; i<3; i++) for (int j=0; j<2; j++)
00053 face[i][j].destroy();
00054 loaded = false;
00055 }
00056
00057
00058 template<class Color>
00059 void CubeMap<Color>::loadToGPU(GLint texFormat) const {
00060 if (!loaded) {
00061 Message::error("cube map pas encore chargee");
00062 return;
00063 }
00064 for (int i=0; i<3; i++) for (int j=0; j<2; j++)
00065 face[i][j].loadTexture2D(texFormat, targetName(i, j));
00066 }
00067
00068 template<class Color>
00069 GLenum CubeMap<Color>::targetName(int i, int j) {
00070 int c = i + 3*j;
00071 return targetNames[c];
00072 }
00073
00074 template<class Color>
00075 QString CubeMap<Color>::imageFileName(int i, int j) {
00076 return axisNames[i] + signNames[j];
00077 }
00078
00079 template<class Color>
00080 QStringList CubeMap<Color>::namesList(QString dirName, QString first) {
00081 QStringList list = util::subDirsList(dirName);
00082 const int i = list.indexOf(first);
00083 if (i != -1) list.push_front(list.takeAt(i));
00084 return list;
00085 }
00086
00087
00088
00089
00090 template<class Color>
00091 Color CubeMap<Color>::sample(Vec3 r) {
00092 const Vec3 a = abs(r);
00093 int i;
00094 if (a.x > a.y) {
00095 if (a.x > a.z)
00096 i = 0;
00097 else
00098 i = 2;
00099 }
00100 else {
00101 if (a.y > a.z)
00102 i = 1;
00103 else
00104 i = 2;
00105 }
00106 const bool pos = r[i] > 0;
00107 float s, t;
00108 switch(i) {
00109 case 0 :
00110 s = pos ? -r[2] : r[2];
00111 t = -r[1];
00112 break;
00113 case 1 :
00114 s = r[0];
00115 t = pos ? r[2] : -r[2];
00116 break;
00117 case 2 :
00118 default :
00119 s = pos ? r[0] : -r[0];
00120 t = -r[1];
00121 break;
00122 }
00123 const float
00124 x = (s / a[i] + 1.0f) / 2.0f,
00125 y = (t / a[i] + 1.0f) / 2.0f;
00126 const int j = pos ? 1 : 0;
00127 return face[i][j].interp(x,y);
00128 }
00129
00130 }
00131