Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://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 //------------------------------------------------------------------------------