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: */