00001 /* 00002 Copyright (c) 2010, The Barbarian Group 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00006 the following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00009 the following disclaimer. 00010 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00011 the following disclaimer in the documentation and/or other materials provided with the distribution. 00012 00013 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00014 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00015 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00016 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00017 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00018 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00019 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00020 POSSIBILITY OF SUCH DAMAGE. 00021 */ 00022 00023 #pragma once 00024 00025 #include "cinder/Cinder.h" 00026 00027 #if defined( CINDER_MAC ) 00028 #include <OpenGL/gl.h> 00029 #include <OpenGL/glext.h> 00030 #elif defined( CINDER_MSW ) 00031 #include "cinder/gl/GLee.h" 00032 #else 00033 #define CINDER_GLES 00034 #define CINDER_GLES1 00035 #endif 00036 00037 #include "cinder/Exception.h" 00038 #include "cinder/Quaternion.h" 00039 #include "cinder/Matrix.h" 00040 #include "cinder/Vector.h" 00041 #include "cinder/Color.h" 00042 #include "cinder/Rect.h" 00043 #include "cinder/Font.h" 00044 #include "cinder/PolyLine.h" 00045 #include "cinder/AxisAlignedBox.h" 00046 00047 #if defined( CINDER_MSW ) 00048 #include <windows.h> 00049 #undef min 00050 #undef max 00051 #include <gl/gl.h> 00052 #elif defined( CINDER_COCOA_TOUCH ) 00053 #include <OpenGLES/ES1/gl.h> 00054 #include <OpenGLES/ES1/glext.h> 00055 #elif defined( CINDER_MAC ) 00056 #include <OpenGL/gl.h> 00057 #endif 00058 00059 // forward declarations 00060 namespace cinder { 00061 class Camera; class TriMesh2d; class TriMesh; class Sphere; 00062 namespace gl { 00063 class VboMesh; class Texture; 00064 } 00065 } // namespace cinder 00066 00067 namespace cinder { namespace gl { 00068 00070 bool isExtensionAvailable( const std::string &extName ); 00071 00073 void clear( const ColorA &color = ColorA::black(), bool clearDepthBuffer = true ); 00074 00076 void enableVerticalSync( bool enable = true ); 00078 inline void disableVerticalSync() { enableVerticalSync( false ); } 00080 bool isVerticalSyncEnabled(); 00081 00083 void setMatrices( const Camera &cam ); 00085 void setModelView( const Camera &cam ); 00087 void setProjection( const Camera &cam ); 00089 void pushModelView(); 00091 void popModelView(); 00093 void pushModelView( const Camera &cam ); 00095 void pushProjection( const Camera &cam ); 00097 void pushMatrices(); 00099 void popMatrices(); 00101 void multModelView( const Matrix44f &mtx ); 00103 void multProjection( const Matrix44f &mtx ); 00105 Matrix44f getModelView(); 00107 Matrix44f getProjection(); 00108 00110 void setMatricesWindowPersp( int screenWidth, int screenHeight, float fovDegrees = 60.0f, float nearPlane = 1.0f, float farPlane = 1000.0f, bool originUpperLeft = true ); 00112 inline void setMatricesWindowPersp( const Vec2i &screenSize, float fovDegrees = 60.0f, float nearPlane = 1.0f, float farPlane = 1000.0f, bool originUpperLeft = true ) 00113 { setMatricesWindowPersp( screenSize.x, screenSize.y, fovDegrees, nearPlane, farPlane ); } 00115 void setMatricesWindow( int screenWidth, int screenHeight, bool originUpperLeft = true ); 00117 inline void setMatricesWindow( const Vec2i &screenSize, bool originUpperLeft = true ) { setMatricesWindow( screenSize.x, screenSize.y, originUpperLeft ); } 00118 00120 Area getViewport(); 00122 void setViewport( const Area &area ); 00123 00125 void translate( const Vec2f &pos ); 00127 inline void translate( float x, float y ) { translate( Vec2f( x, y ) ); } 00129 void translate( const Vec3f &pos ); 00131 inline void translate( float x, float y, float z ) { translate( Vec3f( x, y, z ) ); } 00132 00134 void scale( const Vec3f &scl ); 00136 inline void scale( const Vec2f &scl ) { scale( Vec3f( scl.x, scl.y, 0 ) ); } 00138 inline void scale( float x, float y ) { scale( Vec3f( x, y, 0 ) ); } 00140 inline void scale( float x, float y, float z ) { scale( Vec3f( x, y, z ) ); } 00141 00143 void rotate( const Vec3f &xyz ); 00145 void rotate( const Quatf &quat ); 00147 inline void rotate( float degrees ) { rotate( Vec3f( 0, 0, degrees ) ); } 00148 00149 #if ! defined( CINDER_GLES ) 00150 00151 inline void begin( GLenum mode ) { glBegin( mode ); } 00153 inline void end() { glEnd(); } 00155 inline void vertex( const Vec2f &v ) { glVertex2fv( &v.x ); } 00157 inline void vertex( float x, float y ) { glVertex2f( x, y ); } 00159 inline void vertex( const Vec3f &v ) { glVertex3fv( &v.x ); } 00161 inline void vertex( float x, float y, float z ) { glVertex3f( x, y, z ); } 00163 inline void texCoord( float x, float y ) { glTexCoord2f( x, y ); } 00165 inline void texCoord( const Vec2f &v ) { glTexCoord2f( v.x, v.y ); } 00167 inline void texCoord( float x, float y, float z ) { glTexCoord3f( x, y, z ); } 00169 inline void texCoord( const Vec3f &v ) { glTexCoord3f( v.x, v.y, v.z ); } 00170 #endif // ! defined( CINDER_GLES ) 00171 00172 inline void color( float r, float g, float b ) { glColor4f( r, g, b, 1.0f ); } 00174 inline void color( float r, float g, float b, float a ) { glColor4f( r, g, b, a ); } 00176 inline void color( const Color8u &c ) { glColor4ub( c.r, c.g, c.b, 255 ); } 00178 inline void color( const ColorA8u &c ) { glColor4ub( c.r, c.g, c.b, c.a ); } 00180 inline void color( const Color &c ) { glColor4f( c.r, c.g, c.b, 1.0f ); } 00182 inline void color( const ColorA &c ) { glColor4f( c.r, c.g, c.b, c.a ); } 00183 00185 inline void enable( GLenum state ) { glEnable( state ); } 00187 inline void disable( GLenum state ) { glDisable( state ); } 00188 00190 void enableAlphaBlending( bool premultiplied = false ); 00192 void disableAlphaBlending(); 00194 void enableAdditiveBlending(); 00195 00198 void enableAlphaTest( float value = 0.5f, int func = GL_GREATER ); 00200 void disableAlphaTest(); 00201 00202 #if ! defined( CINDER_GLES ) 00203 00204 void enableWireframe(); 00206 void disableWireframe(); 00207 #endif // ! defined( CINDER_GLES ) 00208 00210 void disableDepthRead(); 00212 void disableDepthWrite(); 00214 void enableDepthRead( bool enable = true ); 00216 void enableDepthWrite( bool enable = true ); 00217 00219 void drawLine( const Vec2f &start, const Vec2f &end ); 00221 void drawLine( const Vec3f &start, const Vec3f &end ); 00223 void drawCube( const Vec3f ¢er, const Vec3f &size ); 00225 void drawColorCube( const Vec3f ¢er, const Vec3f &size ); 00227 void drawStrokedCube( const Vec3f ¢er, const Vec3f &size ); 00229 inline void drawStrokedCube( const AxisAlignedBox3f &aab ) { drawStrokedCube( aab.getCenter(), aab.getSize() ); } 00231 void drawSphere( const Vec3f ¢er, float radius, int segments = 12 ); 00233 void draw( const class Sphere &sphere, int segments = 12 ); 00235 void drawSolidCircle( const Vec2f ¢er, float radius, int numSegments = 0 ); 00237 void drawStrokedCircle( const Vec2f ¢er, float radius, int numSegments = 0 ); 00239 void drawSolidEllipse( const Vec2f ¢er, float radiusX, float radiusY, int numSegments = 0 ); 00241 void drawStrokedEllipse( const Vec2f ¢er, float radiusX, float radiusY, int numSegments = 0 ); 00243 void drawSolidRect( const Rectf &rect, bool textureRectangle = false ); 00245 void drawStrokedRect( const Rectf &rect ); 00246 void drawSolidRoundedRect( const Rectf &r, float cornerRadius, int numSegmentsPerCorner = 0 ); 00247 void drawStrokedRoundedRect( const Rectf &r, float cornerRadius, int numSegmentsPerCorner = 0 ); 00249 void drawCoordinateFrame( float axisLength = 1.0f, float headLength = 0.2f, float headRadius = 0.05f ); 00251 void drawVector( const Vec3f &start, const Vec3f &end, float headLength = 0.2f, float headRadius = 0.05f ); 00253 void drawFrustum( const Camera &cam ); 00255 void drawTorus( float outterRadius, float innerRadius, int longitudeSegments = 12, int latitudeSegments = 12 ); 00257 void drawCylinder( float baseRadius, float topRadius, float height, int slices = 12, int stacks = 1 ); 00259 void draw( const class PolyLine<Vec2f> &polyLine ); 00261 void draw( const class PolyLine<Vec3f> &polyLine ); 00263 void draw( const class Path2d &path2d, float approximationScale = 1.0f ); 00265 void draw( const class Shape2d &shape2d, float approximationScale = 1.0f ); 00266 00268 void drawSolid( const class Path2d &path2d, float approximationScale = 1.0f ); 00270 void drawSolid( const class Shape2d &shape2d, float approximationScale = 1.0f ); 00272 void drawSolid( const PolyLine2f &polyLine ); 00273 00275 void draw( const TriMesh2d &mesh ); 00277 void drawRange( const TriMesh2d &mesh, size_t startTriangle, size_t triangleCount ); 00279 void draw( const TriMesh &mesh ); 00281 void drawRange( const TriMesh &mesh, size_t startTriangle, size_t triangleCount ); 00283 00284 #if ! defined ( CINDER_GLES ) 00285 void draw( const VboMesh &vbo ); 00287 void drawRange( const VboMesh &vbo, size_t startIndex, size_t indexCount, int vertexStart = -1, int vertexEnd = -1 ); 00289 void drawArrays( const VboMesh &vbo, GLint first, GLsizei count ); 00291 #endif 00292 00293 void drawBillboard( const Vec3f &pos, const Vec2f &scale, float rotationDegrees, const Vec3f &bbRight, const Vec3f &bbUp ); 00295 void draw( const Texture &texture ); 00297 void draw( const Texture &texture, const Vec2f &pos ); 00299 void draw( const Texture &texture, const Rectf &rect ); 00301 void draw( const Texture &texture, const Area &srcArea, const Rectf &destRect ); 00302 00304 void drawString( const std::string &str, const Vec2f &pos, const ColorA &color = ColorA( 1, 1, 1, 1 ), Font font = Font() ); 00306 void drawStringCentered( const std::string &str, const Vec2f &pos, const ColorA &color = ColorA( 1, 1, 1, 1 ), Font font = Font() ); 00308 void drawStringRight( const std::string &str, const Vec2f &pos, const ColorA &color = ColorA( 1, 1, 1, 1 ), Font font = Font() ); 00309 00310 00312 struct SaveTextureBindState { 00313 SaveTextureBindState( GLint target ); 00314 ~SaveTextureBindState(); 00315 private: 00316 GLint mTarget; 00317 GLint mOldID; 00318 }; 00319 00321 struct BoolState { 00322 BoolState( GLint target ); 00323 ~BoolState(); 00324 private: 00325 GLint mTarget; 00326 GLboolean mOldValue; 00327 }; 00328 00330 struct ClientBoolState { 00331 ClientBoolState( GLint target ); 00332 ~ClientBoolState(); 00333 private: 00334 GLint mTarget; 00335 GLboolean mOldValue; 00336 }; 00337 00339 struct SaveColorState { 00340 SaveColorState(); 00341 ~SaveColorState(); 00342 private: 00343 GLfloat mOldValues[4]; 00344 }; 00345 00347 struct SaveFramebufferBinding { 00348 SaveFramebufferBinding(); 00349 ~SaveFramebufferBinding(); 00350 private: 00351 GLint mOldValue; 00352 }; 00353 00354 #if defined( CINDER_MSW ) 00355 00356 void initializeGlee(); 00357 #endif 00358 00359 class Exception : public cinder::Exception { 00360 }; 00361 00362 class ExceptionUnknownTarget : public Exception { 00363 }; 00364 00365 } } // namespace cinder::gl 00366 00368 00369 #if ! defined( CINDER_GLES ) 00370 inline void glVertex2f( const cinder::Vec2f &v ) { glVertex2f( v.x, v.y ); } 00371 inline void glVertex3f( const cinder::Vec3f &v ) { glVertex3f( v.x, v.y, v.z ); } 00372 inline void glVertex4f( const cinder::Vec4f &v ) { glVertex4f( v.x, v.y, v.z, v.w ); } 00373 inline void glNormal3f( const cinder::Vec3f &v ) { glNormal3f( v.x, v.y, v.z ); } 00374 inline void glColor3f( const cinder::Color &c ) { glColor3f( c.r, c.g, c.b ); } 00375 inline void glColor4f( const cinder::ColorA &c ) { glColor4f( c.r, c.g, c.b, c.a ); } 00376 inline void glTexCoord2f( const cinder::Vec2f &v ) { glTexCoord2f( v.x, v.y ); } 00377 inline void glTexCoord3f( const cinder::Vec3f &v ) { glTexCoord3f( v.x, v.y, v.z ); } 00378 inline void glTexCoord4f( const cinder::Vec4f &v ) { glTexCoord4f( v.x, v.y, v.z, v.w ); } 00379 // This style of definition conflicts with GLee 00380 //inline void glMultiTexCoord2f( GLenum target, const cinder::Vec2f &v ) { glMultiTexCoord2f( target, v.x, v.y ); } 00381 //inline void glMultiTexCoord3f( GLenum target, const cinder::Vec3f &v ) { glMultiTexCoord3f( target, v.x, v.y, v.z ); } 00382 //inline void glMultiTexCoord4f( GLenum target, const cinder::Vec4f &v ) { glMultiTexCoord4f( target, v.x, v.y, v.z, v.w ); } 00383 #endif // ! defined( CINDER_GLES ) 00384 inline void glTranslatef( const cinder::Vec3f &v ) { glTranslatef( v.x, v.y, v.z ); } 00385 inline void glScalef( const cinder::Vec3f &v ) { glScalef( v.x, v.y, v.z ); } 00386 inline void glRotatef( float angle, const cinder::Vec3f &v ) { glRotatef( angle, v.x, v.y, v.z ); } 00387 inline void glRotatef( const cinder::Quatf &quat ) { cinder::Vec3f axis; float angle; quat.getAxisAngle( &axis, &angle ); glRotatef( cinder::toDegrees( angle ), axis.x, axis.y, axis.z ); } 00388 inline void glMultMatrixf( const cinder::Matrix44f &m ) { glMultMatrixf( m.m ); } 00389 inline void glLoadMatrixf( const cinder::Matrix44f &m ) { glLoadMatrixf( m.m ); }