using namespace std;
-namespace {
+namespace Msp {
+namespace GL {
-// An array to facilitate looping through the cube faces
-Msp::GL::TextureCubeFace faces[6] =
+Vector3 TextureCube::directions[6] =
{
- Msp::GL::POSITIVE_X,
- Msp::GL::NEGATIVE_X,
- Msp::GL::POSITIVE_Y,
- Msp::GL::NEGATIVE_Y,
- Msp::GL::POSITIVE_Z,
- Msp::GL::NEGATIVE_Z
+ Vector3(1, 0, 0),
+ Vector3(-1, 0, 0),
+ Vector3(0, 1, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, 1),
+ Vector3(0, 0, -1)
};
-}
-
-
-namespace Msp {
-namespace GL {
-
TextureCube::TextureCube():
Texture(GL_TEXTURE_CUBE_MAP),
size(0),
return;
for(unsigned i=0; i<6; ++i)
- image(faces[i], level, get_base_pixelformat(ifmt), UNSIGNED_BYTE, 0);
+ image(enumerate_faces(i), level, get_base_pixelformat(ifmt), UNSIGNED_BYTE, 0);
}
void TextureCube::image(TextureCubeFace face, unsigned level, PixelFormat fmt, DataType type, const void *data)
return size>>level;
}
+TextureCubeFace TextureCube::enumerate_faces(unsigned i)
+{
+ switch(i)
+ {
+ case 0: return POSITIVE_X;
+ case 1: return NEGATIVE_X;
+ case 2: return POSITIVE_Y;
+ case 3: return NEGATIVE_Y;
+ case 4: return POSITIVE_Z;
+ case 5: return NEGATIVE_Z;
+ default: throw out_of_range("TextureCube::enumerate_faces");
+ }
+}
+
+const Vector3 &TextureCube::get_face_direction(TextureCubeFace face)
+{
+ switch(face)
+ {
+ case POSITIVE_X: return directions[0];
+ case NEGATIVE_X: return directions[1];
+ case POSITIVE_Y: return directions[2];
+ case NEGATIVE_Y: return directions[3];
+ case POSITIVE_Z: return directions[4];
+ case NEGATIVE_Z: return directions[5];
+ default: throw invalid_argument("TextureCube::get_face_direction");
+ }
+}
+
+const Vector3 &TextureCube::get_s_direction(TextureCubeFace face)
+{
+ switch(face)
+ {
+ case POSITIVE_X: return directions[5];
+ case NEGATIVE_X: return directions[4];
+ case POSITIVE_Y: return directions[0];
+ case NEGATIVE_Y: return directions[0];
+ case POSITIVE_Z: return directions[0];
+ case NEGATIVE_Z: return directions[1];
+ default: throw invalid_argument("TextureCube::get_s_direction");
+ }
+}
+
+const Vector3 &TextureCube::get_t_direction(TextureCubeFace face)
+{
+ switch(face)
+ {
+ case POSITIVE_X: return directions[3];
+ case NEGATIVE_X: return directions[3];
+ case POSITIVE_Y: return directions[4];
+ case NEGATIVE_Y: return directions[5];
+ case POSITIVE_Z: return directions[3];
+ case NEGATIVE_Z: return directions[3];
+ default: throw invalid_argument("TextureCube::get_t_direction");
+ }
+}
+
+Vector3 TextureCube::get_texel_direction(TextureCubeFace face, unsigned u, unsigned v)
+{
+ float s = (u+0.5f)*2.0f/size-1.0f;
+ float t = (v+0.5f)*2.0f/size-1.0f;
+ const Vector3 &fv = get_face_direction(face);
+ const Vector3 &sv = get_s_direction(face);
+ const Vector3 &tv = get_t_direction(face);
+ return Vector3(fv.x+s*sv.x, fv.y+t*tv.y, fv.z+s*sv.z+t*tv.z);
+}
+
} // namespace GL
} // namespace Msp
#include "datatype.h"
#include "pixelformat.h"
#include "texture.h"
+#include "vector.h"
namespace Msp {
namespace GL {
the same size. A cube map texture is addressed by three-dimensional texture
coordinates, with a principal range of [-1, 1]. The face is first selected
according to the largest coordinate, and the remaining two coordinates are used
-to sample the face image.
+to sample the face image. The images are oriented so that the cross product of
+the s and t axes will point into the cube.
All faces of a cube map texture must be allocated for it to be usable.
unsigned size;
unsigned allocated;
+ static Vector3 directions[6];
+
public:
TextureCube();
unsigned get_size() const { return size; }
private:
unsigned get_level_size(unsigned);
+
+public:
+ /** Translates indices into face constants. Valid indices are between 0
+ and 5, inclusive. */
+ static TextureCubeFace enumerate_faces(unsigned);
+
+ /** Returns a vector pointing out of the face. */
+ static const Vector3 &get_face_direction(TextureCubeFace);
+
+ /** Returns a vector in the direction of the s axis of the face. */
+ static const Vector3 &get_s_direction(TextureCubeFace);
+
+ /** Returns a vector in the direction of the t axis of the face. */
+ static const Vector3 &get_t_direction(TextureCubeFace);
+
+ /** Returns a vector pointing to the center a texel. */
+ Vector3 get_texel_direction(TextureCubeFace, unsigned, unsigned);
};
} // namespace GL