// Include the standard OpenGL headers
#include "gl\gl.h"
#include "gl\glu.h"
#include "gl\glaux.h"
#include "math.h" // For sqrt
#include <stdexcept> // For runtime_error exception
// Static assert, derived from Andrei Alexandrescu's
// static_checker
// See Andrei's CUJ April'99 article on SAFEARRAYs
template <bool> struct static_checker;
template <> struct static_checker<true> {};
#define STATIC_ASSERT(expr) static_checker<expr>()
//********************************************************
// OpenGL reusable template classes GLpoint4 and GLvector3
// By G.Bavestrelli, Copyright Techint S.p.A. 1998-1999
// Any feedback is welcome:
// You can contact me at : giovanni.bavestrelli@pomini.it
//********************************************************
// Class GLpoint4: A homogeneous coordinate in 3D space
template <class Numeric>
class GLpoint4
{
public:
Numeric x;
Numeric y;
Numeric z;
Numeric w;
GLpoint4()
:x(0),y(0),z(0),w(1)
{}
GLpoint4(Numeric x,Numeric y,
Numeric z=0,Numeric w=1)
:x(x),y(y),z(z),w(w)
{}
GLpoint4(const Numeric * p)
:x(p[0]),y(p[1]),z(p[2]),w(p[3])
{}
operator const Numeric * () const
{
// If this line does not compile,
// it's because the Numeric members x and y
// are not aligned like C arrays
STATIC_ASSERT(offsetof(GLpoint4<Numeric>,y)
-offsetof(GLpoint4<Numeric>,x)
==sizeof(Numeric));
return &x;
}
GLpoint4 & operator = (const Numeric * c)
{
x=c[0]; y=c[1]; z=c[2]; w=c[3];
return *this;
}
BOOL Normalize()
{
if (w==0) return false;
if (w==1) return true;
x/=w; y/=w; z/=w; w=1;
return true;
}
};
template <class Numeric>
BOOL operator == (const GLpoint4<Numeric> & C1,
const GLpoint4<Numeric> & C2)
{
return C1.x==C2.x && C1.y==C2.y && C1.z==C2.z && C1.w==C2.w;
}
template <class Numeric>
BOOL operator != (const GLpoint4<Numeric> & C1,
const GLpoint4<Numeric> & C2)
{
return !(C1==C2);
}