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@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 21namespace 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) \ 49namespace 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 \ 66template<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) \ 72namespace 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) \ 80namespace 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 90EIGEN_GL_FUNC_DECLARATION (glVertex) 91EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 2,2iv) 92EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 2,2sv) 93EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 2,2fv) 94EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 2,2dv) 95EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 3,3iv) 96EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 3,3sv) 97EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 3,3fv) 98EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 3,3dv) 99EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 4,4iv) 100EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 4,4sv) 101EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 4,4fv) 102EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 4,4dv) 103 104EIGEN_GL_FUNC_DECLARATION (glTexCoord) 105EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 2,2iv) 106EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 2,2sv) 107EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 2,2fv) 108EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 2,2dv) 109EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 3,3iv) 110EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 3,3sv) 111EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 3,3fv) 112EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 3,3dv) 113EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 4,4iv) 114EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 4,4sv) 115EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 4,4fv) 116EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 4,4dv) 117 118EIGEN_GL_FUNC_DECLARATION (glColor) 119EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 2,2iv) 120EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 2,2sv) 121EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 2,2fv) 122EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 2,2dv) 123EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 3,3iv) 124EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 3,3sv) 125EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 3,3fv) 126EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 3,3dv) 127EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 4,4iv) 128EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 4,4sv) 129EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 4,4fv) 130EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 4,4dv) 131 132EIGEN_GL_FUNC_DECLARATION (glNormal) 133EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,int, 3,3iv) 134EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,short, 3,3sv) 135EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,float, 3,3fv) 136EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,double, 3,3dv) 137 138inline void glScale2fv(const float* v) { glScalef(v[0], v[1], 1.f); } 139inline void glScale2dv(const double* v) { glScaled(v[0], v[1], 1.0); } 140inline void glScale3fv(const float* v) { glScalef(v[0], v[1], v[2]); } 141inline void glScale3dv(const double* v) { glScaled(v[0], v[1], v[2]); } 142 143EIGEN_GL_FUNC_DECLARATION (glScale) 144EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float, 2,2fv) 145EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 2,2dv) 146EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float, 3,3fv) 147EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 3,3dv) 148 149template<typename Scalar> void glScale(const UniformScaling<Scalar>& s) { glScale(Matrix<Scalar,3,1>::Constant(s.factor())); } 150 151inline void glTranslate2fv(const float* v) { glTranslatef(v[0], v[1], 0.f); } 152inline void glTranslate2dv(const double* v) { glTranslated(v[0], v[1], 0.0); } 153inline void glTranslate3fv(const float* v) { glTranslatef(v[0], v[1], v[2]); } 154inline void glTranslate3dv(const double* v) { glTranslated(v[0], v[1], v[2]); } 155 156EIGEN_GL_FUNC_DECLARATION (glTranslate) 157EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float, 2,2fv) 158EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 2,2dv) 159EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float, 3,3fv) 160EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 3,3dv) 161 162template<typename Scalar> void glTranslate(const Translation<Scalar,2>& t) { glTranslate(t.vector()); } 163template<typename Scalar> void glTranslate(const Translation<Scalar,3>& t) { glTranslate(t.vector()); } 164 165EIGEN_GL_FUNC_DECLARATION (glMultMatrix) 166EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,float, 4,4,f) 167EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,double, 4,4,d) 168 169template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,Affine>& t) { glMultMatrix(t.matrix()); } 170template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,Projective>& t) { glMultMatrix(t.matrix()); } 171template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,AffineCompact>& t) { glMultMatrix(Transform<Scalar,3,Affine>(t).matrix()); } 172 173EIGEN_GL_FUNC_DECLARATION (glLoadMatrix) 174EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,float, 4,4,f) 175EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,double, 4,4,d) 176 177template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,Affine>& t) { glLoadMatrix(t.matrix()); } 178template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,Projective>& t) { glLoadMatrix(t.matrix()); } 179template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,AffineCompact>& t) { glLoadMatrix(Transform<Scalar,3,Affine>(t).matrix()); } 180 181inline void glRotate(const Rotation2D<float>& rot) 182{ 183 glRotatef(rot.angle()*180.f/float(EIGEN_PI), 0.f, 0.f, 1.f); 184} 185inline void glRotate(const Rotation2D<double>& rot) 186{ 187 glRotated(rot.angle()*180.0/EIGEN_PI, 0.0, 0.0, 1.0); 188} 189 190template<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) \ 201namespace 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 \ 218template<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) \ 224namespace 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) \ 232namespace 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 241EIGEN_GL_FUNC1_DECLARATION (glGet,GLenum,_) 242EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,float, 4,4,Floatv) 243EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,double, 4,4,Doublev) 244 245// glUniform API 246 247#ifdef GL_VERSION_2_0 248 249inline void glUniform2fv_ei (GLint loc, const float* v) { glUniform2fv(loc,1,v); } 250inline void glUniform2iv_ei (GLint loc, const int* v) { glUniform2iv(loc,1,v); } 251 252inline void glUniform3fv_ei (GLint loc, const float* v) { glUniform3fv(loc,1,v); } 253inline void glUniform3iv_ei (GLint loc, const int* v) { glUniform3iv(loc,1,v); } 254 255inline void glUniform4fv_ei (GLint loc, const float* v) { glUniform4fv(loc,1,v); } 256inline void glUniform4iv_ei (GLint loc, const int* v) { glUniform4iv(loc,1,v); } 257 258inline void glUniformMatrix2fv_ei (GLint loc, const float* v) { glUniformMatrix2fv(loc,1,false,v); } 259inline void glUniformMatrix3fv_ei (GLint loc, const float* v) { glUniformMatrix3fv(loc,1,false,v); } 260inline void glUniformMatrix4fv_ei (GLint loc, const float* v) { glUniformMatrix4fv(loc,1,false,v); } 261 262 263EIGEN_GL_FUNC1_DECLARATION (glUniform,GLint,const) 264EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 2,2fv_ei) 265EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 2,2iv_ei) 266EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 3,3fv_ei) 267EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 3,3iv_ei) 268EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 4,4fv_ei) 269EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 4,4iv_ei) 270 271EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,2,Matrix2fv_ei) 272EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,3,Matrix3fv_ei) 273EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,4,Matrix4fv_ei) 274 275#endif 276 277#ifdef GL_VERSION_2_1 278 279inline void glUniformMatrix2x3fv_ei(GLint loc, const float* v) { glUniformMatrix2x3fv(loc,1,false,v); } 280inline void glUniformMatrix3x2fv_ei(GLint loc, const float* v) { glUniformMatrix3x2fv(loc,1,false,v); } 281inline void glUniformMatrix2x4fv_ei(GLint loc, const float* v) { glUniformMatrix2x4fv(loc,1,false,v); } 282inline void glUniformMatrix4x2fv_ei(GLint loc, const float* v) { glUniformMatrix4x2fv(loc,1,false,v); } 283inline void glUniformMatrix3x4fv_ei(GLint loc, const float* v) { glUniformMatrix3x4fv(loc,1,false,v); } 284inline void glUniformMatrix4x3fv_ei(GLint loc, const float* v) { glUniformMatrix4x3fv(loc,1,false,v); } 285 286EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,3,Matrix2x3fv_ei) 287EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,2,Matrix3x2fv_ei) 288EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,4,Matrix2x4fv_ei) 289EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,2,Matrix4x2fv_ei) 290EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,4,Matrix3x4fv_ei) 291EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,3,Matrix4x3fv_ei) 292 293#endif 294 295#ifdef GL_VERSION_3_0 296 297inline void glUniform2uiv_ei (GLint loc, const unsigned int* v) { glUniform2uiv(loc,1,v); } 298inline void glUniform3uiv_ei (GLint loc, const unsigned int* v) { glUniform3uiv(loc,1,v); } 299inline void glUniform4uiv_ei (GLint loc, const unsigned int* v) { glUniform4uiv(loc,1,v); } 300 301EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 2,2uiv_ei) 302EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 3,3uiv_ei) 303EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 4,4uiv_ei) 304 305#endif 306 307#ifdef GL_ARB_gpu_shader_fp64 308inline void glUniform2dv_ei (GLint loc, const double* v) { glUniform2dv(loc,1,v); } 309inline void glUniform3dv_ei (GLint loc, const double* v) { glUniform3dv(loc,1,v); } 310inline void glUniform4dv_ei (GLint loc, const double* v) { glUniform4dv(loc,1,v); } 311 312EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 2,2dv_ei) 313EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 3,3dv_ei) 314EIGEN_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