1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library 2*bf2c3715SXin Li // for linear algebra. 3*bf2c3715SXin Li // 4*bf2c3715SXin Li // Copyright (C) 2008 Gael Guennebaud <[email protected]> 5*bf2c3715SXin Li // 6*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla 7*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed 8*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9*bf2c3715SXin Li 10*bf2c3715SXin Li #ifndef EIGEN_GPUHELPER_H 11*bf2c3715SXin Li #define EIGEN_GPUHELPER_H 12*bf2c3715SXin Li 13*bf2c3715SXin Li #include <Eigen/Geometry> 14*bf2c3715SXin Li #include <GL/gl.h> 15*bf2c3715SXin Li #include <vector> 16*bf2c3715SXin Li 17*bf2c3715SXin Li using namespace Eigen; 18*bf2c3715SXin Li 19*bf2c3715SXin Li typedef Vector4f Color; 20*bf2c3715SXin Li 21*bf2c3715SXin Li class GpuHelper 22*bf2c3715SXin Li { 23*bf2c3715SXin Li public: 24*bf2c3715SXin Li 25*bf2c3715SXin Li GpuHelper(); 26*bf2c3715SXin Li 27*bf2c3715SXin Li ~GpuHelper(); 28*bf2c3715SXin Li 29*bf2c3715SXin Li enum ProjectionMode2D { PM_Normalized = 1, PM_Viewport = 2 }; 30*bf2c3715SXin Li void pushProjectionMode2D(ProjectionMode2D pm); 31*bf2c3715SXin Li void popProjectionMode2D(); 32*bf2c3715SXin Li 33*bf2c3715SXin Li /** Multiply the OpenGL matrix \a matrixTarget by the matrix \a mat. 34*bf2c3715SXin Li Essentially, this helper function automatically calls glMatrixMode(matrixTarget) if required 35*bf2c3715SXin Li and does a proper call to the right glMultMatrix*() function according to the scalar type 36*bf2c3715SXin Li and storage order. 37*bf2c3715SXin Li \warning glMatrixMode() must never be called directly. If your're unsure, use forceMatrixMode(). 38*bf2c3715SXin Li \sa Matrix, loadMatrix(), forceMatrixMode() 39*bf2c3715SXin Li */ 40*bf2c3715SXin Li template<typename Scalar, int _Flags> 41*bf2c3715SXin Li void multMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget); 42*bf2c3715SXin Li 43*bf2c3715SXin Li /** Load the matrix \a mat to the OpenGL matrix \a matrixTarget. 44*bf2c3715SXin Li Essentially, this helper function automatically calls glMatrixMode(matrixTarget) if required 45*bf2c3715SXin Li and does a proper call to the right glLoadMatrix*() or glLoadIdentity() function according to the scalar type 46*bf2c3715SXin Li and storage order. 47*bf2c3715SXin Li \warning glMatrixMode() must never be called directly. If your're unsure, use forceMatrixMode(). 48*bf2c3715SXin Li \sa Matrix, multMatrix(), forceMatrixMode() 49*bf2c3715SXin Li */ 50*bf2c3715SXin Li template<typename Scalar, int _Flags> 51*bf2c3715SXin Li void loadMatrix(const Eigen::Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget); 52*bf2c3715SXin Li 53*bf2c3715SXin Li template<typename Scalar, typename Derived> 54*bf2c3715SXin Li void loadMatrix( 55*bf2c3715SXin Li const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&, 56*bf2c3715SXin Li GLenum matrixTarget); 57*bf2c3715SXin Li 58*bf2c3715SXin Li /** Make the matrix \a matrixTarget the current OpenGL matrix target. 59*bf2c3715SXin Li Call this function before loadMatrix() or multMatrix() if you cannot guarantee that glMatrixMode() 60*bf2c3715SXin Li has never been called after the last loadMatrix() or multMatrix() calls. 61*bf2c3715SXin Li \todo provides a debug mode checking the sanity of the cached matrix mode. 62*bf2c3715SXin Li */ forceMatrixTarget(GLenum matrixTarget)63*bf2c3715SXin Li inline void forceMatrixTarget(GLenum matrixTarget) {glMatrixMode(mCurrentMatrixTarget=matrixTarget);} 64*bf2c3715SXin Li 65*bf2c3715SXin Li inline void setMatrixTarget(GLenum matrixTarget); 66*bf2c3715SXin Li 67*bf2c3715SXin Li /** Push the OpenGL matrix \a matrixTarget and load \a mat. 68*bf2c3715SXin Li */ 69*bf2c3715SXin Li template<typename Scalar, int _Flags> 70*bf2c3715SXin Li inline void pushMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget); 71*bf2c3715SXin Li 72*bf2c3715SXin Li template<typename Scalar, typename Derived> 73*bf2c3715SXin Li void pushMatrix( 74*bf2c3715SXin Li const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&, 75*bf2c3715SXin Li GLenum matrixTarget); 76*bf2c3715SXin Li 77*bf2c3715SXin Li /** Push and clone the OpenGL matrix \a matrixTarget 78*bf2c3715SXin Li */ 79*bf2c3715SXin Li inline void pushMatrix(GLenum matrixTarget); 80*bf2c3715SXin Li 81*bf2c3715SXin Li /** Pop the OpenGL matrix \a matrixTarget 82*bf2c3715SXin Li */ 83*bf2c3715SXin Li inline void popMatrix(GLenum matrixTarget); 84*bf2c3715SXin Li 85*bf2c3715SXin Li void drawVector(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect = 50.); 86*bf2c3715SXin Li void drawVectorBox(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect = 50.); 87*bf2c3715SXin Li void drawUnitCube(void); 88*bf2c3715SXin Li void drawUnitSphere(int level=0); 89*bf2c3715SXin Li 90*bf2c3715SXin Li /// draw the \a nofElement first elements 91*bf2c3715SXin Li inline void draw(GLenum mode, uint nofElement); 92*bf2c3715SXin Li 93*bf2c3715SXin Li /// draw a range of elements 94*bf2c3715SXin Li inline void draw(GLenum mode, uint start, uint end); 95*bf2c3715SXin Li 96*bf2c3715SXin Li /// draw an indexed subset 97*bf2c3715SXin Li inline void draw(GLenum mode, const std::vector<uint>* pIndexes); 98*bf2c3715SXin Li 99*bf2c3715SXin Li protected: 100*bf2c3715SXin Li 101*bf2c3715SXin Li void update(void); 102*bf2c3715SXin Li 103*bf2c3715SXin Li GLuint mColorBufferId; 104*bf2c3715SXin Li int mVpWidth, mVpHeight; 105*bf2c3715SXin Li GLenum mCurrentMatrixTarget; 106*bf2c3715SXin Li bool mInitialized; 107*bf2c3715SXin Li }; 108*bf2c3715SXin Li 109*bf2c3715SXin Li /** Singleton shortcut 110*bf2c3715SXin Li */ 111*bf2c3715SXin Li extern GpuHelper gpu; 112*bf2c3715SXin Li 113*bf2c3715SXin Li 114*bf2c3715SXin Li /** \internal 115*bf2c3715SXin Li */ 116*bf2c3715SXin Li template<bool RowMajor, int _Flags> struct GlMatrixHelper; 117*bf2c3715SXin Li 118*bf2c3715SXin Li template<int _Flags> struct GlMatrixHelper<false,_Flags> 119*bf2c3715SXin Li { 120*bf2c3715SXin Li static void loadMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glLoadMatrixf(mat.data()); } 121*bf2c3715SXin Li static void loadMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glLoadMatrixd(mat.data()); } 122*bf2c3715SXin Li static void multMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glMultMatrixf(mat.data()); } 123*bf2c3715SXin Li static void multMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glMultMatrixd(mat.data()); } 124*bf2c3715SXin Li }; 125*bf2c3715SXin Li 126*bf2c3715SXin Li template<int _Flags> struct GlMatrixHelper<true,_Flags> 127*bf2c3715SXin Li { 128*bf2c3715SXin Li static void loadMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glLoadMatrixf(mat.transpose().eval().data()); } 129*bf2c3715SXin Li static void loadMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glLoadMatrixd(mat.transpose().eval().data()); } 130*bf2c3715SXin Li static void multMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glMultMatrixf(mat.transpose().eval().data()); } 131*bf2c3715SXin Li static void multMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glMultMatrixd(mat.transpose().eval().data()); } 132*bf2c3715SXin Li }; 133*bf2c3715SXin Li 134*bf2c3715SXin Li inline void GpuHelper::setMatrixTarget(GLenum matrixTarget) 135*bf2c3715SXin Li { 136*bf2c3715SXin Li if (matrixTarget != mCurrentMatrixTarget) 137*bf2c3715SXin Li glMatrixMode(mCurrentMatrixTarget=matrixTarget); 138*bf2c3715SXin Li } 139*bf2c3715SXin Li 140*bf2c3715SXin Li template<typename Scalar, int _Flags> 141*bf2c3715SXin Li void GpuHelper::multMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget) 142*bf2c3715SXin Li { 143*bf2c3715SXin Li setMatrixTarget(matrixTarget); 144*bf2c3715SXin Li GlMatrixHelper<_Flags&Eigen::RowMajorBit, _Flags>::multMatrix(mat); 145*bf2c3715SXin Li } 146*bf2c3715SXin Li 147*bf2c3715SXin Li template<typename Scalar, typename Derived> 148*bf2c3715SXin Li void GpuHelper::loadMatrix( 149*bf2c3715SXin Li const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&, 150*bf2c3715SXin Li GLenum matrixTarget) 151*bf2c3715SXin Li { 152*bf2c3715SXin Li setMatrixTarget(matrixTarget); 153*bf2c3715SXin Li glLoadIdentity(); 154*bf2c3715SXin Li } 155*bf2c3715SXin Li 156*bf2c3715SXin Li template<typename Scalar, int _Flags> 157*bf2c3715SXin Li void GpuHelper::loadMatrix(const Eigen::Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget) 158*bf2c3715SXin Li { 159*bf2c3715SXin Li setMatrixTarget(matrixTarget); 160*bf2c3715SXin Li GlMatrixHelper<(_Flags&Eigen::RowMajorBit)!=0, _Flags>::loadMatrix(mat); 161*bf2c3715SXin Li } 162*bf2c3715SXin Li 163*bf2c3715SXin Li inline void GpuHelper::pushMatrix(GLenum matrixTarget) 164*bf2c3715SXin Li { 165*bf2c3715SXin Li setMatrixTarget(matrixTarget); 166*bf2c3715SXin Li glPushMatrix(); 167*bf2c3715SXin Li } 168*bf2c3715SXin Li 169*bf2c3715SXin Li template<typename Scalar, int _Flags> 170*bf2c3715SXin Li inline void GpuHelper::pushMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget) 171*bf2c3715SXin Li { 172*bf2c3715SXin Li pushMatrix(matrixTarget); 173*bf2c3715SXin Li GlMatrixHelper<_Flags&Eigen::RowMajorBit,_Flags>::loadMatrix(mat); 174*bf2c3715SXin Li } 175*bf2c3715SXin Li 176*bf2c3715SXin Li template<typename Scalar, typename Derived> 177*bf2c3715SXin Li void GpuHelper::pushMatrix( 178*bf2c3715SXin Li const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&, 179*bf2c3715SXin Li GLenum matrixTarget) 180*bf2c3715SXin Li { 181*bf2c3715SXin Li pushMatrix(matrixTarget); 182*bf2c3715SXin Li glLoadIdentity(); 183*bf2c3715SXin Li } 184*bf2c3715SXin Li 185*bf2c3715SXin Li inline void GpuHelper::popMatrix(GLenum matrixTarget) 186*bf2c3715SXin Li { 187*bf2c3715SXin Li setMatrixTarget(matrixTarget); 188*bf2c3715SXin Li glPopMatrix(); 189*bf2c3715SXin Li } 190*bf2c3715SXin Li 191*bf2c3715SXin Li inline void GpuHelper::draw(GLenum mode, uint nofElement) 192*bf2c3715SXin Li { 193*bf2c3715SXin Li glDrawArrays(mode, 0, nofElement); 194*bf2c3715SXin Li } 195*bf2c3715SXin Li 196*bf2c3715SXin Li 197*bf2c3715SXin Li inline void GpuHelper::draw(GLenum mode, const std::vector<uint>* pIndexes) 198*bf2c3715SXin Li { 199*bf2c3715SXin Li glDrawElements(mode, pIndexes->size(), GL_UNSIGNED_INT, &(pIndexes->front())); 200*bf2c3715SXin Li } 201*bf2c3715SXin Li 202*bf2c3715SXin Li inline void GpuHelper::draw(GLenum mode, uint start, uint end) 203*bf2c3715SXin Li { 204*bf2c3715SXin Li glDrawArrays(mode, start, end-start); 205*bf2c3715SXin Li } 206*bf2c3715SXin Li 207*bf2c3715SXin Li #endif // EIGEN_GPUHELPER_H 208