lib/wave-glut/wave-glut.h

Go to the documentation of this file.
00001 /*
00002  * wave-glut.h
00003  *
00004  * Copyright (C) 2008-2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * This "library" (my own glut library) is just a thin shell on top of the
00032  * actual freeglut libraries.  This is here only to make it easy for other
00033  * programs that use glut to find headers, link correctly, etc.
00034  */
00035 
00036 #ifndef WAVE_GLUT_WAVE_GLUT_H__
00037 #define WAVE_GLUT_WAVE_GLUT_H__
00038 
00039 
00040 // includes --------------------------------------------------------------------
00041 #include "color/color.h"
00042 #include "geometry/geometry_3d.h"
00043 #include "geometry/matrix_4.h"
00044 #include "threadsafe/smart_ptr.h"
00045 
00046 // need to define these to force static linking
00047 #define FREEGLUT_STATIC
00048 #define GLUT_STATIC_LIB
00049 #define GLEW_STATIC
00050 
00051 #include "GL/glew.h"
00052 #ifdef WIN32
00053 #include "GL/wglew.h"
00054 #else   // WIN32
00055 #include "GL/glxew.h"
00056 #endif  // WIN32
00057 #include "GL/freeglut.h"
00058 
00059 namespace glut {
00060 
00061 
00062 ////////////////////////////////////////////////////////////////////////////////
00063 ///
00064 /// \ingroup wave_glut
00065 /// \defgroup glut Wavepacket Glut Library Wrapper
00066 ///
00067 /// \n
00068 /// Mostly this library
00069 /// is here only as a convenient placeholder.  Code with
00070 /// glut dependencies can refer to this module in the build, and then the
00071 /// right directories will be searched for include files, the right libraries
00072 /// linked, etc.
00073 ///
00074 /// This library does provide a few helper objects and methods to make using
00075 /// glut easier, and to abstract away common setup code.
00076 ///
00077 ////////////////////////////////////////////////////////////////////////////////
00078 /*@{*/
00079 
00080 
00081 /// base floating point color object
00082 struct fcolor_t {
00083         // constructor, manipulators
00084         fcolor_t(void) throw() { this->clear(); }
00085         void clear(void) throw() {
00086                         red = green = blue = 0.0;
00087                         alpha = 1.0;
00088                 }
00089         bool isValid(void) const throw() {
00090                         return (red >= 0.0 && red <= 1.0 &&
00091                                 green >= 0.0 && green <= 1.0 &&
00092                                 blue >= 0.0 && blue <= 1.0 &&
00093                                 alpha >= 0.0 && alpha <= 1.0);
00094                 }
00095         operator float * (void) throw() {
00096                         return &red;
00097                 }
00098         operator const float * (void) const throw() {
00099                         return &red;
00100                 }
00101 
00102         // data fields
00103         float           red;
00104         float           green;
00105         float           blue;
00106         float           alpha;
00107 };
00108 
00109 
00110 
00111 /// If a client wants to use this library's glut helper entry point, it needs
00112 /// to supply an object that supports this interface.
00113 class Host {
00114 public:
00115         // public typedefs -----------------------------------------------------
00116         enum eBehavior {
00117                 eContinue       = 1,    ///< continue in glut loop
00118                 eExit           = 2,    ///< exit program immediately
00119 
00120                 // must be last!
00121                 eInvalid        = 0
00122         };
00123 
00124         // virtual destructor --------------------------------------------------
00125         virtual ~Host(void) throw();
00126 
00127         // glut::Host class interface methods ----------------------------------
00128 
00129         /// Called once, at initialization (just before main glut loop)
00130         virtual void init(void) { }
00131 
00132         /// Called on every glut idle event, with elapsed seconds since last
00133         virtual eBehavior tick(IN float dt) { return eContinue; }
00134 
00135         /// Called for every display frame.
00136         virtual void display(IN int w, IN int h) { }
00137 
00138         /// Called on mouse motion (see glutPassiveMotionFunc()).
00139         virtual eBehavior mouseMove(IN int x, IN int y) { return eContinue; }
00140 
00141         /// Called on mouse button events (see glutMouseFunc()).
00142         virtual eBehavior mouseButton(IN int button, IN int state,
00143                                 IN int x, IN int y)
00144                                 { return eContinue; }
00145 
00146         /// Called on keyboard events.
00147         virtual eBehavior keyboard(IN int key, IN int mods)
00148                                 { return eContinue; }
00149 
00150         /// Called when a special key is pressed (see glutSpecialFunc())
00151         virtual eBehavior specialKey(IN int key, IN int mods)
00152                                 { return eContinue; }
00153 
00154         /// Called only once, at glut shutdown.  Host can provide program
00155         ///     return value (typically zero if no errors).
00156         virtual int shutdown(void) { return 0; }
00157 };
00158 
00159 
00160 
00161 /// clients can call this to get common glut setup
00162 void start(IN int argc,
00163                         IN const char * argv[],
00164                         IN int width,           ///< window width, pixels
00165                         IN int height,          ///< window height, pixels
00166                         IN const char * title,  ///< window title
00167                         IN const char * gameModeString, ///< optional
00168                         IN smart_ptr<Host>& host);
00169 
00170 
00171 
00172 /// \ingroup glut
00173 /// \defgroup glut_threading Wavepacket OpenGL Threading
00174 ///
00175 /// \n
00176 /// Threading in OpenGL is non-trivial!  Just do some internet searches for
00177 /// "OpenGL multithreading context" and you'll see what I mean.
00178 ///
00179 /// \n
00180 /// In general, OpenGL isn't easy to use in a multithreaded way.  It can be
00181 /// done, but for most purposes, diving into OpenGL contexts is probably overkill.
00182 /// However, by default OpenGL isn't thread-friendly, so some sort of
00183 /// synchronization is required.
00184 ///
00185 /// \n
00186 /// This library uses multithreading in OpenGL in a very basic way: a single thread
00187 /// is doing all of the rendering, but background threads occasionally kick in
00188 /// and need to load and set up textures, etc.
00189 ///
00190 /// When a thread needs to do some open-GL specific work (that is, any time
00191 /// it needs to call OpenGL or glut APIs!) it should request that as a task.
00192 /// If the calling thread is not the OpenGL thread, the call (requestTask())
00193 /// will block until the OpenGL thread gets to it.  If the thread is the
00194 /// OpenGL thread, then the task executes right away.
00195 /*@{*/
00196 
00197 
00198 /// Create one of these (you'll have to inherit) if you have openGL work you
00199 /// need to submit to requestTask().
00200 class Task {
00201 public:
00202         // virtual destructor --------------------------------------------------
00203         virtual ~Task(void) throw();
00204 
00205         // glut::Task class interface methods ----------------------------------
00206 
00207         /// here is where the implementer can do any OpenGL-specific work
00208         virtual void doTask(void) = 0;
00209 };
00210 
00211 
00212 
00213 /// Here a thread can request that a task be handled by the open GL thread.
00214 /// Blocks until task is completed!  If task throws an exception, the
00215 /// exception will also be thrown back to the caller.
00216 void requestTask(IO Task * task);
00217 
00218 
00219 /// draw the outline of a 3D rectangle
00220 void drawRectLines(IN const rect3d_t& r,
00221                                 IN const glut_color_t& c) throw();
00222 
00223 /// get a 4x4 matrix from the given OpenGL matrix
00224 void getModelViewMatrix(OUT matrix4_t& T) throw();
00225 
00226 
00227 };      // glut namespace
00228 
00229 
00230 #endif  //WAVE_GLUT_WAVE_GLUT_H__
00231