00001 #ifndef GL_UTIL_H_IS_INCLUDED 00002 #define GL_UTIL_H_IS_INCLUDED 00003 00004 /*! 00005 * \file gl_util.H 00006 * \brief Contains several OpenGL related utility functions. 00007 * 00008 */ 00009 00010 #include <cassert> 00011 00012 #include "std/support.H" 00013 #include "glew/glew.H" 00014 00015 #include "disp/color.H" 00016 #include "mlib/points.H" 00017 00018 using namespace mlib; 00019 00020 /*! 00021 * \brief Representation of an array of 4 floats. Convenient for 00022 * passing COLOR + alpha, Wpt, or Wvec to OpenGL: 00023 * 00024 * Examples: 00025 * 00026 * // Set current color and alpha: 00027 * COLOR c = Color::orange4; 00028 * double a = 0.7; // alpha 00029 * glColor4fv(float4(c, a)); 00030 * 00031 * // Pass a position or direction to define light coordinates, 00032 * // where the homogeneous coordinate h is 1 or 0, respectively: 00033 * Wpt p; Wvec v; 00034 * if (positional_light) 00035 * glLightfv(GL_LIGHT0, GL_POSITION, float4(p)); // h == 1 00036 * else 00037 * glLightfv(GL_LIGHT0, GL_POSITION, float4(v)); // h == 0 00038 * 00039 */ 00040 class float4 { 00041 public: 00042 //! \name Constructors 00043 //@{ 00044 float4(CCOLOR& c, double alpha = 1.0) { 00045 _data[0] = static_cast<GLfloat>(c[0]); 00046 _data[1] = static_cast<GLfloat>(c[1]); 00047 _data[2] = static_cast<GLfloat>(c[2]); 00048 _data[3] = static_cast<GLfloat>(alpha); 00049 } 00050 float4(CWpt& p) { 00051 _data[0] = static_cast<GLfloat>(p[0]); 00052 _data[1] = static_cast<GLfloat>(p[1]); 00053 _data[2] = static_cast<GLfloat>(p[2]); 00054 _data[3] = 1; 00055 } 00056 float4(CWvec& v) { 00057 _data[0] = static_cast<GLfloat>(v[0]); 00058 _data[1] = static_cast<GLfloat>(v[1]); 00059 _data[2] = static_cast<GLfloat>(v[2]); 00060 _data[3] = 0; 00061 } 00062 //@} 00063 00064 //! \brief Define implicit cast from float4 to GLfloat*: 00065 operator GLfloat* () { return _data; } 00066 00067 private: 00068 GLfloat _data[4]; 00069 }; 00070 00071 /*! 00072 * \brief Representation of an array of 3 floats. 00073 * Convenient for passing a Wpt, Wvec, or COLOR to OpenGL. 00074 * 00075 * Examples: 00076 * 00077 * // Send a Wvec to a GLSL shader 00078 * Wvec v; 00079 * glUniform3fv(float3(v)); 00080 * 00081 */ 00082 class float3 { 00083 public: 00084 //! \name Constructors 00085 //@{ 00086 float3(CWpt& p) { 00087 _data[0] = static_cast<GLfloat>(p[0]); 00088 _data[1] = static_cast<GLfloat>(p[1]); 00089 _data[2] = static_cast<GLfloat>(p[2]); 00090 } 00091 float3(CWvec& v) { 00092 _data[0] = static_cast<GLfloat>(v[0]); 00093 _data[1] = static_cast<GLfloat>(v[1]); 00094 _data[2] = static_cast<GLfloat>(v[2]); 00095 } 00096 float3(CNDCZpt& p) { 00097 _data[0] = static_cast<GLfloat>(p[0]); 00098 _data[1] = static_cast<GLfloat>(p[1]); 00099 _data[2] = static_cast<GLfloat>(p[2]); 00100 } 00101 float3(CNDCZvec& v) { 00102 _data[0] = static_cast<GLfloat>(v[0]); 00103 _data[1] = static_cast<GLfloat>(v[1]); 00104 _data[2] = static_cast<GLfloat>(v[2]); 00105 } 00106 float3(CCOLOR& c) { 00107 _data[0] = static_cast<GLfloat>(c[0]); 00108 _data[1] = static_cast<GLfloat>(c[1]); 00109 _data[2] = static_cast<GLfloat>(c[2]); 00110 } 00111 //@} 00112 00113 //! \brief Define implicit cast from float3 to GLfloat*: 00114 operator GLfloat* () { return _data; } 00115 00116 private: 00117 GLfloat _data[3]; 00118 }; 00119 00120 /*! 00121 * \brief Representation of an array of 2 floats. 00122 * Convenient for passing a PIXEL or other 2D type to OpenGL. 00123 * 00124 * Examples: 00125 * 00126 * // Send a PIXEL to a GLSL shader 00127 * PIXEL p; 00128 * glUniform2fv(float2(p)); 00129 * 00130 */ 00131 class float2 { 00132 public: 00133 //! \name Constructors 00134 //@{ 00135 float2(CXYpt& p) { 00136 _data[0] = static_cast<GLfloat>(p[0]); 00137 _data[1] = static_cast<GLfloat>(p[1]); 00138 } 00139 float2(CXYvec& v) { 00140 _data[0] = static_cast<GLfloat>(v[0]); 00141 _data[1] = static_cast<GLfloat>(v[1]); 00142 } 00143 float2(CNDCpt& p) { 00144 _data[0] = static_cast<GLfloat>(p[0]); 00145 _data[1] = static_cast<GLfloat>(p[1]); 00146 } 00147 float2(CNDCvec& v) { 00148 _data[0] = static_cast<GLfloat>(v[0]); 00149 _data[1] = static_cast<GLfloat>(v[1]); 00150 } 00151 float2(CPIXEL& p) { 00152 _data[0] = static_cast<GLfloat>(p[0]); 00153 _data[1] = static_cast<GLfloat>(p[1]); 00154 } 00155 float2(CVEXEL& v) { 00156 _data[0] = static_cast<GLfloat>(v[0]); 00157 _data[1] = static_cast<GLfloat>(v[1]); 00158 } 00159 float2(CUVpt& p) { 00160 _data[0] = static_cast<GLfloat>(p[0]); 00161 _data[1] = static_cast<GLfloat>(p[1]); 00162 } 00163 float2(CUVvec& v) { 00164 _data[0] = static_cast<GLfloat>(v[0]); 00165 _data[1] = static_cast<GLfloat>(v[1]); 00166 } 00167 //@} 00168 00169 //! \brief Define implicit cast from float2 to GLfloat*: 00170 operator GLfloat* () { return _data; } 00171 00172 private: 00173 GLfloat _data[2]; 00174 }; 00175 00176 /*! 00177 * \brief Representation of an array of 16 floats. Really only seems 00178 * applicable for Wtransf, thus that is the only variety provided. 00179 */ 00180 class float16 { 00181 public: 00182 // constructor for Wtransf. If you want a different constructor, write it. 00183 float16(CWtransf& w) { 00184 _data[0] = static_cast<GLfloat>(w[0][0]); 00185 _data[1] = static_cast<GLfloat>(w[0][1]); 00186 _data[2] = static_cast<GLfloat>(w[0][2]); 00187 _data[3] = static_cast<GLfloat>(w[0][3]); 00188 _data[4] = static_cast<GLfloat>(w[1][0]); 00189 _data[5] = static_cast<GLfloat>(w[1][1]); 00190 _data[6] = static_cast<GLfloat>(w[1][2]); 00191 _data[7] = static_cast<GLfloat>(w[1][3]); 00192 _data[8] = static_cast<GLfloat>(w[2][0]); 00193 _data[9] = static_cast<GLfloat>(w[2][1]); 00194 _data[10] = static_cast<GLfloat>(w[2][2]); 00195 _data[11] = static_cast<GLfloat>(w[2][3]); 00196 _data[12] = static_cast<GLfloat>(w[3][0]); 00197 _data[13] = static_cast<GLfloat>(w[3][1]); 00198 _data[14] = static_cast<GLfloat>(w[3][2]); 00199 _data[15] = static_cast<GLfloat>(w[3][3]); 00200 } 00201 00202 //! \brief Define implicit cast from float16 to GLfloat*: 00203 operator GLfloat* () { return _data; } 00204 00205 private: 00206 GLfloat _data[16]; 00207 }; 00208 00209 //! \brief Convenience function. E.g.: light_i(0) returns GL_LIGHT0 00210 inline GLenum 00211 light_i(int i) 00212 { 00213 switch(i) { 00214 case 0: return GL_LIGHT0; break; 00215 case 1: return GL_LIGHT1; break; 00216 case 2: return GL_LIGHT2; break; 00217 case 3: return GL_LIGHT3; break; 00218 case 4: return GL_LIGHT4; break; 00219 case 5: return GL_LIGHT5; break; 00220 case 6: return GL_LIGHT6; break; 00221 case 7: return GL_LIGHT7; break; 00222 default: assert(0); 00223 } 00224 return GL_LIGHT0; // for the compiler 00225 } 00226 00227 //! \brief Send a color and alpha value to OpenGL. 00228 inline void 00229 GL_COL(CCOLOR &c, double a) 00230 { 00231 glColor4fv(float4(c,a)); 00232 } 00233 00234 //! \brief Set OpenGL material color values given a COLOR and an alpha value. 00235 inline void 00236 GL_MAT_COLOR(GLenum face, GLenum pname, const COLOR &c, double a) 00237 { 00238 // Make sure the face parameter is valid: 00239 assert((face == GL_FRONT) || (face == GL_BACK) || (face == GL_FRONT_AND_BACK)); 00240 00241 // Make sure the pname parameter is valid (it has to be a color channel value): 00242 assert((pname == GL_AMBIENT) || 00243 (pname == GL_DIFFUSE) || 00244 (pname == GL_SPECULAR) || 00245 (pname == GL_EMISSION) || 00246 (pname == GL_AMBIENT_AND_DIFFUSE)); 00247 00248 glMaterialfv(face, pname, float4(c,a)); 00249 } 00250 00251 #endif // GL_UTIL_H_IS_INCLUDED 00252 00253 // end of file gl_util.H