You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
19 KiB

  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. #ifndef EIGEN_OPENGL_MODULE
  10. #define EIGEN_OPENGL_MODULE
  11. #include <Eigen/Geometry>
  12. #if defined(__APPLE_CC__)
  13. #include <OpenGL/gl.h>
  14. #else
  15. #include <GL/gl.h>
  16. #endif
  17. namespace Eigen {
  18. /**
  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. #define EIGEN_GL_FUNC_DECLARATION(FUNC) \
  43. namespace internal { \
  44. template< typename XprType, \
  45. typename Scalar = typename XprType::Scalar, \
  46. int Rows = XprType::RowsAtCompileTime, \
  47. int Cols = XprType::ColsAtCompileTime, \
  48. bool IsGLCompatible = bool(XprType::Flags&LinearAccessBit) \
  49. && bool(XprType::Flags&DirectAccessBit) \
  50. && (XprType::IsVectorAtCompileTime || (XprType::Flags&RowMajorBit)==0)> \
  51. struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl); \
  52. \
  53. template<typename XprType, typename Scalar, int Rows, int Cols> \
  54. struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType,Scalar,Rows,Cols,false> { \
  55. inline static void run(const XprType& p) { \
  56. EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<typename plain_matrix_type_column_major<XprType>::type>::run(p); } \
  57. }; \
  58. } \
  59. \
  60. template<typename Derived> inline void FUNC(const Eigen::DenseBase<Derived>& p) { \
  61. EIGEN_CAT(EIGEN_CAT(internal::gl_,FUNC),_impl)<Derived>::run(p.derived()); \
  62. }
  63. #define EIGEN_GL_FUNC_SPECIALIZATION_MAT(FUNC,SCALAR,ROWS,COLS,SUFFIX) \
  64. namespace internal { \
  65. template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, ROWS, COLS, true> { \
  66. inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \
  67. }; \
  68. }
  69. #define EIGEN_GL_FUNC_SPECIALIZATION_VEC(FUNC,SCALAR,SIZE,SUFFIX) \
  70. namespace internal { \
  71. template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, SIZE, 1, true> { \
  72. inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \
  73. }; \
  74. template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, 1, SIZE, true> { \
  75. inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \
  76. }; \
  77. }
  78. EIGEN_GL_FUNC_DECLARATION (glVertex)
  79. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 2,2iv)
  80. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 2,2sv)
  81. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 2,2fv)
  82. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 2,2dv)
  83. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 3,3iv)
  84. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 3,3sv)
  85. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 3,3fv)
  86. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 3,3dv)
  87. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 4,4iv)
  88. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 4,4sv)
  89. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 4,4fv)
  90. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 4,4dv)
  91. EIGEN_GL_FUNC_DECLARATION (glTexCoord)
  92. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 2,2iv)
  93. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 2,2sv)
  94. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 2,2fv)
  95. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 2,2dv)
  96. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 3,3iv)
  97. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 3,3sv)
  98. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 3,3fv)
  99. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 3,3dv)
  100. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 4,4iv)
  101. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 4,4sv)
  102. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 4,4fv)
  103. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 4,4dv)
  104. EIGEN_GL_FUNC_DECLARATION (glColor)
  105. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 2,2iv)
  106. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 2,2sv)
  107. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 2,2fv)
  108. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 2,2dv)
  109. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 3,3iv)
  110. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 3,3sv)
  111. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 3,3fv)
  112. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 3,3dv)
  113. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 4,4iv)
  114. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 4,4sv)
  115. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 4,4fv)
  116. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 4,4dv)
  117. EIGEN_GL_FUNC_DECLARATION (glNormal)
  118. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,int, 3,3iv)
  119. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,short, 3,3sv)
  120. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,float, 3,3fv)
  121. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,double, 3,3dv)
  122. inline void glScale2fv(const float* v) { glScalef(v[0], v[1], 1.f); }
  123. inline void glScale2dv(const double* v) { glScaled(v[0], v[1], 1.0); }
  124. inline void glScale3fv(const float* v) { glScalef(v[0], v[1], v[2]); }
  125. inline void glScale3dv(const double* v) { glScaled(v[0], v[1], v[2]); }
  126. EIGEN_GL_FUNC_DECLARATION (glScale)
  127. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float, 2,2fv)
  128. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 2,2dv)
  129. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float, 3,3fv)
  130. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 3,3dv)
  131. template<typename Scalar> void glScale(const UniformScaling<Scalar>& s) { glScale(Matrix<Scalar,3,1>::Constant(s.factor())); }
  132. inline void glTranslate2fv(const float* v) { glTranslatef(v[0], v[1], 0.f); }
  133. inline void glTranslate2dv(const double* v) { glTranslated(v[0], v[1], 0.0); }
  134. inline void glTranslate3fv(const float* v) { glTranslatef(v[0], v[1], v[2]); }
  135. inline void glTranslate3dv(const double* v) { glTranslated(v[0], v[1], v[2]); }
  136. EIGEN_GL_FUNC_DECLARATION (glTranslate)
  137. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float, 2,2fv)
  138. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 2,2dv)
  139. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float, 3,3fv)
  140. EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 3,3dv)
  141. template<typename Scalar> void glTranslate(const Translation<Scalar,2>& t) { glTranslate(t.vector()); }
  142. template<typename Scalar> void glTranslate(const Translation<Scalar,3>& t) { glTranslate(t.vector()); }
  143. EIGEN_GL_FUNC_DECLARATION (glMultMatrix)
  144. EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,float, 4,4,f)
  145. EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,double, 4,4,d)
  146. template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,Affine>& t) { glMultMatrix(t.matrix()); }
  147. template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,Projective>& t) { glMultMatrix(t.matrix()); }
  148. template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,AffineCompact>& t) { glMultMatrix(Transform<Scalar,3,Affine>(t).matrix()); }
  149. EIGEN_GL_FUNC_DECLARATION (glLoadMatrix)
  150. EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,float, 4,4,f)
  151. EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,double, 4,4,d)
  152. template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,Affine>& t) { glLoadMatrix(t.matrix()); }
  153. template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,Projective>& t) { glLoadMatrix(t.matrix()); }
  154. template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,AffineCompact>& t) { glLoadMatrix(Transform<Scalar,3,Affine>(t).matrix()); }
  155. static void glRotate(const Rotation2D<float>& rot)
  156. {
  157. glRotatef(rot.angle()*180.f/float(M_PI), 0.f, 0.f, 1.f);
  158. }
  159. static void glRotate(const Rotation2D<double>& rot)
  160. {
  161. glRotated(rot.angle()*180.0/M_PI, 0.0, 0.0, 1.0);
  162. }
  163. template<typename Derived> void glRotate(const RotationBase<Derived,3>& rot)
  164. {
  165. Transform<typename Derived::Scalar,3,Projective> tr(rot);
  166. glMultMatrix(tr.matrix());
  167. }
  168. #define EIGEN_GL_MAKE_CONST_const const
  169. #define EIGEN_GL_MAKE_CONST__
  170. #define EIGEN_GL_EVAL(X) X
  171. #define EIGEN_GL_FUNC1_DECLARATION(FUNC,ARG1,CONST) \
  172. namespace internal { \
  173. template< typename XprType, \
  174. typename Scalar = typename XprType::Scalar, \
  175. int Rows = XprType::RowsAtCompileTime, \
  176. int Cols = XprType::ColsAtCompileTime, \
  177. bool IsGLCompatible = bool(XprType::Flags&LinearAccessBit) \
  178. && bool(XprType::Flags&DirectAccessBit) \
  179. && (XprType::IsVectorAtCompileTime || (XprType::Flags&RowMajorBit)==0)> \
  180. struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl); \
  181. \
  182. template<typename XprType, typename Scalar, int Rows, int Cols> \
  183. struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType,Scalar,Rows,Cols,false> { \
  184. inline static void run(ARG1 a,EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { \
  185. EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<typename plain_matrix_type_column_major<XprType>::type>::run(a,p); } \
  186. }; \
  187. } \
  188. \
  189. template<typename Derived> inline void FUNC(ARG1 a,EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) Eigen::DenseBase<Derived>& p) { \
  190. EIGEN_CAT(EIGEN_CAT(internal::gl_,FUNC),_impl)<Derived>::run(a,p.derived()); \
  191. }
  192. #define EIGEN_GL_FUNC1_SPECIALIZATION_MAT(FUNC,ARG1,CONST,SCALAR,ROWS,COLS,SUFFIX) \
  193. namespace internal { \
  194. template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, ROWS, COLS, true> { \
  195. inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); } \
  196. }; \
  197. }
  198. #define EIGEN_GL_FUNC1_SPECIALIZATION_VEC(FUNC,ARG1,CONST,SCALAR,SIZE,SUFFIX) \
  199. namespace internal { \
  200. template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, SIZE, 1, true> { \
  201. inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); } \
  202. }; \
  203. template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, 1, SIZE, true> { \
  204. inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); } \
  205. }; \
  206. }
  207. EIGEN_GL_FUNC1_DECLARATION (glGet,GLenum,_)
  208. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,float, 4,4,Floatv)
  209. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,double, 4,4,Doublev)
  210. // glUniform API
  211. #ifdef GL_VERSION_2_0
  212. static void glUniform2fv_ei (GLint loc, const float* v) { glUniform2fv(loc,1,v); }
  213. static void glUniform2iv_ei (GLint loc, const int* v) { glUniform2iv(loc,1,v); }
  214. static void glUniform3fv_ei (GLint loc, const float* v) { glUniform3fv(loc,1,v); }
  215. static void glUniform3iv_ei (GLint loc, const int* v) { glUniform3iv(loc,1,v); }
  216. static void glUniform4fv_ei (GLint loc, const float* v) { glUniform4fv(loc,1,v); }
  217. static void glUniform4iv_ei (GLint loc, const int* v) { glUniform4iv(loc,1,v); }
  218. static void glUniformMatrix2fv_ei (GLint loc, const float* v) { glUniformMatrix2fv(loc,1,false,v); }
  219. static void glUniformMatrix3fv_ei (GLint loc, const float* v) { glUniformMatrix3fv(loc,1,false,v); }
  220. static void glUniformMatrix4fv_ei (GLint loc, const float* v) { glUniformMatrix4fv(loc,1,false,v); }
  221. EIGEN_GL_FUNC1_DECLARATION (glUniform,GLint,const)
  222. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 2,2fv_ei)
  223. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 2,2iv_ei)
  224. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 3,3fv_ei)
  225. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 3,3iv_ei)
  226. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 4,4fv_ei)
  227. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 4,4iv_ei)
  228. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,2,Matrix2fv_ei)
  229. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,3,Matrix3fv_ei)
  230. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,4,Matrix4fv_ei)
  231. #endif
  232. #ifdef GL_VERSION_2_1
  233. static void glUniformMatrix2x3fv_ei(GLint loc, const float* v) { glUniformMatrix2x3fv(loc,1,false,v); }
  234. static void glUniformMatrix3x2fv_ei(GLint loc, const float* v) { glUniformMatrix3x2fv(loc,1,false,v); }
  235. static void glUniformMatrix2x4fv_ei(GLint loc, const float* v) { glUniformMatrix2x4fv(loc,1,false,v); }
  236. static void glUniformMatrix4x2fv_ei(GLint loc, const float* v) { glUniformMatrix4x2fv(loc,1,false,v); }
  237. static void glUniformMatrix3x4fv_ei(GLint loc, const float* v) { glUniformMatrix3x4fv(loc,1,false,v); }
  238. static void glUniformMatrix4x3fv_ei(GLint loc, const float* v) { glUniformMatrix4x3fv(loc,1,false,v); }
  239. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,3,Matrix2x3fv_ei)
  240. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,2,Matrix3x2fv_ei)
  241. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,4,Matrix2x4fv_ei)
  242. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,2,Matrix4x2fv_ei)
  243. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,4,Matrix3x4fv_ei)
  244. EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,3,Matrix4x3fv_ei)
  245. #endif
  246. #ifdef GL_VERSION_3_0
  247. static void glUniform2uiv_ei (GLint loc, const unsigned int* v) { glUniform2uiv(loc,1,v); }
  248. static void glUniform3uiv_ei (GLint loc, const unsigned int* v) { glUniform3uiv(loc,1,v); }
  249. static void glUniform4uiv_ei (GLint loc, const unsigned int* v) { glUniform4uiv(loc,1,v); }
  250. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 2,2uiv_ei)
  251. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 3,3uiv_ei)
  252. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 4,4uiv_ei)
  253. #endif
  254. #ifdef GL_ARB_gpu_shader_fp64
  255. static void glUniform2dv_ei (GLint loc, const double* v) { glUniform2dv(loc,1,v); }
  256. static void glUniform3dv_ei (GLint loc, const double* v) { glUniform3dv(loc,1,v); }
  257. static void glUniform4dv_ei (GLint loc, const double* v) { glUniform4dv(loc,1,v); }
  258. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 2,2dv_ei)
  259. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 3,3dv_ei)
  260. EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 4,4dv_ei)
  261. #endif
  262. //@}
  263. }
  264. #endif // EIGEN_OPENGL_MODULE