Home | History | Annotate | Download | only in Eigen
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud (a] inria.fr>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #ifndef EIGEN_OPENGL_MODULE
     11 #define EIGEN_OPENGL_MODULE
     12 
     13 #include <Eigen/Geometry>
     14 #include <GL/gl.h>
     15 
     16 namespace Eigen {
     17 
     18 /** \ingroup Unsupported_modules
     19   * \defgroup OpenGLSUpport_Module OpenGL Support module
     20   *
     21   * This module provides wrapper functions for a couple of OpenGL functions
     22   * which simplify the way to pass Eigen's object to openGL.
     23   * Here is an exmaple:
     24   * 
     25   * \code
     26   * // You need to add path_to_eigen/unsupported to your include path.
     27   * #include <Eigen/OpenGLSupport>
     28   * // ...
     29   * Vector3f x, y;
     30   * Matrix3f rot;
     31   * 
     32   * glVertex(y + x * rot);
     33   * 
     34   * Quaternion q;
     35   * glRotate(q);
     36   * 
     37   * // ...
     38   * \endcode
     39   *
     40   */
     41 //@{
     42 
     43 #define EIGEN_GL_FUNC_DECLARATION(FUNC)                                                                             \
     44 namespace internal {                                                                                                \
     45   template< typename XprType,                                                                                       \
     46             typename Scalar = typename XprType::Scalar,                                                             \
     47             int Rows = XprType::RowsAtCompileTime,                                                                  \
     48             int Cols = XprType::ColsAtCompileTime,                                                                  \
     49             bool IsGLCompatible = bool(XprType::Flags&LinearAccessBit)                                              \
     50                               && bool(XprType::Flags&DirectAccessBit)                                               \
     51                               && (XprType::IsVectorAtCompileTime || (XprType::Flags&RowMajorBit)==0)>               \
     52   struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl);                                                                      \
     53                                                                                                                     \
     54   template<typename XprType, typename Scalar, int Rows, int Cols>                                                   \
     55   struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType,Scalar,Rows,Cols,false> {                                     \
     56     inline static void run(const XprType& p) {                                                                      \
     57       EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<typename plain_matrix_type_column_major<XprType>::type>::run(p); }       \
     58   };                                                                                                                \
     59 }                                                                                                                   \
     60                                                                                                                     \
     61 template<typename Derived> inline void FUNC(const Eigen::DenseBase<Derived>& p) {                                   \
     62   EIGEN_CAT(EIGEN_CAT(internal::gl_,FUNC),_impl)<Derived>::run(p.derived());                                        \
     63 }
     64 
     65 
     66 #define EIGEN_GL_FUNC_SPECIALIZATION_MAT(FUNC,SCALAR,ROWS,COLS,SUFFIX)                                              \
     67 namespace internal {                                                                                                \
     68   template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, ROWS, COLS, true> {      \
     69     inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); }                                            \
     70   };                                                                                                                \
     71 }
     72 
     73   
     74 #define EIGEN_GL_FUNC_SPECIALIZATION_VEC(FUNC,SCALAR,SIZE,SUFFIX)                                                   \
     75 namespace internal {                                                                                                \
     76   template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, SIZE, 1, true> {         \
     77     inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); }                                            \
     78   };                                                                                                                \
     79   template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, 1, SIZE, true> {         \
     80     inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); }                                            \
     81   };                                                                                                                \
     82 }
     83 
     84   
     85 EIGEN_GL_FUNC_DECLARATION       (glVertex)
     86 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int,    2,2iv)
     87 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short,  2,2sv)
     88 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float,  2,2fv)
     89 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 2,2dv)
     90 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int,    3,3iv)
     91 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short,  3,3sv)
     92 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float,  3,3fv)
     93 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 3,3dv)
     94 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int,    4,4iv)
     95 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short,  4,4sv)
     96 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float,  4,4fv)
     97 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 4,4dv)
     98 
     99 EIGEN_GL_FUNC_DECLARATION       (glTexCoord)
    100 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int,    2,2iv)
    101 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short,  2,2sv)
    102 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float,  2,2fv)
    103 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 2,2dv)
    104 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int,    3,3iv)
    105 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short,  3,3sv)
    106 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float,  3,3fv)
    107 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 3,3dv)
    108 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int,    4,4iv)
    109 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short,  4,4sv)
    110 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float,  4,4fv)
    111 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 4,4dv)
    112 
    113 EIGEN_GL_FUNC_DECLARATION       (glColor)
    114 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int,    2,2iv)
    115 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short,  2,2sv)
    116 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float,  2,2fv)
    117 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 2,2dv)
    118 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int,    3,3iv)
    119 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short,  3,3sv)
    120 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float,  3,3fv)
    121 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 3,3dv)
    122 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int,    4,4iv)
    123 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short,  4,4sv)
    124 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float,  4,4fv)
    125 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 4,4dv)
    126 
    127 EIGEN_GL_FUNC_DECLARATION       (glNormal)
    128 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,int,    3,3iv)
    129 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,short,  3,3sv)
    130 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,float,  3,3fv)
    131 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,double, 3,3dv)
    132 
    133 inline void glScale2fv(const float*  v) { glScalef(v[0], v[1], 1.f);  }
    134 inline void glScale2dv(const double* v) { glScaled(v[0], v[1], 1.0);  }
    135 inline void glScale3fv(const float*  v) { glScalef(v[0], v[1], v[2]); }
    136 inline void glScale3dv(const double* v) { glScaled(v[0], v[1], v[2]); }
    137 
    138 EIGEN_GL_FUNC_DECLARATION       (glScale)
    139 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float,  2,2fv)
    140 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 2,2dv)
    141 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float,  3,3fv)
    142 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 3,3dv)
    143 
    144 template<typename Scalar> void glScale(const UniformScaling<Scalar>& s)  { glScale(Matrix<Scalar,3,1>::Constant(s.factor())); }
    145 
    146 inline void glTranslate2fv(const float*  v) { glTranslatef(v[0], v[1], 0.f);  }
    147 inline void glTranslate2dv(const double* v) { glTranslated(v[0], v[1], 0.0);  }
    148 inline void glTranslate3fv(const float*  v) { glTranslatef(v[0], v[1], v[2]); }
    149 inline void glTranslate3dv(const double* v) { glTranslated(v[0], v[1], v[2]); }
    150 
    151 EIGEN_GL_FUNC_DECLARATION       (glTranslate)
    152 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float,  2,2fv)
    153 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 2,2dv)
    154 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float,  3,3fv)
    155 EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 3,3dv)
    156 
    157 template<typename Scalar> void glTranslate(const Translation<Scalar,2>& t)  { glTranslate(t.vector()); }
    158 template<typename Scalar> void glTranslate(const Translation<Scalar,3>& t)  { glTranslate(t.vector()); }
    159 
    160 EIGEN_GL_FUNC_DECLARATION       (glMultMatrix)
    161 EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,float,  4,4,f)
    162 EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,double, 4,4,d)
    163 
    164 template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,Affine>& t)        { glMultMatrix(t.matrix()); }
    165 template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,Projective>& t)    { glMultMatrix(t.matrix()); }
    166 template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,AffineCompact>& t) { glMultMatrix(Transform<Scalar,3,Affine>(t).matrix()); }
    167 
    168 EIGEN_GL_FUNC_DECLARATION       (glLoadMatrix)
    169 EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,float,  4,4,f)
    170 EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,double, 4,4,d)
    171 
    172 template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,Affine>& t)        { glLoadMatrix(t.matrix()); }
    173 template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,Projective>& t)    { glLoadMatrix(t.matrix()); }
    174 template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,AffineCompact>& t) { glLoadMatrix(Transform<Scalar,3,Affine>(t).matrix()); }
    175 
    176 static void glRotate(const Rotation2D<float>& rot)
    177 {
    178   glRotatef(rot.angle()*180.f/float(M_PI), 0.f, 0.f, 1.f);
    179 }
    180 static void glRotate(const Rotation2D<double>& rot)
    181 {
    182   glRotated(rot.angle()*180.0/M_PI, 0.0, 0.0, 1.0);
    183 }
    184 
    185 template<typename Derived> void glRotate(const RotationBase<Derived,3>& rot)
    186 {  
    187   Transform<typename Derived::Scalar,3,Projective> tr(rot);
    188   glMultMatrix(tr.matrix());
    189 }
    190 
    191 #define EIGEN_GL_MAKE_CONST_const const
    192 #define EIGEN_GL_MAKE_CONST__ 
    193 #define EIGEN_GL_EVAL(X) X
    194 
    195 #define EIGEN_GL_FUNC1_DECLARATION(FUNC,ARG1,CONST)                                                                             \
    196 namespace internal {                                                                                                            \
    197   template< typename XprType,                                                                                                   \
    198             typename Scalar = typename XprType::Scalar,                                                                         \
    199             int Rows = XprType::RowsAtCompileTime,                                                                              \
    200             int Cols = XprType::ColsAtCompileTime,                                                                              \
    201             bool IsGLCompatible = bool(XprType::Flags&LinearAccessBit)                                                          \
    202                               && bool(XprType::Flags&DirectAccessBit)                                                           \
    203                               && (XprType::IsVectorAtCompileTime || (XprType::Flags&RowMajorBit)==0)>                           \
    204   struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl);                                                                                  \
    205                                                                                                                                 \
    206   template<typename XprType, typename Scalar, int Rows, int Cols>                                                               \
    207   struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType,Scalar,Rows,Cols,false> {                                                 \
    208     inline static void run(ARG1 a,EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) {                                      \
    209       EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<typename plain_matrix_type_column_major<XprType>::type>::run(a,p); }                 \
    210   };                                                                                                                            \
    211 }                                                                                                                               \
    212                                                                                                                                 \
    213 template<typename Derived> inline void FUNC(ARG1 a,EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) Eigen::DenseBase<Derived>& p) {   \
    214   EIGEN_CAT(EIGEN_CAT(internal::gl_,FUNC),_impl)<Derived>::run(a,p.derived());                                                  \
    215 }
    216 
    217 
    218 #define EIGEN_GL_FUNC1_SPECIALIZATION_MAT(FUNC,ARG1,CONST,SCALAR,ROWS,COLS,SUFFIX)                                              \
    219 namespace internal {                                                                                                            \
    220   template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, ROWS, COLS, true> {                  \
    221     inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); }         \
    222   }; \
    223 }
    224 
    225   
    226 #define EIGEN_GL_FUNC1_SPECIALIZATION_VEC(FUNC,ARG1,CONST,SCALAR,SIZE,SUFFIX)                                                   \
    227 namespace internal {                                                                                                            \
    228   template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, SIZE, 1, true> {                     \
    229     inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); }         \
    230   };                                                                                                                            \
    231   template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, 1, SIZE, true> {                     \
    232     inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); }         \
    233   };                                                                                                                            \
    234 }
    235 
    236 EIGEN_GL_FUNC1_DECLARATION       (glGet,GLenum,_)
    237 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,float,  4,4,Floatv)
    238 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,double, 4,4,Doublev)
    239 
    240 // glUniform API
    241 
    242 #ifdef GL_VERSION_2_0
    243 
    244 static void glUniform2fv_ei  (GLint loc, const float* v)         { glUniform2fv(loc,1,v); }
    245 static void glUniform2iv_ei  (GLint loc, const int* v)           { glUniform2iv(loc,1,v); }
    246 
    247 static void glUniform3fv_ei  (GLint loc, const float* v)         { glUniform3fv(loc,1,v); }
    248 static void glUniform3iv_ei  (GLint loc, const int* v)           { glUniform3iv(loc,1,v); }
    249 
    250 static void glUniform4fv_ei  (GLint loc, const float* v)         { glUniform4fv(loc,1,v); }
    251 static void glUniform4iv_ei  (GLint loc, const int* v)           { glUniform4iv(loc,1,v); }
    252 
    253 static void glUniformMatrix2fv_ei  (GLint loc, const float* v)         { glUniformMatrix2fv(loc,1,false,v); }
    254 static void glUniformMatrix3fv_ei  (GLint loc, const float* v)         { glUniformMatrix3fv(loc,1,false,v); }
    255 static void glUniformMatrix4fv_ei  (GLint loc, const float* v)         { glUniformMatrix4fv(loc,1,false,v); }
    256 
    257 
    258 EIGEN_GL_FUNC1_DECLARATION       (glUniform,GLint,const)
    259 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float,        2,2fv_ei)
    260 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int,          2,2iv_ei)
    261 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float,        3,3fv_ei)
    262 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int,          3,3iv_ei)
    263 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float,        4,4fv_ei)
    264 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int,          4,4iv_ei)
    265 
    266 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        2,2,Matrix2fv_ei)
    267 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        3,3,Matrix3fv_ei)
    268 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        4,4,Matrix4fv_ei)
    269 
    270 #endif
    271 
    272 #ifdef GL_VERSION_2_1
    273 
    274 static void glUniformMatrix2x3fv_ei(GLint loc, const float* v)         { glUniformMatrix2x3fv(loc,1,false,v); }
    275 static void glUniformMatrix3x2fv_ei(GLint loc, const float* v)         { glUniformMatrix3x2fv(loc,1,false,v); }
    276 static void glUniformMatrix2x4fv_ei(GLint loc, const float* v)         { glUniformMatrix2x4fv(loc,1,false,v); }
    277 static void glUniformMatrix4x2fv_ei(GLint loc, const float* v)         { glUniformMatrix4x2fv(loc,1,false,v); }
    278 static void glUniformMatrix3x4fv_ei(GLint loc, const float* v)         { glUniformMatrix3x4fv(loc,1,false,v); }
    279 static void glUniformMatrix4x3fv_ei(GLint loc, const float* v)         { glUniformMatrix4x3fv(loc,1,false,v); }
    280 
    281 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        2,3,Matrix2x3fv_ei)
    282 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        3,2,Matrix3x2fv_ei)
    283 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        2,4,Matrix2x4fv_ei)
    284 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        4,2,Matrix4x2fv_ei)
    285 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        3,4,Matrix3x4fv_ei)
    286 EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float,        4,3,Matrix4x3fv_ei)
    287 
    288 #endif
    289 
    290 #ifdef GL_VERSION_3_0
    291 
    292 static void glUniform2uiv_ei (GLint loc, const unsigned int* v)  { glUniform2uiv(loc,1,v); }
    293 static void glUniform3uiv_ei (GLint loc, const unsigned int* v)  { glUniform3uiv(loc,1,v); }
    294 static void glUniform4uiv_ei (GLint loc, const unsigned int* v)  { glUniform4uiv(loc,1,v); }
    295 
    296 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 2,2uiv_ei)
    297 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 3,3uiv_ei)
    298 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 4,4uiv_ei)
    299 
    300 #endif
    301 
    302 #ifdef GL_ARB_gpu_shader_fp64
    303 static void glUniform2dv_ei  (GLint loc, const double* v)        { glUniform2dv(loc,1,v); }
    304 static void glUniform3dv_ei  (GLint loc, const double* v)        { glUniform3dv(loc,1,v); }
    305 static void glUniform4dv_ei  (GLint loc, const double* v)        { glUniform4dv(loc,1,v); }
    306 
    307 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double,       2,2dv_ei)
    308 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double,       3,3dv_ei)
    309 EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double,       4,4dv_ei)
    310 #endif
    311 
    312 
    313 //@}
    314 
    315 }
    316 
    317 #endif // EIGEN_OPENGL_MODULE
    318