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