У меня есть шаблон и два векторных класса ниже, один сумасшедший, один вменяемый. Шаблон реализует простой фиксированный во время компиляции массив значений. Он предназначен для создания подклассов и использует переменную защищенного массива, чтобы вам не приходилось прыгать через обручи для доступа к массиву. (Некоторым людям может не понравиться такой дизайн. Я говорю, если ваши подклассы вызывают ваши перегруженные операторы, связывание может быть хорошей идеей.)
Сумасшедший класс позволяет вам иметь переменные-члены с именами x, y, z, и он действует как массив для вызовов glGetFloatV. У здравомыслящего только есть функции доступа x (), y (), z () и все еще работает с glGetFloatV. Вы можете использовать любой класс в качестве основы для других векторных объектов, которые вы можете передать в библиотеку OpenGL. Хотя приведенные ниже классы относятся только к точкам, очевидно, вы можете просто выполнить поиск / замену, чтобы превратить их в цветовые классы rgb.
Сумасшедший класс сумасшедший, потому что стоимость синтаксического сахара vec.x вместо vec.x () равна 3 ссылочным переменным. Это может занять много места в большом приложении. Используйте более простую и разумную версию.
template <typename T, int N>
class FixedVector {
protected:
T arr[N];
public:
FixedVector();
FixedVector(const T* a) {
for (int i = 0; i < N; ++i) {
arr[i] = a[i];
}
}
FixedVector(const T& other) {
for (int i = 0; i < N; ++i) {
arr[i] = other.arr[i];
}
}
FixedVector& operator=(const T& other) {
for (int i = 0; i < N; ++i) {
arr[i] = other.arr[i];
}
return *this;
}
T* operator&() { return arr; }
const T* operator&() const { return arr; }
T& operator[](int ofs) {
assert(ofs >= 0 && ofs < N);
return arr[ofs];
}
const T& operator[](int ofs) const {
assert(ofs >= 0 && ofs < N);
return arr[ofs];
}
};
class CrazyPoint : public FixedVector<float, 3> {
public:
float &x, &y, &z;
CrazyPoint()
: x(arr[0]), y(arr[1]), z(arr[2])
{ arr[0] = arr[1] = arr[2] = 0.0; }
CrazyPoint(const float* a)
: x(arr[0]), y(arr[1]), z(arr[2])
{
arr[0] = a[0];
arr[1] = a[1];
arr[2] = a[2];
}
CrazyPoint(float a, float b, float c)
: x(a), y(b), z(c)
{
arr[0] = a;
arr[1] = b;
arr[2] = c;
}
};
class SanePoint : public FixedVector<float, 3> {
public:
float& x() { return arr[0]; }
float& y() { return arr[1]; }
float& z() { return arr[2]; }
SanePoint() { arr[0] = arr[1] = arr[2] = 0.0; }
SanePoint(float a, float b, float c)
{
arr[0] = a;
arr[1] = b;
arr[2] = c;
}
};
// usage
SanePoint normal;
glGetFloatV(GL_CURRENT_NORMAL, &normal);