]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/COpenGLExtensionHandler.cpp
Revert "Fix: Listbox was sometimes sending EGET_LISTBOX_SELECTED_AGAIN instead of...
[irrlicht.git] / source / Irrlicht / COpenGLExtensionHandler.cpp
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 #include "COpenGLExtensionHandler.h"\r
6 \r
7 #ifdef _IRR_COMPILE_WITH_OPENGL_\r
8 \r
9 #include "irrString.h"\r
10 #include "SMaterial.h"\r
11 #include "fast_atof.h"\r
12 \r
13 namespace irr\r
14 {\r
15 namespace video\r
16 {\r
17 \r
18 bool COpenGLExtensionHandler::needsDSAFramebufferHack = true;\r
19 \r
20 COpenGLExtensionHandler::COpenGLExtensionHandler() :\r
21                 StencilBuffer(false), TextureCompressionExtension(false), MaxLights(1),\r
22                 MaxAnisotropy(1), MaxUserClipPlanes(0), MaxAuxBuffers(0), MaxIndices(65535),\r
23                 MaxTextureSize(1), MaxGeometryVerticesOut(0),\r
24                 MaxTextureLODBias(0.f), Version(0), ShaderLanguageVersion(0),\r
25                 OcclusionQuerySupport(false), IsAtiRadeonX(false)\r
26 #ifdef _IRR_OPENGL_USE_EXTPOINTER_\r
27         ,pGlActiveTexture(0)\r
28         ,pGlActiveTextureARB(0), pGlClientActiveTextureARB(0),\r
29         pGlGenProgramsARB(0), pGlGenProgramsNV(0),\r
30         pGlBindProgramARB(0), pGlBindProgramNV(0),\r
31         pGlDeleteProgramsARB(0), pGlDeleteProgramsNV(0),\r
32         pGlProgramStringARB(0), pGlLoadProgramNV(0),\r
33         pGlProgramLocalParameter4fvARB(0),\r
34         pGlCreateShaderObjectARB(0), pGlShaderSourceARB(0),\r
35         pGlCompileShaderARB(0), pGlCreateProgramObjectARB(0), pGlAttachObjectARB(0),\r
36         pGlLinkProgramARB(0), pGlUseProgramObjectARB(0), pGlDeleteObjectARB(0),\r
37         pGlCreateProgram(0), pGlUseProgram(0),\r
38         pGlDeleteProgram(0), pGlDeleteShader(0),\r
39         pGlGetAttachedObjectsARB(0), pGlGetAttachedShaders(0),\r
40         pGlCreateShader(0), pGlShaderSource(0), pGlCompileShader(0),\r
41         pGlAttachShader(0), pGlLinkProgram(0),\r
42         pGlGetInfoLogARB(0), pGlGetShaderInfoLog(0), pGlGetProgramInfoLog(0),\r
43         pGlGetObjectParameterivARB(0), pGlGetShaderiv(0), pGlGetProgramiv(0),\r
44         pGlGetUniformLocationARB(0), pGlGetUniformLocation(0),\r
45         pGlUniform1fvARB(0), pGlUniform2fvARB(0), pGlUniform3fvARB(0), pGlUniform4fvARB(0),\r
46         pGlUniform1ivARB(0), pGlUniform2ivARB(0), pGlUniform3ivARB(0), pGlUniform4ivARB(0),\r
47         pGlUniform1uiv(0), pGlUniform2uiv(0), pGlUniform3uiv(0), pGlUniform4uiv(0),\r
48         pGlUniformMatrix2fvARB(0), pGlUniformMatrix2x3fv(0), pGlUniformMatrix2x4fv(0),\r
49         pGlUniformMatrix3x2fv(0), pGlUniformMatrix3fvARB(0), pGlUniformMatrix3x4fv(0),\r
50         pGlUniformMatrix4x2fv(0), pGlUniformMatrix4x3fv(0), pGlUniformMatrix4fvARB(0),\r
51         pGlGetActiveUniformARB(0), pGlGetActiveUniform(0),\r
52         pGlPointParameterfARB(0), pGlPointParameterfvARB(0),\r
53         pGlStencilFuncSeparate(0), pGlStencilOpSeparate(0),\r
54         pGlStencilFuncSeparateATI(0), pGlStencilOpSeparateATI(0),\r
55         pGlCompressedTexImage2D(0), pGlCompressedTexSubImage2D(0),\r
56         // ARB framebuffer object\r
57         pGlBindFramebuffer(0), pGlDeleteFramebuffers(0), pGlGenFramebuffers(0),\r
58         pGlCheckFramebufferStatus(0), pGlFramebufferTexture2D(0),\r
59         pGlBindRenderbuffer(0), pGlDeleteRenderbuffers(0), pGlGenRenderbuffers(0),\r
60         pGlRenderbufferStorage(0), pGlFramebufferRenderbuffer(0), pGlGenerateMipmap(0),\r
61         // EXT framebuffer object\r
62         pGlBindFramebufferEXT(0), pGlDeleteFramebuffersEXT(0), pGlGenFramebuffersEXT(0),\r
63         pGlCheckFramebufferStatusEXT(0), pGlFramebufferTexture2DEXT(0),\r
64         pGlBindRenderbufferEXT(0), pGlDeleteRenderbuffersEXT(0), pGlGenRenderbuffersEXT(0),\r
65         pGlRenderbufferStorageEXT(0), pGlFramebufferRenderbufferEXT(0), pGlGenerateMipmapEXT(0),\r
66         pGlActiveStencilFaceEXT(0),\r
67         // MRTs\r
68         pGlDrawBuffersARB(0), pGlDrawBuffersATI(0),\r
69         pGlGenBuffersARB(0), pGlBindBufferARB(0), pGlBufferDataARB(0), pGlDeleteBuffersARB(0),\r
70         pGlBufferSubDataARB(0), pGlGetBufferSubDataARB(0), pGlMapBufferARB(0), pGlUnmapBufferARB(0),\r
71         pGlIsBufferARB(0), pGlGetBufferParameterivARB(0), pGlGetBufferPointervARB(0),\r
72         pGlProvokingVertexARB(0), pGlProvokingVertexEXT(0),\r
73         pGlProgramParameteriARB(0), pGlProgramParameteriEXT(0),\r
74         pGlGenQueriesARB(0), pGlDeleteQueriesARB(0), pGlIsQueryARB(0),\r
75         pGlBeginQueryARB(0), pGlEndQueryARB(0), pGlGetQueryivARB(0),\r
76         pGlGetQueryObjectivARB(0), pGlGetQueryObjectuivARB(0),\r
77         pGlGenOcclusionQueriesNV(0), pGlDeleteOcclusionQueriesNV(0),\r
78         pGlIsOcclusionQueryNV(0), pGlBeginOcclusionQueryNV(0),\r
79         pGlEndOcclusionQueryNV(0), pGlGetOcclusionQueryivNV(0),\r
80         pGlGetOcclusionQueryuivNV(0),\r
81         // Blend\r
82         pGlBlendFuncSeparateEXT(0), pGlBlendFuncSeparate(0),\r
83         pGlBlendEquationEXT(0), pGlBlendEquation(0), pGlBlendEquationSeparateEXT(0), pGlBlendEquationSeparate(0),\r
84         // Indexed\r
85         pGlEnableIndexedEXT(0), pGlDisableIndexedEXT(0),\r
86         pGlColorMaskIndexedEXT(0),\r
87         pGlBlendFuncIndexedAMD(0), pGlBlendFunciARB(0), pGlBlendFuncSeparateIndexedAMD(0), pGlBlendFuncSeparateiARB(0),\r
88         pGlBlendEquationIndexedAMD(0), pGlBlendEquationiARB(0), pGlBlendEquationSeparateIndexedAMD(0), pGlBlendEquationSeparateiARB(0),\r
89         // DSA\r
90     pGlTextureStorage2D(0), pGlTextureStorage3D(0), pGlTextureSubImage2D(0), pGlGetTextureImage(0), pGlNamedFramebufferTexture(0),\r
91     pGlTextureParameteri(0), pGlTextureParameterf(0), pGlTextureParameteriv(0), pGlTextureParameterfv(0),\r
92         pGlCreateTextures(0), pGlCreateFramebuffers(0), pGlBindTextures(0), pGlGenerateTextureMipmap(0),\r
93     // DSA with EXT or functions to simulate it\r
94         pGlTextureStorage2DEXT(0), pGlTexStorage2D(0), pGlTextureStorage3DEXT(0), pGlTexStorage3D(0), pGlTextureSubImage2DEXT(0), pGlGetTextureImageEXT(0),\r
95         pGlNamedFramebufferTextureEXT(0), pGlFramebufferTexture(0), pGlGenerateTextureMipmapEXT(0)\r
96 #if defined(GLX_SGI_swap_control)\r
97         ,pGlxSwapIntervalSGI(0)\r
98 #endif\r
99 #if defined(GLX_EXT_swap_control)\r
100         ,pGlxSwapIntervalEXT(0)\r
101 #endif\r
102 #if defined(WGL_EXT_swap_control)\r
103         ,pWglSwapIntervalEXT(0)\r
104 #endif\r
105 #if defined(GLX_MESA_swap_control)\r
106         ,pGlxSwapIntervalMESA(0)\r
107 #endif\r
108 #endif // _IRR_OPENGL_USE_EXTPOINTER_\r
109 {\r
110         for (u32 i=0; i<IRR_OpenGL_Feature_Count; ++i)\r
111                 FeatureAvailable[i]=false;\r
112         DimAliasedLine[0]=1.f;\r
113         DimAliasedLine[1]=1.f;\r
114         DimAliasedPoint[0]=1.f;\r
115         DimAliasedPoint[1]=1.f;\r
116         DimSmoothedLine[0]=1.f;\r
117         DimSmoothedLine[1]=1.f;\r
118         DimSmoothedPoint[0]=1.f;\r
119         DimSmoothedPoint[1]=1.f;\r
120 }\r
121 \r
122 \r
123 void COpenGLExtensionHandler::dump(ELOG_LEVEL logLevel) const\r
124 {\r
125         for (u32 i=0; i<IRR_OpenGL_Feature_Count; ++i)\r
126                 os::Printer::log(OpenGLFeatureStrings[i], FeatureAvailable[i]?" true":" false", logLevel);\r
127 }\r
128 \r
129 \r
130 void COpenGLExtensionHandler::dumpFramebufferFormats() const\r
131 {\r
132 #ifdef _IRR_WINDOWS_API_\r
133         HDC hdc=wglGetCurrentDC();\r
134         core::stringc wglExtensions;\r
135 #ifdef WGL_ARB_extensions_string\r
136         PFNWGLGETEXTENSIONSSTRINGARBPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");\r
137         if (irrGetExtensionsString)\r
138                 wglExtensions = irrGetExtensionsString(hdc);\r
139 #elif defined(WGL_EXT_extensions_string)\r
140         PFNWGLGETEXTENSIONSSTRINGEXTPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");\r
141         if (irrGetExtensionsString)\r
142                 wglExtensions = irrGetExtensionsString(hdc);\r
143 #endif\r
144         const bool pixel_format_supported = (wglExtensions.find("WGL_ARB_pixel_format") != -1);\r
145         const bool multi_sample_supported = ((wglExtensions.find("WGL_ARB_multisample") != -1) ||\r
146                 (wglExtensions.find("WGL_EXT_multisample") != -1) || (wglExtensions.find("WGL_3DFX_multisample") != -1) );\r
147 #ifdef _DEBUG\r
148         os::Printer::log("WGL_extensions", wglExtensions);\r
149 #endif\r
150 \r
151 #ifdef WGL_ARB_pixel_format\r
152         PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");\r
153         if (pixel_format_supported && wglChoosePixelFormat_ARB)\r
154         {\r
155                 // This value determines the number of samples used for antialiasing\r
156                 // My experience is that 8 does not show a big\r
157                 // improvement over 4, but 4 shows a big improvement\r
158                 // over 2.\r
159 \r
160                 PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribiv_ARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");\r
161                 if (wglGetPixelFormatAttribiv_ARB)\r
162                 {\r
163                         int vals[128];\r
164                         int atts[] = {\r
165                                 WGL_NUMBER_PIXEL_FORMATS_ARB,\r
166                                 WGL_DRAW_TO_BITMAP_ARB,\r
167                                 WGL_ACCELERATION_ARB,\r
168                                 WGL_NEED_PALETTE_ARB,\r
169                                 WGL_NEED_SYSTEM_PALETTE_ARB,\r
170                                 WGL_SWAP_LAYER_BUFFERS_ARB,\r
171                                 WGL_SWAP_METHOD_ARB,\r
172                                 WGL_NUMBER_OVERLAYS_ARB,\r
173                                 WGL_NUMBER_UNDERLAYS_ARB,\r
174                                 WGL_TRANSPARENT_ARB,\r
175                                 WGL_TRANSPARENT_RED_VALUE_ARB,\r
176                                 WGL_TRANSPARENT_GREEN_VALUE_ARB,\r
177                                 WGL_TRANSPARENT_BLUE_VALUE_ARB,\r
178                                 WGL_TRANSPARENT_ALPHA_VALUE_ARB,\r
179                                 WGL_TRANSPARENT_INDEX_VALUE_ARB,\r
180                                 WGL_SHARE_DEPTH_ARB,\r
181                                 WGL_SHARE_STENCIL_ARB,\r
182                                 WGL_SHARE_ACCUM_ARB,\r
183                                 WGL_SUPPORT_GDI_ARB,\r
184                                 WGL_SUPPORT_OPENGL_ARB,\r
185                                 WGL_DOUBLE_BUFFER_ARB,\r
186                                 WGL_STEREO_ARB,\r
187                                 WGL_PIXEL_TYPE_ARB,\r
188                                 WGL_COLOR_BITS_ARB,\r
189                                 WGL_RED_BITS_ARB,\r
190                                 WGL_RED_SHIFT_ARB,\r
191                                 WGL_GREEN_BITS_ARB,\r
192                                 WGL_GREEN_SHIFT_ARB,\r
193                                 WGL_BLUE_BITS_ARB,\r
194                                 WGL_BLUE_SHIFT_ARB,\r
195                                 WGL_ALPHA_BITS_ARB,\r
196                                 WGL_ALPHA_SHIFT_ARB,\r
197                                 WGL_ACCUM_BITS_ARB,\r
198                                 WGL_ACCUM_RED_BITS_ARB,\r
199                                 WGL_ACCUM_GREEN_BITS_ARB,\r
200                                 WGL_ACCUM_BLUE_BITS_ARB,\r
201                                 WGL_ACCUM_ALPHA_BITS_ARB,\r
202                                 WGL_DEPTH_BITS_ARB,\r
203                                 WGL_STENCIL_BITS_ARB,\r
204                                 WGL_AUX_BUFFERS_ARB\r
205 #ifdef WGL_ARB_render_texture\r
206                                 ,WGL_BIND_TO_TEXTURE_RGB_ARB //40\r
207                                 ,WGL_BIND_TO_TEXTURE_RGBA_ARB\r
208 #endif\r
209 #ifdef WGL_ARB_pbuffer\r
210                                 ,WGL_DRAW_TO_PBUFFER_ARB //42\r
211                                 ,WGL_MAX_PBUFFER_PIXELS_ARB\r
212                                 ,WGL_MAX_PBUFFER_WIDTH_ARB\r
213                                 ,WGL_MAX_PBUFFER_HEIGHT_ARB\r
214 #endif\r
215 #ifdef WGL_ARB_framebuffer_sRGB\r
216                                 ,WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB //46\r
217 #endif\r
218 #ifdef WGL_ARB_multisample\r
219                                 ,WGL_SAMPLES_ARB //47\r
220                                 ,WGL_SAMPLE_BUFFERS_ARB\r
221 #endif\r
222 #ifdef WGL_EXT_depth_float\r
223                                 ,WGL_DEPTH_FLOAT_EXT //49\r
224 #endif\r
225                                 ,0,0,0,0\r
226                         };\r
227                         size_t nums = sizeof(atts)/sizeof(int);\r
228                         const bool depth_float_supported= (wglExtensions.find("WGL_EXT_depth_float") != -1);\r
229                         if (!depth_float_supported)\r
230                         {\r
231                                 memmove(&atts[49], &atts[50], (nums-50)*sizeof(int));\r
232                                 nums -= 1;\r
233                         }\r
234                         if (!multi_sample_supported)\r
235                         {\r
236                                 memmove(&atts[47], &atts[49], (nums-49)*sizeof(int));\r
237                                 nums -= 2;\r
238                         }\r
239                         const bool framebuffer_sRGB_supported= (wglExtensions.find("WGL_ARB_framebuffer_sRGB") != -1);\r
240                         if (!framebuffer_sRGB_supported)\r
241                         {\r
242                                 memmove(&atts[46], &atts[47], (nums-47)*sizeof(int));\r
243                                 nums -= 1;\r
244                         }\r
245                         const bool pbuffer_supported = (wglExtensions.find("WGL_ARB_pbuffer") != -1);\r
246                         if (!pbuffer_supported)\r
247                         {\r
248                                 memmove(&atts[42], &atts[46], (nums-46)*sizeof(int));\r
249                                 nums -= 4;\r
250                         }\r
251                         const bool render_texture_supported = (wglExtensions.find("WGL_ARB_render_texture") != -1);\r
252                         if (!render_texture_supported)\r
253                         {\r
254                                 memmove(&atts[40], &atts[42], (nums-42)*sizeof(int));\r
255                                 nums -= 2;\r
256                         }\r
257                         wglGetPixelFormatAttribiv_ARB(hdc,0,0,1,atts,vals);\r
258                         const int count = vals[0];\r
259                         atts[0]=WGL_DRAW_TO_WINDOW_ARB;\r
260                         for (int i=1; i<count; ++i)\r
261                         {\r
262                                 memset(vals,0,sizeof(vals));\r
263 #define tmplog(x,y) os::Printer::log(x, core::stringc(y).c_str())\r
264                                 const BOOL res = wglGetPixelFormatAttribiv_ARB(hdc,i,0,(UINT)nums,atts,vals);\r
265                                 if (FALSE==res)\r
266                                         continue;\r
267                                 tmplog("Pixel format ",i);\r
268                                 u32 j=0;\r
269                                 tmplog("Draw to window " , vals[j]);\r
270                                 tmplog("Draw to bitmap " , vals[++j]);\r
271                                 ++j;\r
272                                 tmplog("Acceleration " , (vals[j]==WGL_NO_ACCELERATION_ARB?"No":\r
273                                         vals[j]==WGL_GENERIC_ACCELERATION_ARB?"Generic":vals[j]==WGL_FULL_ACCELERATION_ARB?"Full":"ERROR"));\r
274                                 tmplog("Need palette " , vals[++j]);\r
275                                 tmplog("Need system palette " , vals[++j]);\r
276                                 tmplog("Swap layer buffers " , vals[++j]);\r
277                                 ++j;\r
278                                 tmplog("Swap method " , (vals[j]==WGL_SWAP_EXCHANGE_ARB?"Exchange":\r
279                                         vals[j]==WGL_SWAP_COPY_ARB?"Copy":vals[j]==WGL_SWAP_UNDEFINED_ARB?"Undefined":"ERROR"));\r
280                                 tmplog("Number of overlays " , vals[++j]);\r
281                                 tmplog("Number of underlays " , vals[++j]);\r
282                                 tmplog("Transparent " , vals[++j]);\r
283                                 tmplog("Transparent red value " , vals[++j]);\r
284                                 tmplog("Transparent green value " , vals[++j]);\r
285                                 tmplog("Transparent blue value " , vals[++j]);\r
286                                 tmplog("Transparent alpha value " , vals[++j]);\r
287                                 tmplog("Transparent index value " , vals[++j]);\r
288                                 tmplog("Share depth " , vals[++j]);\r
289                                 tmplog("Share stencil " , vals[++j]);\r
290                                 tmplog("Share accum " , vals[++j]);\r
291                                 tmplog("Support GDI " , vals[++j]);\r
292                                 tmplog("Support OpenGL " , vals[++j]);\r
293                                 tmplog("Double Buffer " , vals[++j]);\r
294                                 tmplog("Stereo Buffer " , vals[++j]);\r
295                                 tmplog("Pixel type " , vals[++j]);\r
296                                 tmplog("Color bits" , vals[++j]);\r
297                                 tmplog("Red bits " , vals[++j]);\r
298                                 tmplog("Red shift " , vals[++j]);\r
299                                 tmplog("Green bits " , vals[++j]);\r
300                                 tmplog("Green shift " , vals[++j]);\r
301                                 tmplog("Blue bits " , vals[++j]);\r
302                                 tmplog("Blue shift " , vals[++j]);\r
303                                 tmplog("Alpha bits " , vals[++j]);\r
304                                 tmplog("Alpha Shift " , vals[++j]);\r
305                                 tmplog("Accum bits " , vals[++j]);\r
306                                 tmplog("Accum red bits " , vals[++j]);\r
307                                 tmplog("Accum green bits " , vals[++j]);\r
308                                 tmplog("Accum blue bits " , vals[++j]);\r
309                                 tmplog("Accum alpha bits " , vals[++j]);\r
310                                 tmplog("Depth bits " , vals[++j]);\r
311                                 tmplog("Stencil bits " , vals[++j]);\r
312                                 tmplog("Aux buffers " , vals[++j]);\r
313                                 if (render_texture_supported)\r
314                                 {\r
315                                         tmplog("Bind to texture RGB" , vals[++j]);\r
316                                         tmplog("Bind to texture RGBA" , vals[++j]);\r
317                                 }\r
318                                 if (pbuffer_supported)\r
319                                 {\r
320                                         tmplog("Draw to pbuffer" , vals[++j]);\r
321                                         tmplog("Max pbuffer pixels " , vals[++j]);\r
322                                         tmplog("Max pbuffer width" , vals[++j]);\r
323                                         tmplog("Max pbuffer height" , vals[++j]);\r
324                                 }\r
325                                 if (framebuffer_sRGB_supported)\r
326                                         tmplog("Framebuffer sRBG capable" , vals[++j]);\r
327                                 if (multi_sample_supported)\r
328                                 {\r
329                                         tmplog("Samples " , vals[++j]);\r
330                                         tmplog("Sample buffers " , vals[++j]);\r
331                                 }\r
332                                 if (depth_float_supported)\r
333                                         tmplog("Depth float" , vals[++j]);\r
334 #undef tmplog\r
335                         }\r
336                 }\r
337         }\r
338 #endif\r
339 #elif defined(IRR_LINUX_DEVICE)\r
340 #endif\r
341 }\r
342 \r
343 \r
344 void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)\r
345 {\r
346         const f32 ogl_ver = core::fast_atof(reinterpret_cast<const c8*>(glGetString(GL_VERSION)));\r
347         Version = static_cast<u16>(core::floor32(ogl_ver)*100+core::round32(core::fract(ogl_ver)*10.0f));\r
348         if ( Version >= 102)\r
349                 os::Printer::log("OpenGL driver version is 1.2 or better.", ELL_INFORMATION);\r
350         else\r
351                 os::Printer::log("OpenGL driver version is not 1.2 or better.", ELL_WARNING);\r
352 \r
353         {\r
354                 const char* t = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));\r
355                 size_t len = 0;\r
356                 c8 *str = 0;\r
357                 if (t)\r
358                 {\r
359                         len = strlen(t);\r
360                         str = new c8[len+1];\r
361                 }\r
362                 c8* p = str;\r
363 \r
364                 for (size_t i=0; i<len; ++i)\r
365                 {\r
366                         str[i] = static_cast<char>(t[i]);\r
367 \r
368                         if (str[i] == ' ')\r
369                         {\r
370                                 str[i] = 0;\r
371                                 for (u32 j=0; j<IRR_OpenGL_Feature_Count; ++j)\r
372                                 {\r
373                                         if (!strcmp(OpenGLFeatureStrings[j], p))\r
374                                         {\r
375                                                 FeatureAvailable[j] = true;\r
376                                                 break;\r
377                                         }\r
378                                 }\r
379 \r
380                                 p = p + strlen(p) + 1;\r
381                         }\r
382                 }\r
383 \r
384                 delete [] str;\r
385         }\r
386 \r
387         TextureCompressionExtension = FeatureAvailable[IRR_ARB_texture_compression];\r
388         StencilBuffer=stencilBuffer;\r
389 \r
390         const char* renderer = (const char*)glGetString(GL_RENDERER);\r
391         if ( renderer )\r
392         {\r
393                 IsAtiRadeonX = (strncmp(renderer, "ATI RADEON X", 12) == 0) || (strncmp(renderer, "ATI MOBILITY RADEON X", 21) == 0);\r
394         }\r
395 \r
396 #ifdef _IRR_OPENGL_USE_EXTPOINTER_\r
397 #ifdef _IRR_WINDOWS_API_\r
398         #define IRR_OGL_LOAD_EXTENSION(x) wglGetProcAddress(reinterpret_cast<const char*>(x))\r
399 #elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && !defined(_IRR_COMPILE_WITH_X11_DEVICE_)\r
400         #define IRR_OGL_LOAD_EXTENSION(x) SDL_GL_GetProcAddress(reinterpret_cast<const char*>(x))\r
401 #else\r
402         // Accessing the correct function is quite complex\r
403         // All libraries should support the ARB version, however\r
404         // since GLX 1.4 the non-ARB version is the official one\r
405         // So we have to check the runtime environment and\r
406         // choose the proper symbol\r
407         // In case you still have problems please enable the\r
408         // next line by uncommenting it\r
409         // #define _IRR_GETPROCADDRESS_WORKAROUND_\r
410 \r
411         #ifndef _IRR_GETPROCADDRESS_WORKAROUND_\r
412         __GLXextFuncPtr (*IRR_OGL_LOAD_EXTENSION_FUNCP)(const GLubyte*)=0;\r
413         #ifdef GLX_VERSION_1_4\r
414                 int major=0,minor=0;\r
415                 if (glXGetCurrentDisplay())\r
416                         glXQueryVersion(glXGetCurrentDisplay(), &major, &minor);\r
417                 if ((major>1) || (minor>3))\r
418                         IRR_OGL_LOAD_EXTENSION_FUNCP=glXGetProcAddress;\r
419                 else\r
420         #endif\r
421                         IRR_OGL_LOAD_EXTENSION_FUNCP=glXGetProcAddressARB;\r
422                 #define IRR_OGL_LOAD_EXTENSION(X) IRR_OGL_LOAD_EXTENSION_FUNCP(reinterpret_cast<const GLubyte*>(X))\r
423         #else\r
424                 #define IRR_OGL_LOAD_EXTENSION(X) glXGetProcAddressARB(reinterpret_cast<const GLubyte*>(X))\r
425         #endif // workaround\r
426 #endif // Windows, SDL, or Linux\r
427 \r
428         // get multitexturing function pointers\r
429         pGlActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) IRR_OGL_LOAD_EXTENSION("glActiveTextureARB");\r
430         pGlClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) IRR_OGL_LOAD_EXTENSION("glClientActiveTextureARB");\r
431 \r
432         // get fragment and vertex program function pointers\r
433         pGlGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) IRR_OGL_LOAD_EXTENSION("glGenProgramsARB");\r
434         pGlGenProgramsNV = (PFNGLGENPROGRAMSNVPROC) IRR_OGL_LOAD_EXTENSION("glGenProgramsNV");\r
435         pGlBindProgramARB = (PFNGLBINDPROGRAMARBPROC) IRR_OGL_LOAD_EXTENSION("glBindProgramARB");\r
436         pGlBindProgramNV = (PFNGLBINDPROGRAMNVPROC) IRR_OGL_LOAD_EXTENSION("glBindProgramNV");\r
437         pGlProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) IRR_OGL_LOAD_EXTENSION("glProgramStringARB");\r
438         pGlLoadProgramNV = (PFNGLLOADPROGRAMNVPROC) IRR_OGL_LOAD_EXTENSION("glLoadProgramNV");\r
439         pGlDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) IRR_OGL_LOAD_EXTENSION("glDeleteProgramsARB");\r
440         pGlDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC) IRR_OGL_LOAD_EXTENSION("glDeleteProgramsNV");\r
441         pGlProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) IRR_OGL_LOAD_EXTENSION("glProgramLocalParameter4fvARB");\r
442         pGlCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glCreateShaderObjectARB");\r
443         pGlCreateShader = (PFNGLCREATESHADERPROC) IRR_OGL_LOAD_EXTENSION("glCreateShader");\r
444         pGlShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) IRR_OGL_LOAD_EXTENSION("glShaderSourceARB");\r
445         pGlShaderSource = (PFNGLSHADERSOURCEPROC) IRR_OGL_LOAD_EXTENSION("glShaderSource");\r
446         pGlCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) IRR_OGL_LOAD_EXTENSION("glCompileShaderARB");\r
447         pGlCompileShader = (PFNGLCOMPILESHADERPROC) IRR_OGL_LOAD_EXTENSION("glCompileShader");\r
448         pGlCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glCreateProgramObjectARB");\r
449         pGlCreateProgram = (PFNGLCREATEPROGRAMPROC) IRR_OGL_LOAD_EXTENSION("glCreateProgram");\r
450         pGlAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glAttachObjectARB");\r
451         pGlAttachShader = (PFNGLATTACHSHADERPROC) IRR_OGL_LOAD_EXTENSION("glAttachShader");\r
452         pGlLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) IRR_OGL_LOAD_EXTENSION("glLinkProgramARB");\r
453         pGlLinkProgram = (PFNGLLINKPROGRAMPROC) IRR_OGL_LOAD_EXTENSION("glLinkProgram");\r
454         pGlUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glUseProgramObjectARB");\r
455         pGlUseProgram = (PFNGLUSEPROGRAMPROC) IRR_OGL_LOAD_EXTENSION("glUseProgram");\r
456         pGlDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glDeleteObjectARB");\r
457         pGlDeleteProgram = (PFNGLDELETEPROGRAMPROC) IRR_OGL_LOAD_EXTENSION("glDeleteProgram");\r
458         pGlDeleteShader = (PFNGLDELETESHADERPROC) IRR_OGL_LOAD_EXTENSION("glDeleteShader");\r
459         pGlGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) IRR_OGL_LOAD_EXTENSION("glGetAttachedShaders");\r
460         pGlGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) IRR_OGL_LOAD_EXTENSION("glGetAttachedObjectsARB");\r
461         pGlGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) IRR_OGL_LOAD_EXTENSION("glGetInfoLogARB");\r
462         pGlGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog");\r
463         pGlGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog");\r
464         pGlGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetObjectParameterivARB");\r
465         pGlGetShaderiv = (PFNGLGETSHADERIVPROC) IRR_OGL_LOAD_EXTENSION("glGetShaderiv");\r
466         pGlGetProgramiv = (PFNGLGETPROGRAMIVPROC) IRR_OGL_LOAD_EXTENSION("glGetProgramiv");\r
467         pGlGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) IRR_OGL_LOAD_EXTENSION("glGetUniformLocationARB");\r
468         pGlGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) IRR_OGL_LOAD_EXTENSION("glGetUniformLocation");\r
469         pGlUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform1fvARB");\r
470         pGlUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform2fvARB");\r
471         pGlUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform3fvARB");\r
472         pGlUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform4fvARB");\r
473         pGlUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform1ivARB");\r
474         pGlUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform2ivARB");\r
475         pGlUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform3ivARB");\r
476         pGlUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform4ivARB");\r
477         pGlUniform1uiv = (PFNGLUNIFORM1UIVPROC) IRR_OGL_LOAD_EXTENSION("glUniform1uiv");\r
478         pGlUniform2uiv = (PFNGLUNIFORM2UIVPROC) IRR_OGL_LOAD_EXTENSION("glUniform2uiv");\r
479         pGlUniform3uiv = (PFNGLUNIFORM3UIVPROC) IRR_OGL_LOAD_EXTENSION("glUniform3uiv");\r
480         pGlUniform4uiv = (PFNGLUNIFORM4UIVPROC) IRR_OGL_LOAD_EXTENSION("glUniform4uiv");\r
481         pGlUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix2fvARB");\r
482         pGlUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix2x3fv");\r
483         pGlUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix2x4fv");\r
484         pGlUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix3x2fv");\r
485         pGlUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix3fvARB");\r
486         pGlUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix3x4fv");\r
487         pGlUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4x2fv");\r
488         pGlUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4x3fv");\r
489         pGlUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fvARB");\r
490         pGlGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) IRR_OGL_LOAD_EXTENSION("glGetActiveUniformARB");\r
491         pGlGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) IRR_OGL_LOAD_EXTENSION("glGetActiveUniform");\r
492 \r
493         // get point parameter extension\r
494         pGlPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC) IRR_OGL_LOAD_EXTENSION("glPointParameterfARB");\r
495         pGlPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC) IRR_OGL_LOAD_EXTENSION("glPointParameterfvARB");\r
496 \r
497         // get stencil extension\r
498         pGlStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) IRR_OGL_LOAD_EXTENSION("glStencilFuncSeparate");\r
499         pGlStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) IRR_OGL_LOAD_EXTENSION("glStencilOpSeparate");\r
500         pGlStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC) IRR_OGL_LOAD_EXTENSION("glStencilFuncSeparateATI");\r
501         pGlStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC) IRR_OGL_LOAD_EXTENSION("glStencilOpSeparateATI");\r
502 \r
503         // compressed textures\r
504         pGlCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");\r
505         pGlCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION("glCompressedTexSubImage2D");\r
506 \r
507         // ARB FrameBufferObjects\r
508         pGlBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glBindFramebuffer");\r
509         pGlDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glDeleteFramebuffers");\r
510         pGlGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glGenFramebuffers");\r
511         pGlCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatus");\r
512         pGlFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferTexture2D");\r
513         pGlBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glBindRenderbuffer");\r
514         pGlDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glDeleteRenderbuffers");\r
515         pGlGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glGenRenderbuffers");\r
516         pGlRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) IRR_OGL_LOAD_EXTENSION("glRenderbufferStorage");\r
517         pGlFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferRenderbuffer");\r
518         pGlGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) IRR_OGL_LOAD_EXTENSION("glGenerateMipmap");\r
519 \r
520         // EXT FrameBufferObjects\r
521         pGlBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION("glBindFramebufferEXT");\r
522         pGlDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glDeleteFramebuffersEXT");\r
523         pGlGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glGenFramebuffersEXT");\r
524         pGlCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatusEXT");\r
525         pGlFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferTexture2DEXT");\r
526         pGlBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION("glBindRenderbufferEXT");\r
527         pGlDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glDeleteRenderbuffersEXT");\r
528         pGlGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glGenRenderbuffersEXT");\r
529         pGlRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) IRR_OGL_LOAD_EXTENSION("glRenderbufferStorageEXT");\r
530         pGlFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferRenderbufferEXT");\r
531         pGlGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) IRR_OGL_LOAD_EXTENSION("glGenerateMipmapEXT");\r
532         pGlDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) IRR_OGL_LOAD_EXTENSION("glDrawBuffersARB");\r
533         pGlDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC) IRR_OGL_LOAD_EXTENSION("glDrawBuffersATI");\r
534 \r
535         // get vertex buffer extension\r
536         pGlGenBuffersARB = (PFNGLGENBUFFERSARBPROC) IRR_OGL_LOAD_EXTENSION("glGenBuffersARB");\r
537         pGlBindBufferARB = (PFNGLBINDBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION("glBindBufferARB");\r
538         pGlBufferDataARB = (PFNGLBUFFERDATAARBPROC) IRR_OGL_LOAD_EXTENSION("glBufferDataARB");\r
539         pGlDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) IRR_OGL_LOAD_EXTENSION("glDeleteBuffersARB");\r
540         pGlBufferSubDataARB= (PFNGLBUFFERSUBDATAARBPROC) IRR_OGL_LOAD_EXTENSION("glBufferSubDataARB");\r
541         pGlGetBufferSubDataARB= (PFNGLGETBUFFERSUBDATAARBPROC)IRR_OGL_LOAD_EXTENSION("glGetBufferSubDataARB");\r
542         pGlMapBufferARB= (PFNGLMAPBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION("glMapBufferARB");\r
543         pGlUnmapBufferARB= (PFNGLUNMAPBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION("glUnmapBufferARB");\r
544         pGlIsBufferARB= (PFNGLISBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION("glIsBufferARB");\r
545         pGlGetBufferParameterivARB= (PFNGLGETBUFFERPARAMETERIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetBufferParameterivARB");\r
546         pGlGetBufferPointervARB= (PFNGLGETBUFFERPOINTERVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetBufferPointervARB");\r
547         pGlProvokingVertexARB= (PFNGLPROVOKINGVERTEXPROC) IRR_OGL_LOAD_EXTENSION("glProvokingVertex");\r
548         pGlProvokingVertexEXT= (PFNGLPROVOKINGVERTEXEXTPROC) IRR_OGL_LOAD_EXTENSION("glProvokingVertexEXT");\r
549         pGlProgramParameteriARB= (PFNGLPROGRAMPARAMETERIARBPROC) IRR_OGL_LOAD_EXTENSION("glProgramParameteriARB");\r
550         pGlProgramParameteriEXT= (PFNGLPROGRAMPARAMETERIEXTPROC) IRR_OGL_LOAD_EXTENSION("glProgramParameteriEXT");\r
551 \r
552         // occlusion query\r
553         pGlGenQueriesARB = (PFNGLGENQUERIESARBPROC) IRR_OGL_LOAD_EXTENSION("glGenQueriesARB");\r
554         pGlDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC) IRR_OGL_LOAD_EXTENSION("glDeleteQueriesARB");\r
555         pGlIsQueryARB = (PFNGLISQUERYARBPROC) IRR_OGL_LOAD_EXTENSION("glIsQueryARB");\r
556         pGlBeginQueryARB = (PFNGLBEGINQUERYARBPROC) IRR_OGL_LOAD_EXTENSION("glBeginQueryARB");\r
557         pGlEndQueryARB = (PFNGLENDQUERYARBPROC) IRR_OGL_LOAD_EXTENSION("glEndQueryARB");\r
558         pGlGetQueryivARB = (PFNGLGETQUERYIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetQueryivARB");\r
559         pGlGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetQueryObjectivARB");\r
560         pGlGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetQueryObjectuivARB");\r
561         pGlGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC) IRR_OGL_LOAD_EXTENSION("glGenOcclusionQueriesNV");\r
562         pGlDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC) IRR_OGL_LOAD_EXTENSION("glDeleteOcclusionQueriesNV");\r
563         pGlIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC) IRR_OGL_LOAD_EXTENSION("glIsOcclusionQueryNV");\r
564         pGlBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC) IRR_OGL_LOAD_EXTENSION("glBeginOcclusionQueryNV");\r
565         pGlEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC) IRR_OGL_LOAD_EXTENSION("glEndOcclusionQueryNV");\r
566         pGlGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC) IRR_OGL_LOAD_EXTENSION("glGetOcclusionQueryivNV");\r
567         pGlGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC) IRR_OGL_LOAD_EXTENSION("glGetOcclusionQueryuivNV");\r
568 \r
569         // blend\r
570         pGlBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) IRR_OGL_LOAD_EXTENSION("glBlendFuncSeparateEXT");\r
571         pGlBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) IRR_OGL_LOAD_EXTENSION("glBlendFuncSeparate");\r
572         pGlBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationEXT");\r
573         pGlBlendEquation = (PFNGLBLENDEQUATIONPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquation");\r
574         pGlBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationSeparateEXT");\r
575         pGlBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationSeparate");\r
576 \r
577         // indexed\r
578         pGlEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC) IRR_OGL_LOAD_EXTENSION("glEnableIndexedEXT");\r
579         pGlDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC) IRR_OGL_LOAD_EXTENSION("glDisableIndexedEXT");\r
580         pGlColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC) IRR_OGL_LOAD_EXTENSION("glColorMaskIndexedEXT");\r
581         pGlBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC) IRR_OGL_LOAD_EXTENSION("glBlendFuncIndexedAMD");\r
582         pGlBlendFunciARB = (PFNGLBLENDFUNCIPROC) IRR_OGL_LOAD_EXTENSION("glBlendFunciARB");\r
583         pGlBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) IRR_OGL_LOAD_EXTENSION("glBlendFuncSeparateIndexedAMD");\r
584         pGlBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIPROC) IRR_OGL_LOAD_EXTENSION("glBlendFuncSeparateiARB");\r
585         pGlBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationIndexedAMD");\r
586         pGlBlendEquationiARB = (PFNGLBLENDEQUATIONIPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationiARB");\r
587         pGlBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationSeparateIndexedAMD");\r
588         pGlBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationSeparateiARB");\r
589 \r
590     pGlTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) IRR_OGL_LOAD_EXTENSION("glTextureStorage2D");\r
591     pGlTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) IRR_OGL_LOAD_EXTENSION("glTextureStorage3D");\r
592         pGlTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glTextureSubImage2D");\r
593         pGlGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetTextureImage");\r
594     pGlNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) IRR_OGL_LOAD_EXTENSION("glNamedFramebufferTexture");\r
595     pGlTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) IRR_OGL_LOAD_EXTENSION("glTextureParameteri");\r
596         pGlTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC)IRR_OGL_LOAD_EXTENSION("glTextureParameterf");\r
597         pGlTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC)IRR_OGL_LOAD_EXTENSION("glTextureParameteriv");\r
598         pGlTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC)IRR_OGL_LOAD_EXTENSION("glTextureParameterfv");\r
599 \r
600     pGlCreateTextures = (PFNGLCREATETEXTURESPROC) IRR_OGL_LOAD_EXTENSION("glCreateTextures");\r
601     pGlCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glCreateFramebuffers");\r
602     pGlBindTextures = (PFNGLBINDTEXTURESPROC) IRR_OGL_LOAD_EXTENSION("glBindTextures");\r
603     pGlGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) IRR_OGL_LOAD_EXTENSION("glGenerateTextureMipmap");\r
604     //==============================\r
605     pGlTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC)IRR_OGL_LOAD_EXTENSION("glTextureStorage2DEXT");\r
606     pGlTexStorage2D = (PFNGLTEXSTORAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage2D");\r
607     pGlTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC)IRR_OGL_LOAD_EXTENSION("glTextureStorage3DEXT");\r
608     pGlTexStorage3D = (PFNGLTEXSTORAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage3D");\r
609         pGlTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC)IRR_OGL_LOAD_EXTENSION("glTextureSubImage2DEXT");\r
610         pGlGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC)IRR_OGL_LOAD_EXTENSION("glGetTextureImageEXT");\r
611     pGlNamedFramebufferTextureEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)IRR_OGL_LOAD_EXTENSION("glNamedFramebufferTextureEXT");\r
612     pGlFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture");\r
613     pGlActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture");\r
614     pGlGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC) IRR_OGL_LOAD_EXTENSION("glGenerateTextureMipmapEXT");\r
615 \r
616         // get vsync extension\r
617         #if defined(WGL_EXT_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_)\r
618                 pWglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) IRR_OGL_LOAD_EXTENSION("wglSwapIntervalEXT");\r
619         #endif\r
620         #if defined(GLX_SGI_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_)\r
621                 pGlxSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalSGI");\r
622         #endif\r
623         #if defined(GLX_EXT_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_)\r
624                 pGlxSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalEXT");\r
625         #endif\r
626         #if defined(GLX_MESA_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_)\r
627                 pGlxSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalMESA");\r
628         #endif\r
629 #endif // use extension pointer\r
630 \r
631         GLint num=0;\r
632         // set some properties\r
633 #if defined(GL_ARB_multitexture) || defined(GL_VERSION_1_3)\r
634         if (Version>102 || FeatureAvailable[IRR_ARB_multitexture])\r
635         {\r
636 #if defined(GL_MAX_TEXTURE_UNITS)\r
637                 glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num);\r
638 #elif defined(GL_MAX_TEXTURE_UNITS_ARB)\r
639                 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num);\r
640 #endif\r
641                 Feature.MaxTextureUnits=static_cast<u8>(num);   // MULTITEXTURING (fixed function pipeline texture units)\r
642         }\r
643 #endif\r
644 #if defined(GL_ARB_vertex_shader) || defined(GL_VERSION_2_0)\r
645         if (Version>=200 || FeatureAvailable[IRR_ARB_vertex_shader])\r
646         {\r
647                 num=0;\r
648 #if defined(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)\r
649                 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &num);\r
650 #elif defined(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB)\r
651                 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &num);\r
652 #endif\r
653                 Feature.MaxTextureUnits =core::max_(Feature.MaxTextureUnits,static_cast<u8>(num));\r
654         }\r
655 #endif\r
656         glGetIntegerv(GL_MAX_LIGHTS, &num);\r
657         MaxLights=static_cast<u8>(num);\r
658 #ifdef GL_EXT_texture_filter_anisotropic\r
659         if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic])\r
660         {\r
661                 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &num);\r
662                 MaxAnisotropy=static_cast<u8>(num);\r
663         }\r
664 #endif\r
665 #ifdef GL_VERSION_1_2\r
666         if (Version>101)\r
667         {\r
668                 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &num);\r
669                 MaxIndices=num;\r
670         }\r
671 #endif\r
672         glGetIntegerv(GL_MAX_TEXTURE_SIZE, &num);\r
673         MaxTextureSize=static_cast<u32>(num);\r
674         if (queryFeature(EVDF_GEOMETRY_SHADER))\r
675         {\r
676 #if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_shader4)\r
677                 glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &num);\r
678                 MaxGeometryVerticesOut=static_cast<u32>(num);\r
679 #elif defined(GL_NV_geometry_program4)\r
680                 extGlGetProgramiv(GEOMETRY_PROGRAM_NV, GL_MAX_PROGRAM_OUTPUT_VERTICES_NV, &num);\r
681                 MaxGeometryVerticesOut=static_cast<u32>(num);\r
682 #endif\r
683         }\r
684 #ifdef GL_EXT_texture_lod_bias\r
685         if (FeatureAvailable[IRR_EXT_texture_lod_bias])\r
686                 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &MaxTextureLODBias);\r
687 #endif\r
688         glGetIntegerv(GL_MAX_CLIP_PLANES, &num);\r
689         MaxUserClipPlanes=static_cast<u8>(num);\r
690         glGetIntegerv(GL_AUX_BUFFERS, &num);\r
691         MaxAuxBuffers=static_cast<u8>(num);\r
692 #ifdef GL_ARB_draw_buffers\r
693         if (FeatureAvailable[IRR_ARB_draw_buffers])\r
694         {\r
695                 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &num);\r
696                 Feature.MultipleRenderTarget = static_cast<u8>(num);\r
697         }\r
698 #endif\r
699 #if defined(GL_ATI_draw_buffers)\r
700 #ifdef GL_ARB_draw_buffers\r
701         else\r
702 #endif\r
703         if (FeatureAvailable[IRR_ATI_draw_buffers])\r
704         {\r
705                 glGetIntegerv(GL_MAX_DRAW_BUFFERS_ATI, &num);\r
706                 Feature.MultipleRenderTarget = static_cast<u8>(num);\r
707         }\r
708 #endif\r
709 #ifdef GL_ARB_framebuffer_object\r
710         if (FeatureAvailable[IRR_ARB_framebuffer_object])\r
711         {\r
712                 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &num);\r
713                 Feature.ColorAttachment = static_cast<u8>(num);\r
714         }\r
715 #endif\r
716 #if defined(GL_EXT_framebuffer_object)\r
717 #ifdef GL_ARB_framebuffer_object\r
718         else\r
719 #endif\r
720                 if (FeatureAvailable[IRR_EXT_framebuffer_object])\r
721                 {\r
722                         glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &num);\r
723                         Feature.ColorAttachment = static_cast<u8>(num);\r
724                 }\r
725 #endif\r
726 \r
727         glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine);\r
728         glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, DimAliasedPoint);\r
729         glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, DimSmoothedLine);\r
730         glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, DimSmoothedPoint);\r
731 #if defined(GL_ARB_shading_language_100) || defined (GL_VERSION_2_0)\r
732         if (FeatureAvailable[IRR_ARB_shading_language_100] || Version>=200)\r
733         {\r
734                 glGetError(); // clean error buffer\r
735 #ifdef GL_SHADING_LANGUAGE_VERSION\r
736                 const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);\r
737 #else\r
738                 const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);\r
739 #endif\r
740                 if (glGetError() == GL_INVALID_ENUM)\r
741                         ShaderLanguageVersion = 100;\r
742                 else\r
743                 {\r
744                         const f32 sl_ver = core::fast_atof(reinterpret_cast<const c8*>(shaderVersion));\r
745                         ShaderLanguageVersion = static_cast<u16>(core::floor32(sl_ver)*100+core::round32(core::fract(sl_ver)*10.0f));\r
746                 }\r
747         }\r
748 #endif\r
749 \r
750 #ifdef _IRR_OPENGL_USE_EXTPOINTER_\r
751         if (!pGlActiveTextureARB || !pGlClientActiveTextureARB)\r
752         {\r
753                 Feature.MaxTextureUnits = 1;\r
754                 os::Printer::log("Failed to load OpenGL's multitexture extension, proceeding without.", ELL_WARNING);\r
755         }\r
756         else\r
757 #endif\r
758         Feature.MaxTextureUnits = core::min_(Feature.MaxTextureUnits, static_cast<u8>(MATERIAL_MAX_TEXTURES));\r
759 \r
760 #ifdef GL_ARB_occlusion_query\r
761         if (FeatureAvailable[IRR_ARB_occlusion_query])\r
762         {\r
763                 extGlGetQueryiv(GL_SAMPLES_PASSED_ARB,GL_QUERY_COUNTER_BITS_ARB,\r
764                                                 &num);\r
765                 OcclusionQuerySupport=(num>0);\r
766         }\r
767         else\r
768 #endif\r
769 #ifdef GL_NV_occlusion_query\r
770         if (FeatureAvailable[IRR_NV_occlusion_query])\r
771         {\r
772                 glGetIntegerv(GL_PIXEL_COUNTER_BITS_NV, &num);\r
773                 OcclusionQuerySupport=(num>0);\r
774         }\r
775         else\r
776 #endif\r
777                 OcclusionQuerySupport=false;\r
778 \r
779     Feature.BlendOperation = (Version >= 104) ||\r
780             FeatureAvailable[IRR_EXT_blend_minmax] ||\r
781             FeatureAvailable[IRR_EXT_blend_subtract] ||\r
782             FeatureAvailable[IRR_EXT_blend_logic_op];\r
783 \r
784 #ifdef _DEBUG\r
785         if (FeatureAvailable[IRR_NVX_gpu_memory_info])\r
786         {\r
787                 // undocumented flags, so use the RAW values\r
788                 GLint val;\r
789                 glGetIntegerv(0x9047, &val);\r
790                 os::Printer::log("Dedicated video memory (kB)", core::stringc(val));\r
791                 glGetIntegerv(0x9048, &val);\r
792                 os::Printer::log("Total video memory (kB)", core::stringc(val));\r
793                 glGetIntegerv(0x9049, &val);\r
794                 os::Printer::log("Available video memory (kB)", core::stringc(val));\r
795         }\r
796 #ifdef GL_ATI_meminfo\r
797         if (FeatureAvailable[IRR_ATI_meminfo])\r
798         {\r
799                 GLint val[4];\r
800                 glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, val);\r
801                 os::Printer::log("Free texture memory (kB)", core::stringc(val[0]));\r
802                 glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, val);\r
803                 os::Printer::log("Free VBO memory (kB)", core::stringc(val[0]));\r
804                 glGetIntegerv(GL_RENDERBUFFER_FREE_MEMORY_ATI, val);\r
805                 os::Printer::log("Free render buffer memory (kB)", core::stringc(val[0]));\r
806         }\r
807 #endif\r
808 \r
809         if (queryFeature(EVDF_TEXTURE_CUBEMAP_SEAMLESS))\r
810                 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);\r
811 \r
812 #endif\r
813 }\r
814 \r
815 const COpenGLCoreFeature& COpenGLExtensionHandler::getFeature() const\r
816 {\r
817         return Feature;\r
818 }\r
819 \r
820 bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const\r
821 {\r
822         switch (feature)\r
823         {\r
824         case EVDF_RENDER_TO_TARGET:\r
825                 return true;\r
826         case EVDF_HARDWARE_TL:\r
827                 return true; // we cannot tell other things\r
828         case EVDF_MULTITEXTURE:\r
829                 return Feature.MaxTextureUnits > 1;\r
830         case EVDF_BILINEAR_FILTER:\r
831                 return true;\r
832         case EVDF_MIP_MAP:\r
833                 return true;\r
834         case EVDF_MIP_MAP_AUTO_UPDATE:\r
835                 return !IsAtiRadeonX && (FeatureAvailable[IRR_SGIS_generate_mipmap] || FeatureAvailable[IRR_EXT_framebuffer_object] || FeatureAvailable[IRR_ARB_framebuffer_object]);\r
836         case EVDF_STENCIL_BUFFER:\r
837                 return StencilBuffer;\r
838         case EVDF_VERTEX_SHADER_1_1:\r
839         case EVDF_ARB_VERTEX_PROGRAM_1:\r
840                 return FeatureAvailable[IRR_ARB_vertex_program] || FeatureAvailable[IRR_NV_vertex_program1_1];\r
841         case EVDF_PIXEL_SHADER_1_1:\r
842         case EVDF_PIXEL_SHADER_1_2:\r
843         case EVDF_ARB_FRAGMENT_PROGRAM_1:\r
844                 return FeatureAvailable[IRR_ARB_fragment_program] || FeatureAvailable[IRR_NV_fragment_program];\r
845         case EVDF_PIXEL_SHADER_2_0:\r
846         case EVDF_VERTEX_SHADER_2_0:\r
847         case EVDF_ARB_GLSL:\r
848                 return (FeatureAvailable[IRR_ARB_shading_language_100]||Version>=200);\r
849         case EVDF_TEXTURE_NSQUARE:\r
850                 return true; // non-square is always supported\r
851         case EVDF_TEXTURE_NPOT:\r
852                 // Some ATI cards seem to have only SW support in OpenGL 2.0\r
853                 // drivers if the extension is not exposed, so we skip this\r
854                 // extra test for now!\r
855                 // return (FeatureAvailable[IRR_ARB_texture_non_power_of_two]||Version>=200);\r
856                 return (FeatureAvailable[IRR_ARB_texture_non_power_of_two]);\r
857         case EVDF_FRAMEBUFFER_OBJECT:\r
858                 return FeatureAvailable[IRR_EXT_framebuffer_object] || FeatureAvailable[IRR_ARB_framebuffer_object];\r
859         case EVDF_VERTEX_BUFFER_OBJECT:\r
860                 return FeatureAvailable[IRR_ARB_vertex_buffer_object];\r
861         case EVDF_COLOR_MASK:\r
862                 return true;\r
863         case EVDF_ALPHA_TO_COVERAGE:\r
864                 return FeatureAvailable[IRR_ARB_multisample];\r
865         case EVDF_GEOMETRY_SHADER:\r
866                 return FeatureAvailable[IRR_ARB_geometry_shader4] || FeatureAvailable[IRR_EXT_geometry_shader4] || FeatureAvailable[IRR_NV_geometry_program4] || FeatureAvailable[IRR_NV_geometry_shader4];\r
867         case EVDF_MULTIPLE_RENDER_TARGETS:\r
868                 return FeatureAvailable[IRR_ARB_draw_buffers] || FeatureAvailable[IRR_ATI_draw_buffers];\r
869         case EVDF_MRT_BLEND:\r
870         case EVDF_MRT_COLOR_MASK:\r
871                 return FeatureAvailable[IRR_EXT_draw_buffers2];\r
872         case EVDF_MRT_BLEND_FUNC:\r
873                 return FeatureAvailable[IRR_ARB_draw_buffers_blend] || FeatureAvailable[IRR_AMD_draw_buffers_blend];\r
874         case EVDF_OCCLUSION_QUERY:\r
875                 return FeatureAvailable[IRR_ARB_occlusion_query] && OcclusionQuerySupport;\r
876         case EVDF_POLYGON_OFFSET:\r
877                 // both features supported with OpenGL 1.1\r
878                 return Version>=101;\r
879         case EVDF_BLEND_OPERATIONS:\r
880                 return Feature.BlendOperation;\r
881         case EVDF_BLEND_SEPARATE:\r
882                 return (Version>=104) || FeatureAvailable[IRR_EXT_blend_func_separate];\r
883         case EVDF_TEXTURE_MATRIX:\r
884                 return true;\r
885         case EVDF_TEXTURE_COMPRESSED_DXT:\r
886                 return FeatureAvailable[IRR_EXT_texture_compression_s3tc];\r
887         case EVDF_TEXTURE_CUBEMAP:\r
888                 return (Version >= 103) || FeatureAvailable[IRR_ARB_texture_cube_map] || FeatureAvailable[IRR_EXT_texture_cube_map];\r
889         case EVDF_TEXTURE_CUBEMAP_SEAMLESS:\r
890                 return FeatureAvailable[IRR_ARB_seamless_cube_map];\r
891         case EVDF_DEPTH_CLAMP:\r
892                 return FeatureAvailable[IRR_NV_depth_clamp] || FeatureAvailable[IRR_ARB_depth_clamp];\r
893 \r
894         default:\r
895                 return false;\r
896         };\r
897 }\r
898 \r
899 \r
900 }\r
901 }\r
902 \r
903 #endif\r