Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/OpenGL.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2011, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY 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 ON    */
00026 /*  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 
00032 #include <vlGraphics/OpenGL.hpp>
00033 #include <vlCore/String.hpp>
00034 #include <vlCore/Log.hpp>
00035 #include <vlCore/Say.hpp>
00036 #include <algorithm>
00037 
00038 #if defined(VL_OPENGL_ES1) || defined(VL_OPENGL_ES2)
00039   #include <EGL/egl.h> // for eglGetProcAddress()
00040 #endif
00041 
00042 //-----------------------------------------------------------------------------
00043 namespace vl
00044 {
00045   bool Is_OpenGL_Initialized = false;
00046   bool Is_OpenGL_Core_Profile = false;
00047   bool Is_OpenGL_Forward_Compatible = false;
00048 
00049   bool Has_GL_Version_1_1 = false;
00050   bool Has_GL_Version_1_2 = false;
00051   bool Has_GL_Version_1_3 = false;
00052   bool Has_GL_Version_1_4 = false;
00053   bool Has_GL_Version_1_5 = false;
00054   bool Has_GL_Version_2_0 = false;
00055   bool Has_GL_Version_2_1 = false;
00056   bool Has_GL_Version_3_0 = false;
00057   bool Has_GL_Version_3_1 = false;
00058   bool Has_GL_Version_3_2 = false;
00059   bool Has_GL_Version_3_3 = false;
00060   bool Has_GL_Version_4_0 = false;
00061   bool Has_GL_Version_4_1 = false;
00062 
00063   bool Has_Fixed_Function_Pipeline = false;
00064 
00065   // GLES defines
00066 
00067   bool Has_GLES_Version_1_1 = false;
00068   bool Has_GLES_Version_2_0 = false;
00069   bool Has_GLES = false;
00070 
00071   // Helper defines
00072 
00073   bool Has_GLSL = false;
00074   bool Has_GLSL_120_Or_More = false;
00075   bool Has_GLSL_130_Or_More = false;
00076   bool Has_GLSL_140_Or_More = false;
00077   bool Has_GLSL_150_Or_More = false;
00078   bool Has_GLSL_330_Or_More = false;
00079   bool Has_GLSL_400_Or_More = false;
00080   bool Has_GLSL_410_Or_More = false;
00081   bool Has_Geometry_Shader = false;
00082   bool Has_BufferObject = false;
00083   bool Has_FBO = false;
00084   bool Has_PBO = false;
00085   bool Has_FBO_Multisample = false;
00086   bool Has_Cubemap_Textures = false;
00087   bool Has_Texture_Rectangle = false;
00088   bool Has_Texture_Array = false;
00089   bool Has_Texture_Buffer = false;
00090   bool Has_Texture_Multisample = false;
00091   bool Has_Texture_3D = false;
00092   bool Has_Multitexture = false;
00093   bool Has_Primitive_Restart = false;
00094   bool Has_Occlusion_Query = false;
00095   bool Has_Transform_Feedback = false;
00096   bool Has_glGenerateMipmaps = false;
00097   bool Has_GL_GENERATE_MIPMAP = false;
00098   bool Has_Point_Sprite = false;
00099   bool Has_Base_Vertex = false;
00100   bool Has_Primitive_Instancing = false;
00101 
00102   #define VL_EXTENSION(extension) bool Has_##extension = false;
00103   #include <vlGraphics/GL/GLExtensionList.hpp>
00104   #undef VL_EXTENSION
00105 
00106   #define VL_GLES_EXTENSION(extension) bool Has_##extension = false;
00107   #include <vlGraphics/GL/GLESExtensionList.hpp>
00108   #undef VL_GLES_EXTENSION
00109 
00110   #if defined(VL_OPENGL)
00111     #define VL_GL_FUNCTION(TYPE, NAME) TYPE NAME = NULL;
00112     #include <vlGraphics/GL/GLFunctionList.hpp>
00113     #undef VL_GL_FUNCTION
00114   #endif
00115 
00116   #if defined(VL_OPENGL_ES1)
00117     #define VL_GL_FUNCTION(TYPE, NAME) TYPE NAME = NULL;
00118     #include <vlGraphics/GL/GLES1FunctionList.hpp>
00119     #undef VL_GL_FUNCTION
00120   #endif
00121 
00122   #if defined(VL_OPENGL_ES2)
00123     #define VL_GL_FUNCTION(TYPE, NAME) TYPE NAME = NULL;
00124     #include <vlGraphics/GL/GLES2FunctionList.hpp>
00125     #undef VL_GL_FUNCTION
00126   #endif
00127 
00128   const GLenum Translate_Enable[] =
00129   {
00130     // Common ones
00131     GL_BLEND,
00132     GL_CULL_FACE,
00133     GL_DEPTH_TEST,
00134     GL_STENCIL_TEST,
00135     GL_DITHER,
00136     GL_POLYGON_OFFSET_FILL, 
00137     GL_POLYGON_OFFSET_LINE, 
00138     GL_POLYGON_OFFSET_POINT,
00139     GL_COLOR_LOGIC_OP, 
00140     GL_MULTISAMPLE,
00141 
00142     // Smoothing
00143     GL_POINT_SMOOTH,
00144     GL_LINE_SMOOTH, 
00145     GL_POLYGON_SMOOTH,
00146 
00147     // Stippling
00148     GL_LINE_STIPPLE,
00149     GL_POLYGON_STIPPLE,
00150 
00151     // Point sprites
00152     GL_POINT_SPRITE, 
00153     GL_PROGRAM_POINT_SIZE, 
00154 
00155     // Fixed function pipeline
00156     GL_ALPHA_TEST, 
00157     GL_LIGHTING, 
00158     GL_COLOR_SUM,
00159     GL_FOG,
00160     GL_NORMALIZE,
00161     GL_RESCALE_NORMAL,
00162 
00163     // Available only under OpenGL 2.x
00164     GL_VERTEX_PROGRAM_TWO_SIDE,
00165 
00166     // OpenGL 3.2
00167     GL_TEXTURE_CUBE_MAP_SEAMLESS,
00168 
00169     // OpenGL 3.0
00170     GL_CLIP_DISTANCE0,
00171     GL_CLIP_DISTANCE1,
00172     GL_CLIP_DISTANCE2,
00173     GL_CLIP_DISTANCE3,
00174     GL_CLIP_DISTANCE4,
00175     GL_CLIP_DISTANCE5,
00176     GL_CLIP_DISTANCE6,
00177     GL_CLIP_DISTANCE7,
00178 
00179     // Multisampling
00180     GL_SAMPLE_ALPHA_TO_COVERAGE,
00181     GL_SAMPLE_ALPHA_TO_ONE,
00182     GL_SAMPLE_COVERAGE
00183   };
00184 
00185   const char* Translate_Enable_String[] =
00186   {
00187     // Common ones
00188     "GL_BLEND",
00189     "GL_CULL_FACE",
00190     "GL_DEPTH_TEST",
00191     "GL_STENCIL_TEST",
00192     "GL_DITHER",
00193     "GL_POLYGON_OFFSET_FILL", 
00194     "GL_POLYGON_OFFSET_LINE", 
00195     "GL_POLYGON_OFFSET_POINT",
00196     "GL_COLOR_LOGIC_OP", 
00197     "GL_MULTISAMPLE",
00198     
00199     // Smoothing
00200     "GL_POINT_SMOOTH",
00201     "GL_LINE_SMOOTH", 
00202     "GL_POLYGON_SMOOTH",
00203 
00204     // Stippling
00205     "GL_LINE_STIPPLE",
00206     "GL_POLYGON_STIPPLE",
00207 
00208     // Point sprites
00209     "GL_POINT_SPRITE", 
00210     "GL_PROGRAM_POINT_SIZE", 
00211 
00212     // Fixed function pipeline
00213     "GL_ALPHA_TEST", 
00214     "GL_LIGHTING", 
00215     "GL_COLOR_SUM",
00216     "GL_FOG",
00217     "GL_NORMALIZE",
00218     "GL_RESCALE_NORMAL",
00219 
00220     // Available only under OpenGL 2.x
00221     "GL_VERTEX_PROGRAM_TWO_SIDE",
00222 
00223     // OpenGL 3.2
00224     "GL_TEXTURE_CUBE_MAP_SEAMLESS",
00225 
00226     // OpenGL 3.0
00227     "GL_CLIP_DISTANCE0",
00228     "GL_CLIP_DISTANCE1",
00229     "GL_CLIP_DISTANCE2",
00230     "GL_CLIP_DISTANCE3",
00231     "GL_CLIP_DISTANCE4",
00232     "GL_CLIP_DISTANCE5",
00233     "GL_CLIP_DISTANCE6",
00234     "GL_CLIP_DISTANCE7",
00235 
00236     // Multisampling
00237     "GL_SAMPLE_ALPHA_TO_COVERAGE",
00238     "GL_SAMPLE_ALPHA_TO_ONE",
00239     "GL_SAMPLE_COVERAGE"
00240   };
00241 
00242   bool Is_Enable_Supported[EN_EnableCount] = 
00243   {
00244     // Common ones
00245     false /*GL_BLEND*/,
00246     false /*GL_CULL_FACE*/,
00247     false /*GL_DEPTH_TEST*/,
00248     false /*GL_STENCIL_TEST*/,
00249     false /*GL_DITHER*/,
00250     false /*GL_POLYGON_OFFSET_FILL*/, 
00251     false /*GL_POLYGON_OFFSET_LINE*/, 
00252     false /*GL_POLYGON_OFFSET_POINT*/,
00253     false /*GL_COLOR_LOGIC_OP*/, 
00254     false /*GL_MULTISAMPLE*/,
00255 
00256     // Smoothing
00257     false /*GL_POINT_SMOOTH*/,
00258     false /*GL_LINE_SMOOTH*/, 
00259     false /*GL_POLYGON_SMOOTH*/,
00260 
00261     // Stippling
00262     false /*GL_LINE_STIPPLE*/,
00263     false /*GL_POLYGON_STIPPLE*/,
00264 
00265     // Point sprites
00266     false /*GL_POINT_SPRITE*/, 
00267     false /*GL_PROGRAM_POINT_SIZE*/, 
00268 
00269     // Fixed function pipeline
00270     false /*GL_ALPHA_TEST*/, 
00271     false /*GL_LIGHTING*/, 
00272     false /*GL_COLOR_SUM*/,
00273     false /*GL_FOG*/,
00274     false /*GL_NORMALIZE*/,
00275     false /*GL_RESCALE_NORMAL*/,
00276 
00277     // Available only under OpenGL 2.x
00278     false /*GL_VERTEX_PROGRAM_TWO_SIDE*/,
00279 
00280     // OpenGL 3.2
00281     false /*GL_TEXTURE_CUBE_MAP_SEAMLESS*/,
00282 
00283     // OpenGL 3.0
00284     false /*GL_CLIP_DISTANCE0*/,
00285     false /*GL_CLIP_DISTANCE1*/,
00286     false /*GL_CLIP_DISTANCE2*/,
00287     false /*GL_CLIP_DISTANCE3*/,
00288     false /*GL_CLIP_DISTANCE4*/,
00289     false /*GL_CLIP_DISTANCE5*/,
00290     false /*GL_CLIP_DISTANCE6*/,
00291     false /*GL_CLIP_DISTANCE7*/,
00292 
00293     // Multisampling
00294     false /*GL_SAMPLE_ALPHA_TO_COVERAGE*/,
00295     false /*GL_SAMPLE_ALPHA_TO_ONE*/,
00296     false /*GL_SAMPLE_COVERAGE*/
00297   };
00298 
00299   VL_COMPILE_TIME_CHECK( EN_EnableCount == sizeof(Is_Enable_Supported) / sizeof(Is_Enable_Supported[0]) );
00300   VL_COMPILE_TIME_CHECK( EN_EnableCount == sizeof(Translate_Enable) / sizeof(Translate_Enable[0]) );
00301   VL_COMPILE_TIME_CHECK( EN_EnableCount == sizeof(Translate_Enable_String) / sizeof(Translate_Enable_String[0]) );
00302 }
00303 //-----------------------------------------------------------------------------
00304 bool vl::initializeOpenGL()
00305 {
00306   Is_OpenGL_Initialized = false;
00307 
00308   // clear errors
00309   glGetError();
00310 
00311   // check OpenGL context is present
00312   if (glGetError() != GL_NO_ERROR)
00313     return false;
00314 
00315   // - - - OpenGL function pointers - - -
00316 
00317   // opengl function pointer initialization
00318   #if defined(VL_OPENGL)
00319     #define VL_GL_FUNCTION(TYPE, NAME) NAME = (TYPE)getGLProcAddress(#NAME);
00320     #include <vlGraphics/GL/GLFunctionList.hpp>
00321   #endif
00322 
00323   // opengl function pointer initialization
00324   #if defined(VL_OPENGL_ES1)
00325     #define VL_GL_FUNCTION(TYPE, NAME) NAME = (TYPE)getGLProcAddress(#NAME);
00326     #include <vlGraphics/GL/GLES1FunctionList.hpp>
00327   #endif
00328 
00329   // opengl function pointer initialization
00330   #if defined(VL_OPENGL_ES2)
00331     #define VL_GL_FUNCTION(TYPE, NAME) NAME = (TYPE)getGLProcAddress(#NAME);
00332     #include <vlGraphics/GL/GLES2FunctionList.hpp>
00333   #endif
00334 
00335   // - - - OpenGL versions - - -
00336 
00337   // GLES detect
00338   #if defined(VL_OPENGL_ES1)
00339     Has_GLES = Has_GLES_Version_1_1 = true;
00340   #endif
00341 
00342   #if defined(VL_OPENGL_ES2)
00343     Has_GLES = Has_GLES_Version_2_0 = true;
00344   #endif
00345 
00346   // GL versions
00347   // OpenGL ES returns "OpenGL ES-XX N.M"
00348   const char* version_string = (const char*)glGetString(GL_VERSION);
00349 
00350   // These stay zero for GLES
00351   const int vmaj = Has_GLES ? 0 : version_string[0] - '0';
00352   const int vmin = Has_GLES ? 0 : version_string[2] - '0';
00353 
00354   // Check fixed function pipeline
00355 #if defined(VL_OPENGL_ES2)
00356   Is_OpenGL_Core_Profile = false;
00357   Is_OpenGL_Forward_Compatible = false;
00358   Has_Fixed_Function_Pipeline = false;
00359 #elif defined(VL_OPENGL_ES1)
00360   Is_OpenGL_Core_Profile = false;
00361   Is_OpenGL_Forward_Compatible = false;
00362   Has_Fixed_Function_Pipeline = true;
00363 #else
00364   Is_OpenGL_Forward_Compatible = false;
00365   if( vmaj >= 3 )
00366   {
00367     int forward_compatible = 0;
00368     glGetIntegerv( GL_CONTEXT_FLAGS, &forward_compatible ); VL_CHECK_OGL();
00369     Is_OpenGL_Forward_Compatible = (forward_compatible & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) != 0;
00370   }
00371 
00372   Is_OpenGL_Core_Profile = false;
00373   const int version = vmaj*10 + vmin;
00374   if( version >= 32 )
00375   {
00376     // Valid for WGL and GLX
00377     #define CONTEXT_CORE_PROFILE_BIT          0x00000001
00378     #define CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
00379     #define CONTEXT_PROFILE_MASK              0x9126
00380 
00381     // Note: 
00382     // - This should be non-0 by when using wglCreateContextAttribs() and is == 0 when creating a GL context in the old way.
00383     // - Creating a context in the old way returns the highest compatible OpenGL version available thus the presence 
00384     //   of CONTEXT_COMPATIBILITY_PROFILE_BIT is not enough, we need to check the absence of CONTEXT_CORE_PROFILE_BIT
00385     int context_flags = 0;
00386     glGetIntegerv( CONTEXT_PROFILE_MASK, &context_flags ); VL_CHECK_OGL();
00387     Is_OpenGL_Core_Profile = (context_flags & CONTEXT_CORE_PROFILE_BIT) != 0;
00388   }
00389 
00390   Has_Fixed_Function_Pipeline = !Is_OpenGL_Forward_Compatible && !Is_OpenGL_Core_Profile;
00391 #endif
00392 
00393   Has_GL_Version_1_1 = (vmaj == 1 && vmin >= 1) || (vmaj > 1 && Has_Fixed_Function_Pipeline);
00394   Has_GL_Version_1_2 = (vmaj == 1 && vmin >= 2) || (vmaj > 1 && Has_Fixed_Function_Pipeline);
00395   Has_GL_Version_1_3 = (vmaj == 1 && vmin >= 3) || (vmaj > 1 && Has_Fixed_Function_Pipeline);
00396   Has_GL_Version_1_4 = (vmaj == 1 && vmin >= 4) || (vmaj > 1 && Has_Fixed_Function_Pipeline);
00397   Has_GL_Version_1_5 = (vmaj == 1 && vmin >= 5) || (vmaj > 1 && Has_Fixed_Function_Pipeline);
00398   Has_GL_Version_2_0 = (vmaj == 2 && vmin >= 0) || (vmaj > 2 && Has_Fixed_Function_Pipeline);
00399   Has_GL_Version_2_1 = (vmaj == 2 && vmin >= 1) || (vmaj > 2 && Has_Fixed_Function_Pipeline);
00400   Has_GL_Version_3_0 = (vmaj == 3 && vmin >= 0) || (vmaj > 3 && Has_Fixed_Function_Pipeline);
00401   Has_GL_Version_3_1 = (vmaj == 3 && vmin >= 1) || (vmaj > 3 && Has_Fixed_Function_Pipeline);
00402   Has_GL_Version_3_2 = (vmaj == 3 && vmin >= 2) || (vmaj > 3 && Has_Fixed_Function_Pipeline);
00403   Has_GL_Version_3_3 = (vmaj == 3 && vmin >= 3) || (vmaj > 3 && Has_Fixed_Function_Pipeline);
00404   Has_GL_Version_4_0 = (vmaj == 4 && vmin >= 0) || (vmaj > 4 && Has_Fixed_Function_Pipeline);
00405   Has_GL_Version_4_1 = (vmaj == 4 && vmin >= 1) || (vmaj > 4 && Has_Fixed_Function_Pipeline);
00406 
00407   // - - - Extension strings init - - -
00408 
00409   std::string extensions = getOpenGLExtensions();
00410 
00411   #define VL_EXTENSION(extension) Has_##extension = strstr(extensions.c_str(), #extension" ") != NULL;
00412     #include <vlGraphics/GL/GLExtensionList.hpp>
00413   #undef VL_EXTENSION
00414 
00415   #define VL_GLES_EXTENSION(extension) Has_##extension = strstr(extensions.c_str(), #extension" ") != NULL;
00416     #include <vlGraphics/GL/GLESExtensionList.hpp>
00417   #undef VL_GLES_EXTENSION
00418 
00419 #if defined(VL_OPENGL_ES1)
00420   // mic fixme
00421   // POWERVR emulator bugs: http://www.imgtec.com/forum/forum_posts.asp?TID=1379
00422   if (Has_GL_OES_texture_cube_map && glTexGenfOES == 0)
00423   {
00424     Has_GL_OES_texture_cube_map = false;
00425     Has_Cubemap_Textures = false;
00426     Log::error("GL_OES_texture_cube_map exposed but glTexGenfOES == NULL!\n"); /*VL_TRAP();*/
00427   }
00428   if(Has_GL_OES_blend_func_separate && glBlendFuncSeparateOES == 0)
00429   {
00430     Has_GL_OES_blend_func_separate = false;
00431     Log::error("GL_OES_blend_func_separate exposed but glBlendFuncSeparateOES == NULL!\n"); /*VL_TRAP();*/
00432   }
00433   if (Has_GL_OES_fixed_point && glAlphaFuncxOES == NULL)
00434   {
00435     Log::warning("GL_OES_fixed_point functions are not exposed with their OES suffix!\n");
00436   }
00437   if (Has_GL_OES_single_precision && glDepthRangefOES == NULL)
00438   {
00439     Log::warning("GL_OES_single_precision functions are not exposed with their OES suffix!\n");
00440   }
00441 #endif
00442 
00443   // - - - Helper defines - - - 
00444 
00445   // Note that GL extensions pertaining to deprecated features seem to be exposed under Core profiles even if they are not supported (like Has_GL_SGIS_generate_mipmap)
00446 
00447   Has_GLSL = Has_GL_ARB_shading_language_100 || Has_GL_Version_2_0 || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GLES_Version_2_0;
00448   Has_GLSL_120_Or_More = Has_GL_Version_2_1 || Has_GL_Version_3_0 || Has_GL_Version_4_0;
00449   Has_GLSL_130_Or_More = Has_GL_Version_3_0 || Has_GL_Version_4_0;
00450   Has_GLSL_140_Or_More = Has_GL_Version_3_1 || Has_GL_Version_4_0;
00451   Has_GLSL_150_Or_More = Has_GL_Version_3_2 || Has_GL_Version_4_0;
00452   Has_GLSL_330_Or_More = Has_GL_Version_3_3 || Has_GL_Version_4_0;
00453   Has_GLSL_400_Or_More = Has_GL_Version_4_0;
00454   Has_GLSL_410_Or_More = Has_GL_Version_4_1;
00455   Has_Geometry_Shader  = Has_GL_NV_geometry_shader4 || Has_GL_EXT_geometry_shader4 || Has_GL_ARB_geometry_shader4 || Has_GL_Version_3_2 || Has_GL_Version_4_0;
00456   Has_BufferObject = Has_GL_ARB_vertex_buffer_object || Has_GL_Version_1_5 || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GLES;
00457   Has_FBO = Has_GL_EXT_framebuffer_object || Has_GL_ARB_framebuffer_object || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GL_OES_framebuffer_object || Has_GLES_Version_2_0;
00458   Has_PBO = Has_GL_ARB_pixel_buffer_object || Has_GL_EXT_pixel_buffer_object || Has_GL_Version_2_1 || Has_GL_Version_3_0 || Has_GL_Version_4_0;
00459   // We only support GL_ANGLE_framebuffer_blit for GLES, see also:
00460   // http://www.khronos.org/registry/gles/extensions/IMG/IMG_multisampled_render_to_texture.txt
00461   // http://www.khronos.org/registry/gles/extensions/APPLE/APPLE_framebuffer_multisample.txt
00462   Has_FBO_Multisample = Has_GL_Version_4_0 || Has_GL_Version_3_0 || Has_GL_ARB_framebuffer_object || Has_GL_EXT_framebuffer_multisample || Has_GL_ANGLE_framebuffer_multisample;
00463   Has_Cubemap_Textures = Has_GL_ARB_texture_cube_map || Has_GL_Version_1_3 || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GL_OES_texture_cube_map || Has_GLES_Version_2_0;
00464   Has_Texture_Rectangle = Has_GL_ARB_texture_rectangle || Has_GL_NV_texture_rectangle || Has_GL_Version_3_1 || Has_GL_Version_4_0;
00465   Has_Texture_Array = Has_GL_EXT_texture_array || Has_GL_Version_3_0 || Has_GL_Version_4_0;
00466   Has_Texture_Buffer = Has_GL_ARB_texture_buffer_object || Has_GL_EXT_texture_buffer_object || Has_GL_Version_3_1 || Has_GL_Version_4_0;
00467   Has_Texture_Multisample = Has_GL_ARB_texture_multisample || Has_GL_Version_3_2 || Has_GL_Version_4_0;
00468   Has_Texture_3D = Has_GL_EXT_texture3D || Has_GL_Version_1_2 || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GL_OES_texture_3D;
00469   Has_Multitexture = Has_GL_ARB_multitexture || Has_GL_Version_1_3 || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GLES;
00470   Has_Primitive_Restart = Has_GL_Version_3_1 || Has_GL_Version_4_0;
00471   Has_Occlusion_Query = Has_GL_ARB_occlusion_query || Has_GL_Version_1_5 || Has_GL_Version_3_0 || Has_GL_Version_4_0;
00472   Has_Transform_Feedback = Has_GL_NV_transform_feedback || Has_GL_EXT_transform_feedback || Has_GL_Version_3_0 || Has_GL_Version_4_0;
00473   Has_glGenerateMipmaps = Has_GL_ARB_framebuffer_object || Has_GL_Version_3_0 || Has_GL_Version_4_0 || Has_GLES_Version_2_0;
00474   Has_GL_GENERATE_MIPMAP = (Has_GL_SGIS_generate_mipmap && Has_Fixed_Function_Pipeline) || Has_GL_Version_1_4 || Has_GLES_Version_1_1;
00475   Has_Point_Sprite = Has_GL_NV_point_sprite || Has_GL_ARB_point_sprite || Has_GLSL || Has_GLES_Version_1_1;
00476   Has_Base_Vertex = Has_GL_Version_3_2 || Has_GL_Version_4_0 || Has_GL_ARB_draw_elements_base_vertex;
00477   Has_Primitive_Instancing = Has_GL_Version_3_1 || Has_GL_Version_4_0 || Has_GL_ARB_draw_instanced || Has_GL_EXT_draw_instanced;
00478 
00479   // - - - Resolve supported enables - - -
00480 
00481   // Common ones
00482   Is_Enable_Supported[EN_BLEND]        = true;
00483   Is_Enable_Supported[EN_CULL_FACE]    = true;
00484   Is_Enable_Supported[EN_DEPTH_TEST]   = true;
00485   Is_Enable_Supported[EN_STENCIL_TEST] = true;
00486   Is_Enable_Supported[EN_DITHER]       = true;
00487   Is_Enable_Supported[EN_POLYGON_OFFSET_FILL]  = true;
00488   Is_Enable_Supported[EN_POLYGON_OFFSET_LINE]  = !Has_GLES;
00489   Is_Enable_Supported[EN_POLYGON_OFFSET_POINT] = !Has_GLES;
00490   Is_Enable_Supported[EN_COLOR_LOGIC_OP]       = !Has_GLES_Version_2_0;
00491   Is_Enable_Supported[EN_MULTISAMPLE]          = !Has_GLES_Version_2_0;
00492 
00493   // Smooth
00494   Is_Enable_Supported[EN_POINT_SMOOTH]   = Has_GL_Version_1_1||Has_GLES_Version_1_1;
00495   Is_Enable_Supported[EN_LINE_SMOOTH]    = !Has_GLES_Version_2_0;
00496   Is_Enable_Supported[EN_POLYGON_SMOOTH] = !Has_GLES;
00497 
00498   // Stipple
00499   Is_Enable_Supported[EN_LINE_STIPPLE]    = Has_GL_Version_1_1;
00500   Is_Enable_Supported[EN_POLYGON_STIPPLE] = Has_GL_Version_1_1;
00501 
00502   // Point sprites
00503   // Point sprites when !Has_Fixed_Function_Pipeline is considered always enabled but GL_POINT_SPRITE should not be called even if GL_OES_point_sprite, GL_ARB_point_sprite etc. are exposed!
00504   // Note that calling glIsEnabled() with the two below under a Core profile returns true for the same reason.
00505   Is_Enable_Supported[EN_POINT_SPRITE]       = (Has_GL_NV_point_sprite||Has_GL_ARB_point_sprite||Has_GL_Version_2_0||Has_GL_OES_point_sprite||Has_GLES_Version_1_1) && Has_Fixed_Function_Pipeline;
00506   Is_Enable_Supported[EN_PROGRAM_POINT_SIZE] = Has_GLSL && !Has_GLES_Version_2_0; // Only OpenGL ES 2 does not support glPointSize()/GL_POINT_SIZE
00507 
00508   // Fixed function pipeline
00509   Is_Enable_Supported[EN_ALPHA_TEST]     = Has_GL_Version_1_1||Has_GLES_Version_1_1;
00510   Is_Enable_Supported[EN_LIGHTING]       = Has_GL_Version_1_1||Has_GLES_Version_1_1;
00511   Is_Enable_Supported[EN_COLOR_SUM]      = Has_GL_Version_1_1;
00512   Is_Enable_Supported[EN_FOG]            = Has_GL_Version_1_1||Has_GLES_Version_1_1;
00513   Is_Enable_Supported[EN_NORMALIZE]      = Has_GL_Version_1_1||Has_GLES_Version_1_1;
00514   Is_Enable_Supported[EN_RESCALE_NORMAL] = Has_GL_Version_1_2||Has_GLES_Version_1_1;
00515 
00516   // Available only under OpenGL 2.x
00517   Is_Enable_Supported[EN_VERTEX_PROGRAM_TWO_SIDE]   = ((Has_GL_ARB_vertex_program||Has_GL_NV_vertex_program) && Has_GL_Version_1_1) || Has_GL_Version_2_0;
00518 
00519   // OpenGL 3.2
00520   Is_Enable_Supported[EN_TEXTURE_CUBE_MAP_SEAMLESS] = Has_GL_AMD_seamless_cubemap_per_texture||Has_GL_ARB_seamless_cube_map||Has_GL_Version_3_2||Has_GL_Version_4_0;
00521   
00522   // Clipping planes
00523   int max_clip_planes = 0;
00524   // OpenGL ES 2 is the only one without clipping planes!
00525   if (!Has_GLES_Version_2_0)
00526   {
00527     glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max_clip_planes); // GL_MAX_CLIP_DISTANCES == GL_MAX_CLIP_PLANES
00528   }
00529   Is_Enable_Supported[EN_CLIP_DISTANCE0] = max_clip_planes >= 1;
00530   Is_Enable_Supported[EN_CLIP_DISTANCE1] = max_clip_planes >= 2;
00531   Is_Enable_Supported[EN_CLIP_DISTANCE2] = max_clip_planes >= 3;
00532   Is_Enable_Supported[EN_CLIP_DISTANCE3] = max_clip_planes >= 4;
00533   Is_Enable_Supported[EN_CLIP_DISTANCE4] = max_clip_planes >= 5;
00534   Is_Enable_Supported[EN_CLIP_DISTANCE5] = max_clip_planes >= 6;
00535   Is_Enable_Supported[EN_CLIP_DISTANCE6] = max_clip_planes >= 7;
00536   Is_Enable_Supported[EN_CLIP_DISTANCE7] = max_clip_planes >= 8;
00537 
00538   // Multisampling
00539   Is_Enable_Supported[EN_SAMPLE_ALPHA_TO_COVERAGE] = Has_GL_Version_1_3||!Has_Fixed_Function_Pipeline||Has_GLES;
00540   Is_Enable_Supported[EN_SAMPLE_ALPHA_TO_ONE]      = Has_GL_Version_1_3||Has_GL_Version_3_0||Has_GL_Version_4_0||Has_GLES_Version_1_1;
00541   Is_Enable_Supported[EN_SAMPLE_COVERAGE]          = Has_GL_Version_1_3||!Has_Fixed_Function_Pipeline||Has_GLES;
00542 
00543 #ifndef NDEBUG
00544   // Enables management debug code
00545   VL_CHECK_OGL();
00546   bool got_error = false;
00547   for(int i=0; i<EN_EnableCount; ++i)
00548   {
00549     glDisable(Translate_Enable[i]); // glIsEnabled() for some reason is not reliable!
00550     bool supported = glGetError() == GL_NO_ERROR;
00551     if (supported != Is_Enable_Supported[i])
00552     {
00553       Log::error( Say("%s: capability %s supported! This is a harmless glitch either in your GL driver or in VL.\n") << Translate_Enable_String[i] << (supported? "*IS*" : "*IS NOT*") );
00554       got_error = true;
00555     }
00556   }
00557   if(got_error)
00558   {
00559     printf("OpenGL Version = %s\n", glGetString(GL_VERSION));
00560     #define PRINT_INFO(STRING) printf(#STRING" = %d\n", STRING?1:0)
00561     PRINT_INFO(Is_OpenGL_Core_Profile);
00562     PRINT_INFO(Is_OpenGL_Forward_Compatible);
00563     PRINT_INFO(Has_GL_Version_4_1);
00564     PRINT_INFO(Has_GL_Version_4_0);
00565     PRINT_INFO(Has_GL_Version_3_3);
00566     PRINT_INFO(Has_GL_Version_3_2);
00567     PRINT_INFO(Has_GL_Version_3_1);
00568     PRINT_INFO(Has_GL_Version_3_0);
00569     PRINT_INFO(Has_GL_Version_2_1);
00570     PRINT_INFO(Has_GL_Version_2_0);
00571     PRINT_INFO(Has_GL_Version_1_5);
00572     PRINT_INFO(Has_GL_Version_1_4);
00573     PRINT_INFO(Has_GL_Version_1_3);
00574     PRINT_INFO(Has_GL_Version_1_2);
00575     PRINT_INFO(Has_GL_Version_1_1);
00576     // VL_TRAP();
00577   }
00578 #endif
00579 
00580   VL_CHECK_OGL();
00581   return Is_OpenGL_Initialized = true;
00582 }
00583 //-----------------------------------------------------------------------------
00584 const char* vl::getGLErrorString(int err)
00585 {
00586   switch(err)
00587   {
00588   case GL_INVALID_ENUM:      return "Invalid enum";
00589   case GL_INVALID_VALUE:     return "Invalid value";
00590   case GL_INVALID_OPERATION: return "Invalid operation";
00591   case GL_STACK_OVERFLOW:    return "Stack overflow";
00592   case GL_STACK_UNDERFLOW:   return "Stack underflow";
00593   case GL_OUT_OF_MEMORY:     return "Out of memory";
00594   default:
00595     return "";
00596   }
00597 }
00598 //------------------------------------------------------------------------------
00599 int vl::glcheck(const char* file, int line)
00600 {
00601   unsigned int glerr = glGetError();
00602   // if an OpenGL context is available this must be clear!
00603   if ( glGetError() )
00604   {
00605     Log::bug( Say("%s:%n: NO OPENGL CONTEXT ACTIVE!\n") << file << line );
00606   }
00607   else
00608   if (glerr != GL_NO_ERROR)
00609   {
00610     String msg( (char*)getGLErrorString(glerr) );
00611     Log::bug( Say("glGetError() [%s:%n]: %s\n") << file << line << msg );
00612   }
00613   return glerr;
00614 }
00615 //------------------------------------------------------------------------------
00616 // vl::getGLProcAddress() implementation based on GLEW's
00617 //------------------------------------------------------------------------------
00618 #if defined(VL_OPENGL_ES1) || defined(VL_OPENGL_ES2)
00619 void* vl::getGLProcAddress(const char* name)
00620 {
00621   void* func = (void*)eglGetProcAddress(name);
00622   /*if (func)
00623     Log::warning( String().printf("+ %s\n", name) );
00624   else
00625     Log::error( String().printf("- %s\n", name) );*/
00626   return func;
00627 }
00628 #elif defined(VL_PLATFORM_WINDOWS)
00629 void* vl::getGLProcAddress(const char* name)
00630 {
00631   return (void*)wglGetProcAddress((LPCSTR)name);
00632 }
00633 #elif defined(VL_PLATFORM_LINUX)
00634 void* vl::getGLProcAddress(const char* name)
00635 {
00636   return (void*)(*glXGetProcAddress)((const GLubyte*)name);
00637 }
00638 #elif defined(__APPLE__)
00639 #include <stdlib.h>
00640 #include <string.h>
00641 #include <AvailabilityMacros.h>
00642 
00643 #ifdef MAC_OS_X_VERSION_10_3
00644 
00645 #include <dlfcn.h>
00646 
00647 void* vl::getGLProcAddress(const char* name)
00648 {
00649   static void* image = NULL;
00650   if (NULL == image)
00651   {
00652     image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
00653   }
00654   return image ? dlsym(image, name) : NULL;
00655 }
00656 
00657 #else
00658 
00659 #include <mach-o/dyld.h>
00660 
00661 void* vl::getGLProcAddress(const char*name)
00662 {
00663   static const struct mach_header* image = NULL;
00664   NSSymbol symbol;
00665   char* symbolName;
00666   if (NULL == image)
00667   {
00668     image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
00669   }
00670   /* prepend a '_' for the Unix C symbol mangling convention */
00671   symbolName = malloc(strlen(name) + 2);
00672   strcpy(symbolName+1, name);
00673   symbolName[0] = '_';
00674   symbol = NULL;
00675   /* if (NSIsSymbolNameDefined(symbolName))
00676      symbol = NSLookupAndBindSymbol(symbolName); */
00677   symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL;
00678   free(symbolName);
00679   return symbol ? NSAddressOfSymbol(symbol) : NULL;
00680 }
00681 
00682 #endif /* MAC_OS_X_VERSION_10_3 */
00683 
00684 /* __APPLE__ end */
00685 
00686 #elif defined(__sgi) || defined (__sun)
00687 
00688 #include <dlfcn.h>
00689 #include <stdio.h>
00690 #include <stdlib.h>
00691 
00692 void* vl::getGLProcAddress(const char* name)
00693 {
00694   static void* h = NULL;
00695   static void* gpa;
00696 
00697   if (h == NULL)
00698   {
00699     if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL;
00700     gpa = dlsym(h, "glXGetProcAddress");
00701   }
00702 
00703   if (gpa != NULL)
00704     return ((void*(*)(const GLubyte*))gpa)((const GLubyte*)name);
00705   else
00706     return dlsym(h, name);
00707 }
00708 
00709 /* __sgi || __sun end */
00710 
00711 #else
00712 void* vl::getGLProcAddress(const char* name)
00713 {
00714   return NULL;
00715 }
00716 #endif
00717 //------------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:38.
Permission is granted to use this page to write and publish articles regarding Visualization Library.