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.

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