From 2157e9320c60d561208dfdf6034e9a06781c9f30 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 13 Aug 2012 20:47:53 +0300 Subject: [PATCH] Lookup functions to determine the orientation of cube map faces The orientations are somewhat arbitary and not deducible with a simple algorithm. Writing the necessary conditional ladders everywhere would be annoying. --- source/texturecube.cpp | 92 ++++++++++++++++++++++++++++++++++-------- source/texturecube.h | 23 ++++++++++- 2 files changed, 98 insertions(+), 17 deletions(-) diff --git a/source/texturecube.cpp b/source/texturecube.cpp index 4a613a37..ddb0c1e0 100644 --- a/source/texturecube.cpp +++ b/source/texturecube.cpp @@ -5,25 +5,19 @@ 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), @@ -49,7 +43,7 @@ void TextureCube::allocate(unsigned level) 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) @@ -78,5 +72,71 @@ unsigned TextureCube::get_level_size(unsigned level) 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 diff --git a/source/texturecube.h b/source/texturecube.h index b15c1cff..0d23884f 100644 --- a/source/texturecube.h +++ b/source/texturecube.h @@ -4,6 +4,7 @@ #include "datatype.h" #include "pixelformat.h" #include "texture.h" +#include "vector.h" namespace Msp { namespace GL { @@ -23,7 +24,8 @@ Cube map texture, consisting of six square faces. All of the faces must be of 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. @@ -36,6 +38,8 @@ private: unsigned size; unsigned allocated; + static Vector3 directions[6]; + public: TextureCube(); @@ -63,6 +67,23 @@ public: 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 -- 2.45.2