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(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 static void glRotate(const Rotation2D<float>& rot) 182 { 183 glRotatef(rot.angle()*180.f/float(M_PI), 0.f, 0.f, 1.f); 184 } 185 static void glRotate(const Rotation2D<double>& rot) 186 { 187 glRotated(rot.angle()*180.0/M_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(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 static void glUniform2fv_ei (GLint loc, const float* v) { glUniform2fv(loc,1,v); } 250 static void glUniform2iv_ei (GLint loc, const int* v) { glUniform2iv(loc,1,v); } 251 252 static void glUniform3fv_ei (GLint loc, const float* v) { glUniform3fv(loc,1,v); } 253 static void glUniform3iv_ei (GLint loc, const int* v) { glUniform3iv(loc,1,v); } 254 255 static void glUniform4fv_ei (GLint loc, const float* v) { glUniform4fv(loc,1,v); } 256 static void glUniform4iv_ei (GLint loc, const int* v) { glUniform4iv(loc,1,v); } 257 258 static void glUniformMatrix2fv_ei (GLint loc, const float* v) { glUniformMatrix2fv(loc,1,false,v); } 259 static void glUniformMatrix3fv_ei (GLint loc, const float* v) { glUniformMatrix3fv(loc,1,false,v); } 260 static 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 static void glUniformMatrix2x3fv_ei(GLint loc, const float* v) { glUniformMatrix2x3fv(loc,1,false,v); } 280 static void glUniformMatrix3x2fv_ei(GLint loc, const float* v) { glUniformMatrix3x2fv(loc,1,false,v); } 281 static void glUniformMatrix2x4fv_ei(GLint loc, const float* v) { glUniformMatrix2x4fv(loc,1,false,v); } 282 static void glUniformMatrix4x2fv_ei(GLint loc, const float* v) { glUniformMatrix4x2fv(loc,1,false,v); } 283 static void glUniformMatrix3x4fv_ei(GLint loc, const float* v) { glUniformMatrix3x4fv(loc,1,false,v); } 284 static 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 static void glUniform2uiv_ei (GLint loc, const unsigned int* v) { glUniform2uiv(loc,1,v); } 298 static void glUniform3uiv_ei (GLint loc, const unsigned int* v) { glUniform3uiv(loc,1,v); } 299 static 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 static void glUniform2dv_ei (GLint loc, const double* v) { glUniform2dv(loc,1,v); } 309 static void glUniform3dv_ei (GLint loc, const double* v) { glUniform3dv(loc,1,v); } 310 static 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