CVD 0.8
cvd/gl_helpers.h
00001 /*
00002     This file is part of the CVD Library.
00003 
00004     Copyright (C) 2005 The Authors
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2.1 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public
00017     License along with this library; if not, write to the Free Software
00018     Foundation, Inc.,
00019     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 */
00021 #ifndef CVD_GL_HELPERS_H
00022 #define CVD_GL_HELPERS_H
00023 
00024 #include <iostream>
00025 #include <map>
00026 #include <utility>
00027 
00028 #include <cvd/image_ref.h>
00029 #include <cvd/image.h>
00030 #include <cvd/byte.h>
00031 #include <cvd/rgb.h>
00032 #include <cvd/byte.h>
00033 #include <cvd/rgb8.h>
00034 #include <cvd/rgba.h>
00035 #include <cvd/config.h>
00036 #ifdef WIN32
00037 #include <windows.h>
00038 #endif
00039 
00040 #ifdef _OSX
00041 #include <OpenGL/gl.h>
00042 #include <OpenGL/glu.h>
00043 #else
00044 #include <GL/gl.h>
00045 #include <GL/glu.h>
00046 #endif
00047 
00048 
00049 
00050 #include <cvd/internal/gl_types.h>
00051 
00052 #ifdef CVD_HAVE_TOON
00053 #include <TooN/TooN.h>
00054 #include <cvd/se3.h>
00055 #include <cvd/so3.h>
00056 #include <cvd/se2.h>
00057 #include <cvd/so2.h>
00058 #endif
00059 
00060 namespace CVD
00061 {
00062 
00066     inline void glVertex(const ImageRef& i)
00067     {
00068         glVertex2i(i.x, i.y);
00069     }
00070 
00074     inline void glTexCoord(const ImageRef& i)
00075     {
00076         glTexCoord2i(i.x, i.y);
00077     }
00078 
00079 #ifdef GL_GLEXT_PROTOTYPES
00080 
00081 
00082 
00083 
00084     inline void glMultiTexCoord(GLenum unit, const ImageRef& i)
00085     {
00086             glMultiTexCoord2i(unit,  i.x, i.y);
00087     }
00088 #endif
00089 
00090 
00091 
00092     inline void glRasterPos(const ImageRef& i)
00093     {
00094         glRasterPos2i(i.x, i.y);
00095     }
00096 
00101     inline void glRect( const ImageRef & p, const ImageRef & q)
00102     {
00103         glRecti(p.x, p.y, q.x, q.y);
00104     }
00105 
00106     #ifdef CVD_HAVE_TOON
00107 
00108 
00109 
00110     inline void glVertex(const TooN::Vector<2>& v)
00111     {
00112         glVertex2d(v[0], v[1]);
00113     }
00114 
00118     inline void glVertex(const TooN::Vector<3>& v)
00119     {
00120         glVertex3d(v[0], v[1], v[2]);
00121     }
00122 
00126     inline void glVertex(const TooN::Vector<4>& v)
00127     {
00128         glVertex4d(v[0], v[1], v[2], v[3]);
00129     }
00130 
00134     inline void glTexCoord(const TooN::Vector<2>& v)
00135     {
00136         glTexCoord2d(v[0], v[1]);
00137     }
00138 
00142     inline void glTexCoord(const TooN::Vector<3>& v)
00143     {
00144         glTexCoord3d(v[0], v[1], v[2]);
00145     }
00146 
00150     inline void glTexCoord(const TooN::Vector<4>& v)
00151     {
00152         glTexCoord4d(v[0], v[1], v[2], v[3]);
00153     }
00154     
00159     inline void glRect( const TooN::Vector<2> & p, const TooN::Vector<2> & q)
00160     {
00161         glRectd(p[0], p[1], q[0], q[1]);
00162     }
00163 
00164 #ifdef GL_GLEXT_PROTOTYPES
00165 
00166 
00167 
00168 
00169     inline void glMultiTexCoord(GLenum unit, const TooN::Vector<2>& v)
00170     {
00171             glMultiTexCoord2d(unit, v[0], v[1]);
00172     }
00173 
00178     inline void glMultiTexCoord(GLenum unit, const TooN::Vector<3>& v)
00179     {
00180             glMultiTexCoord3d(unit, v[0], v[1], v[2]);
00181     }
00182 
00187     inline void glMultiTexCoord(GLenum unit, const TooN::Vector<4>& v)
00188     {
00189             glMultiTexCoord4d(unit, v[0], v[1], v[2], v[3]);
00190     }
00191 #endif
00192 
00196     inline void glRasterPos(const TooN::Vector<2>& v)
00197     {
00198         glRasterPos2d(v[0], v[1]);
00199     }
00200 
00204     inline void glRasterPos(const TooN::Vector<3>& v)
00205     {
00206         glRasterPos3d(v[0], v[1], v[2]);
00207     }
00208 
00212     inline void glRasterPos(const TooN::Vector<4>& v)
00213     {
00214         glRasterPos4d(v[0], v[1], v[2], v[3]);
00215     }
00216 
00220     inline void glNormal(const TooN::Vector<3>& n)
00221     {
00222             glNormal3d(n[0], n[1], n[2]);
00223     }
00224 
00228     inline void glTranslate( const ImageRef & v )
00229     {
00230         glTranslatef( static_cast<GLfloat>(v.x), static_cast<GLfloat>(v.y), 0);
00231     }
00232 
00236     template <int N> inline void glTranslate( const TooN::Vector<N> & v)
00237     {
00238         glTranslated(v[0], v[1], v[2]);
00239     }
00240 
00245     template <> inline void glTranslate( const TooN::Vector<2> & v)
00246     {
00247         glTranslated(v[0], v[1], 0);
00248     }
00249 
00254     template <> inline void glTranslate( const TooN::Vector<1> & v)
00255     {
00256         glTranslated(v[0], 0, 0);
00257     }
00258 
00264     template <int N, class P, class A> inline void glMultMatrix( const TooN::Matrix<N,N,P,A> & m )
00265     {
00266         GLdouble glm[16];
00267         glm[0] = m[0][0]; glm[1] = m[1][0]; glm[2] = m[2][0]; glm[3] = m[3][0];
00268         glm[4] = m[0][1]; glm[5] = m[1][1]; glm[6] = m[2][1]; glm[7] = m[3][1];
00269         glm[8] = m[0][2]; glm[9] = m[1][2]; glm[10] = m[2][2]; glm[11] = m[3][2];
00270         glm[12] = m[0][3]; glm[13] = m[1][3]; glm[14] = m[2][3]; glm[15] = m[3][3];
00271         glMultMatrixd(glm);
00272     }
00273 
00279     template <class P, class A> inline void glMultMatrix( const TooN::Matrix<3,3,P,A> & m )
00280     {
00281         GLdouble glm[16];
00282         glm[0] = m[0][0]; glm[1] = m[1][0]; glm[2] = m[2][0]; glm[3] = 0;
00283         glm[4] = m[0][1]; glm[5] = m[1][1]; glm[6] = m[2][1]; glm[7] = 0;
00284         glm[8] = m[0][2]; glm[9] = m[1][2]; glm[10] = m[2][2]; glm[11] = 0;
00285         glm[12] = 0; glm[13] = 0; glm[14] = 0; glm[15] = 1;
00286         glMultMatrixd(glm);
00287     }
00288 
00294     template <class P, class A> inline void glMultMatrix( const TooN::Matrix<2,2,P,A> & m )
00295     {
00296         GLdouble glm[16];
00297         glm[0] = m[0][0]; glm[1] = m[1][0]; glm[2] = 0; glm[3] = 0;
00298         glm[4] = m[0][1]; glm[5] = m[1][1]; glm[6] = 0; glm[7] = 0;
00299         glm[8] = 0; glm[9] = 0; glm[10] = 1; glm[11] = 0;
00300         glm[12] = 0; glm[13] = 0; glm[14] = 0; glm[15] = 1;
00301         glMultMatrixd(glm);
00302     }
00303 
00307     template <typename P>
00308     inline void glMultMatrix( const TooN::SO3<P> & so3 )
00309     {
00310         glMultMatrix( so3.get_matrix());
00311     }
00312 
00317     template <typename P>
00318     inline void glMultMatrix( const TooN::SE3<P> & se3 )
00319     {
00320         glTranslate( se3.get_translation());
00321         glMultMatrix( se3.get_rotation());
00322     }
00323 
00327     template <typename P>
00328     inline void glMultMatrix( const TooN::SO2<P> & so2 )
00329     {
00330         glMultMatrix( so2.get_matrix());
00331     }
00332 
00337     template <typename P>
00338     inline void glMultMatrix( const TooN::SE2<P> & se2 )
00339     {
00340         glTranslate( se2.get_translation());
00341         glMultMatrix( se2.get_rotation());
00342     }
00343 
00351     inline void glOrtho( const CVD::ImageRef & size, const double nearPlane = -1.0, const double farPlane = 1.0)
00352     {
00353 	    ::glOrtho( -0.375, size.x - 0.375, size.y - 0.375, -0.375, nearPlane, farPlane );
00354     }
00355 
00360     inline void glOrtho( const TooN::Vector<6> & param)
00361     {
00362 		::glOrtho( param[0], param[1], param[2], param[3], param[4], param[5]);
00363     }
00364 
00377     template <typename P, typename A>
00378     inline void glFrustum( const TooN::Vector<4,P,A> & params, double width, double height, double nearPlane = 0.1, double farPlane = 100)
00379     {
00380         GLdouble left, right, bottom, top;
00381         left = -nearPlane * params[2] / params[0];
00382         top = nearPlane * params[3] / params[1];
00383         right = nearPlane * ( width - params[2] ) / params[0];
00384         bottom = - nearPlane * ( height - params[3] ) / params[1];
00385 		::glFrustum( left, right, bottom, top, nearPlane, farPlane );
00386     }
00387 
00396     template <class CAMERA> inline void glFrustum( const CAMERA & camera, double width, double height, double nearPlane = 0.1, double farPlane = 100)
00397     {
00398         glFrustum( camera.get_parameters().template slice<0,4>(), width, height, nearPlane, farPlane);
00399     }
00400 
00405     inline void glFrustum( const TooN::Vector<6> & param)
00406     {
00407 		::glFrustum( param[0], param[1], param[2], param[3], param[4], param[5]);
00408     }
00409 
00414     inline void glColor(const TooN::Vector<3>& v)
00415     {
00416         glColor3d(v[0], v[1], v[2]);
00417     }
00418 
00423     inline void glColor(const TooN::Vector<4>& v)
00424     {
00425         glColor4d(v[0], v[1], v[2], v[3]);
00426     }
00427 
00432     inline void glClearColor(const TooN::Vector<4>& v)
00433     {
00434 		::glClearColor((GLclampf)v[0], (GLclampf)v[1], (GLclampf)v[2], (GLclampf)v[3]);
00435     }
00436 
00441     inline void glClearColor(const TooN::Vector<3>& v)
00442     {
00443 		::glClearColor((GLclampf)v[0], (GLclampf)v[1], (GLclampf)v[2], 0);
00444     }
00445 
00446 
00447 
00451     inline void glColor(const TooN::Vector<-1> & v)
00452     {
00453         switch(v.size()){
00454         case 3: glColor3d(v[0], v[1], v[2]);
00455             break;
00456         case 4: glColor4d(v[0], v[1], v[2], v[3]);
00457             break;
00458         }
00459     }
00460     #endif
00461 
00465     template <class P1, class P2> inline void glLine(const P1& x1, const P2& x2) {
00466         glBegin(GL_LINES);
00467         glVertex(x1);
00468         glVertex(x2);
00469         glEnd();
00470     }
00471 
00476     template<class C> inline void glVertex( const C & list )
00477     {
00478         for(typename C::const_iterator v = list.begin(); v != list.end(); ++v)
00479             glVertex(*v);
00480     }
00481 
00486     inline void glColor(const CVD::Rgb<byte>& c)
00487     {
00488         glColor3ub(c.red, c.green, c.blue);
00489     }
00490 
00495     inline void glColor(const CVD::Rgb<float>& c)
00496     {
00497         glColor3f(c.red, c.green, c.blue);
00498     }
00499 
00504     inline void glColor3(const CVD::Rgb8& c)
00505     {
00506         glColor3ub(c.red, c.green, c.blue);
00507     }
00508 
00513     inline void glColor4(const CVD::Rgb8& c)
00514     {
00515         glColor4ub(c.red, c.green, c.blue, c.dummy);
00516     }
00517 
00522     inline void glColor(const CVD::Rgba<unsigned char>& c)
00523     {
00524         glColor4ub(c.red, c.green, c.blue, c.alpha);
00525     }
00526 
00531     inline void glColor(const CVD::Rgba<float>& c)
00532     {
00533         glColor4f(c.red, c.green, c.blue, c.alpha);
00534     }
00535 
00536     namespace Internal{
00537             static inline int alignof(const void* ptr)
00538             {
00539                 size_t p = (size_t)ptr;
00540 
00541                 if(p&3)
00542                     if(p&1)
00543                         return 1;
00544                     else 
00545                         return 2;
00546                 else
00547                     if(p&4)
00548                         return 4;
00549                     else
00550                         return 8;
00551             }
00552     }
00553 
00558     template<class C> inline void glDrawPixels(const SubImage<C>& i)
00559     {
00560         ::glPixelStorei(GL_UNPACK_ALIGNMENT, std::min(Internal::alignof(i[0]), Internal::alignof(i[1])));
00561         ::glPixelStorei(GL_UNPACK_ROW_LENGTH, i.row_stride());
00562 		::glDrawPixels(i.size().x, i.size().y, gl::data<C>::format, gl::data<C>::type, i.data());
00563         ::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00564     }
00565 
00570     template<class C> inline void glReadPixels(BasicImage<C>& i, ImageRef origin=ImageRef(0,0))
00571     {
00572 		::glReadPixels(origin.x, origin.y, i.size().x, i.size().y, gl::data<C>::format, gl::data<C>::type, i.data());
00573     }
00574 
00579     template<class C> inline Image<C> glReadPixels(ImageRef size, ImageRef origin=ImageRef(0,0))
00580     {
00581         Image<C> i(size);
00582 		::glReadPixels(origin.x, origin.y, i.size().x, i.size().y, gl::data<C>::format, gl::data<C>::type, i.data());
00583         return i;
00584     }
00585 
00590     template<class C> inline void glTexSubImage2D( const SubImage<C> &i, GLint xoffset = 0, GLint yoffset = 0, GLenum target = GL_TEXTURE_2D, GLint level = 0)
00591     {
00592         ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00593         ::glPixelStorei(GL_UNPACK_ROW_LENGTH, i.row_stride());
00594 		::glTexSubImage2D(target, level, xoffset, yoffset, i.size().x, i.size().y, gl::data<C>::format, gl::data<C>::type, i.data());
00595         ::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00596     }
00597 
00602     template<class C> inline void glTexImage2D( const SubImage<C> &i, GLint border = 0, GLenum target = GL_TEXTURE_2D, GLint level = 0)
00603     {
00604         ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00605         ::glPixelStorei(GL_UNPACK_ROW_LENGTH, i.row_stride());
00606 		::glTexImage2D(target, level, gl::data<C>::format, i.size().x, i.size().y, border, gl::data<C>::format, gl::data<C>::type, i.data());
00607         ::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00608     }
00609 
00612     inline void glPrintErrors(void){
00613         GLenum code;
00614         while((code = glGetError()) != GL_NO_ERROR){
00615             std::cout << "GL:" << code << ":" << gluGetString(code) << std::endl;
00616         }
00617     }
00618 
00622 
00625     void glSetFont( const std::string & fontname );
00626 
00628     const std::string & glGetFont();
00629 
00631     enum TEXT_STYLE {
00632         FILL = 0,       
00633         OUTLINE = 1,    
00634         NICE = 2        
00635     };
00636 
00646     std::pair<double, double> glDrawText(const std::string & text, enum TEXT_STYLE style = NICE, double spacing = 1.5, double kerning = 0.1);
00647 
00649     std::pair<double, double> glGetExtends(const std::string & text, double spacing = 1.5, double kerning = 0.1);
00650 
00652 
00653 };
00654 
00655 #endif