LoGLCanvas.C

Go to the documentation of this file.
00001 /**
00002    \file Robots/LoBot/ui/LoGLCanvas.C
00003 
00004    \brief This file defines the non-inline member functions of the
00005    lobot::GLCanvas class, which is used to encapsulate window and
00006    viewport operations for doing 2D graphics in OpenGL.
00007 */
00008 
00009 // //////////////////////////////////////////////////////////////////// //
00010 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00011 // by the University of Southern California (USC) and the iLab at USC.  //
00012 // See http://iLab.usc.edu for information about this project.          //
00013 // //////////////////////////////////////////////////////////////////// //
00014 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00015 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00016 // in Visual Environments, and Applications'' by Christof Koch and      //
00017 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00018 // pending; application number 09/912,225 filed July 23, 2001; see      //
00019 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00020 // //////////////////////////////////////////////////////////////////// //
00021 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00024 // redistribute it and/or modify it under the terms of the GNU General  //
00025 // Public License as published by the Free Software Foundation; either  //
00026 // version 2 of the License, or (at your option) any later version.     //
00027 //                                                                      //
00028 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00029 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00030 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00031 // PURPOSE.  See the GNU General Public License for more details.       //
00032 //                                                                      //
00033 // You should have received a copy of the GNU General Public License    //
00034 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00035 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00036 // Boston, MA 02111-1307 USA.                                           //
00037 // //////////////////////////////////////////////////////////////////// //
00038 //
00039 // Primary maintainer for this file: mviswana usc edu
00040 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/ui/LoGLCanvas.C $
00041 // $Id: LoGLCanvas.C 13037 2010-03-23 01:00:53Z mviswana $
00042 //
00043 
00044 //---------------------- ALTERNATIVE DEFINITION -------------------------
00045 
00046 #if !defined(INVT_HAVE_LIBGL) || !defined(INVT_HAVE_LIBGLU)
00047 
00048 #include "Robots/LoBot/ui/LoGLCanvas.H"
00049 #include "Robots/LoBot/misc/LoExcept.H"
00050 
00051 namespace lobot {
00052 
00053 GLCanvas::GLCanvas()
00054 {
00055    throw missing_libs(MISSING_OPENGL) ;
00056 }
00057 
00058 // Empty API
00059 void GLCanvas::set_window(float, float, float, float){}
00060 void GLCanvas::set_viewport(int, int, int, int){}
00061 void GLCanvas::screen_to_world(int, int, double*, double*){}
00062 void GLCanvas::zoom_to(float){}
00063 void GLCanvas::pan(float, float){}
00064 void GLCanvas::reset_zoom_pan(){}
00065 
00066 GLCanvas::~GLCanvas(){}
00067 
00068 #else // OpenGL available ==> the real McCoy
00069 
00070 //------------------------------ HEADERS --------------------------------
00071 
00072 // lobot headers
00073 #include "Robots/LoBot/ui/LoGLCanvas.H"
00074 #include "Robots/LoBot/config/LoConfigHelpers.H"
00075 #include "Robots/LoBot/util/LoMath.H"
00076 
00077 // OpenGL headers
00078 #include <GL/glu.h>
00079 #include <GL/gl.h>
00080 
00081 // Standard C++ headers
00082 #include <algorithm>
00083 
00084 //----------------------------- NAMESPACE -------------------------------
00085 
00086 namespace lobot {
00087 
00088 //-------------------------- INITIALIZATION -----------------------------
00089 
00090 GLCanvas::GLCanvas()
00091    : m_zoom_level(1)
00092 {
00093    m_window[LEFT]   = 0 ;
00094    m_window[RIGHT]  = 0 ;
00095    m_window[BOTTOM] = 0 ;
00096    m_window[TOP]    = 0 ;
00097 
00098    m_viewport[LEFT]   = 0 ;
00099    m_viewport[RIGHT]  = 0 ;
00100    m_viewport[BOTTOM] = 0 ;
00101    m_viewport[TOP]    = 0 ;
00102 }
00103 
00104 //-------------- WINDOW AND VIEWPORT RELATED OPERATIONS ----------------
00105 
00106 // Setup the world coordinate system (window in graphics speak)
00107 void GLCanvas::set_window(float left, float right, float bottom, float top)
00108 {
00109    m_window[LEFT]   = left ;
00110    m_window[RIGHT]  = right ;
00111    m_window[BOTTOM] = bottom ;
00112    m_window[TOP]    = top ;
00113 
00114    glMatrixMode(GL_PROJECTION) ;
00115    glLoadIdentity() ;
00116    gluOrtho2D(left, right, bottom, top) ;
00117 
00118    glMatrixMode(GL_MODELVIEW) ;
00119    glLoadIdentity() ;
00120 }
00121 
00122 // Setup graphics viewport with aspect ratio matching window aspect ratio
00123 void GLCanvas::set_viewport(int left, int right, int bottom, int top)
00124 {
00125    const int w = right - left ;
00126    const int h = top - bottom ;
00127    if (w <= 0 || h <= 0)
00128       return ;
00129 
00130    const float R = // window aspect ratio
00131       (m_window[RIGHT] - m_window[LEFT])/(m_window[TOP] - m_window[BOTTOM]) ;
00132    const float r = static_cast<float>(w)/h ; // viewport aspect ratio
00133    if (R < r) // tall thin window ==> adjust viewport width
00134    {
00135       const int w_adjusted = static_cast<int>(R * h) ;
00136       left  = (w - w_adjusted)/2 ;
00137       right = left + w_adjusted ;
00138    }
00139    else // short stout window ==> adjust viewport height
00140    {
00141       const int h_adjusted = static_cast<int>(w/R) ;
00142       bottom = (h - h_adjusted)/2 ;
00143       top    = bottom + h_adjusted ;
00144    }
00145 
00146    m_viewport[LEFT]   = left ;
00147    m_viewport[RIGHT]  = right ;
00148    m_viewport[BOTTOM] = bottom ;
00149    m_viewport[TOP]    = top ;
00150 
00151    glViewport(left, bottom, right - left, top - bottom) ;
00152 }
00153 
00154 void GLCanvas::get_viewport(int* x, int* y, int* width, int* height)
00155 {
00156    if (x)
00157       *x = m_viewport[LEFT] ;
00158    if (y)
00159       *y = m_viewport[BOTTOM] ;
00160    if (width)
00161       *width = m_viewport[RIGHT] - m_viewport[LEFT] ;
00162    if (height)
00163       *height = m_viewport[TOP] - m_viewport[BOTTOM] ;
00164 }
00165 
00166 void GLCanvas::screen_to_world(int x, int y, double* wx, double* wy)
00167 {
00168    if (! wx || ! wy)
00169       return ;
00170 
00171    GLint viewport[4] ;
00172    glGetIntegerv(GL_VIEWPORT, viewport) ;
00173 
00174    GLdouble mvmatrix[16] ;
00175    glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix) ;
00176 
00177    GLdouble projmatrix[16] ;
00178    glGetDoublev (GL_PROJECTION_MATRIX, projmatrix) ;
00179 
00180    GLdouble wz ;
00181    gluUnProject(x, viewport[3] - y - 1, 0, mvmatrix, projmatrix, viewport,
00182                 wx, wy, & wz) ;
00183 }
00184 
00185 //----------------------------- ZOOM/PAN --------------------------------
00186 
00187 void GLCanvas::zoom_to(float zoom_level)
00188 {
00189    zoom_level = clamp(zoom_level, Params::zoom_range()) ;
00190    float zoom_factor = zoom_level/m_zoom_level ;
00191    m_zoom_level = zoom_level ;
00192 
00193    float current_width  = m_window[RIGHT] - m_window[LEFT] ;
00194    float current_height = m_window[TOP] - m_window[BOTTOM] ;
00195 
00196    float new_width  = current_width /zoom_factor ;
00197    float new_height = current_height/zoom_factor ;
00198 
00199    float width_incr  = abs((new_width  - current_width )/2) ;
00200    float height_incr = abs((new_height - current_height)/2) ;
00201 
00202    if (new_width > current_width) // zoom-out
00203    {
00204       m_window[LEFT]   -= width_incr ;
00205       m_window[RIGHT]  += width_incr ;
00206       m_window[BOTTOM] -= height_incr ;
00207       m_window[TOP]    += height_incr ;
00208    }
00209    else // zoom-in
00210    {
00211       m_window[LEFT]   += width_incr ;
00212       m_window[RIGHT]  -= width_incr ;
00213       m_window[BOTTOM] += height_incr ;
00214       m_window[TOP]    -= height_incr ;
00215    }
00216    set_window(m_window) ;
00217 }
00218 
00219 void GLCanvas::pan(float dx, float dy)
00220 {
00221    m_window[LEFT]   += dx ;
00222    m_window[RIGHT]  += dx ;
00223    m_window[BOTTOM] += dy ;
00224    m_window[TOP]    += dy ;
00225 
00226    set_window(m_window) ;
00227 }
00228 
00229 void GLCanvas::reset_zoom_pan()
00230 {
00231    zoom_to(1) ;
00232    pan(-(m_window[LEFT] + m_window[RIGHT])/2,
00233        -(m_window[BOTTOM] + m_window[TOP])/2) ;
00234 }
00235 
00236 //----------------------------- CLEAN-UP --------------------------------
00237 
00238 GLCanvas::~GLCanvas()
00239 {}
00240 
00241 //-------------------------- KNOB TWIDDLING -----------------------------
00242 
00243 // Parameters initialization
00244 GLCanvas::Params::Params()
00245    : m_zoom_range(get_conf<float>("zoom_pan", "zoom_range",
00246                                   make_range(0.0001f, 1000.0f)))
00247 {}
00248 
00249 // Parameters clean-up
00250 GLCanvas::Params::~Params(){}
00251 
00252 // Parameters access
00253 const range<float>& GLCanvas::Params::zoom_range()
00254 {
00255    return instance().m_zoom_range ;
00256 }
00257 
00258 //-----------------------------------------------------------------------
00259 
00260 } // end of namespace encapsulating this file's definitions
00261 
00262 #endif // OpenGL availability check
00263 
00264 /* So things look consistent in everyone's emacs... */
00265 /* Local Variables: */
00266 /* indent-tabs-mode: nil */
00267 /* End: */
Generated on Sun May 8 08:41:31 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3