FS2_Open
Open source remastering of the Freespace 2 engine
gropenglextension.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 
13 #ifdef _WIN32
14 #include <windows.h>
15 #endif
16 
17 #include "cmdline/cmdline.h"
18 #include "ddsutils/ddsutils.h"
21 #include "osapi/outwnd.h"
22 #include "popup/popup.h"
23 
24 
25 
26 char *OGL_extension_string = NULL;
27 
28 // ogl_extension is:
29 // - required for game flag
30 // - enabled flag
31 // - number of extensions to check for
32 // - extension name(s) (max is 3 variants)
33 // - number of functions that extension needs/wants
34 // - function names that extension needs (max is 20)
35 
36 // OpenGL extensions that we will want to use
38 {
39  // allows for per vertex fog coordinate
40  { false, false, 1, { "GL_EXT_fog_coord" }, 2, {
41  "glFogCoordfEXT", "glFogCoordPointerEXT" } },
42 
43  // provides multiple texture units for rendering more than one texture in a single pass
44  // (NOTE: this was included in OpenGL 1.2.1 standard, but we still need to check for it or require > 1.2 OGL)
45  { true, false, 1, { "GL_ARB_multitexture" } , 3, {
46  "glMultiTexCoord2fARB", "glActiveTextureARB", "glClientActiveTextureARB" } },
47 
48  // "ADD" function for texture environment
49  { true, false, 2, { "GL_ARB_texture_env_add", "GL_EXT_texture_env_add" }, 0, { NULL } },
50 
51  // framework for using compressed textures (doesn't provide actual compression formats we use)
52  { false, false, 1, { "GL_ARB_texture_compression" }, 3, {
53  "glCompressedTexImage2D", "glCompressedTexSubImage2D", "glGetCompressedTexImageARB" } },
54 
55  // S3TC texture compression/decompression support (DXT? encoded DDS images)
56  { false, false, 1, { "GL_EXT_texture_compression_s3tc" }, 0, { NULL } },
57 
58  // allows for setting of anisotropic filter (for mipmap texture filtering)
59  { false, false, 1, { "GL_EXT_texture_filter_anisotropic" }, 0, { NULL } },
60 
61  // provides app support to control how distance is calculated in fog computations
62 // { false, false, 1, { "GL_NV_fog_distance" }, 0, { NULL } },
63 
64  // specify RGB values for secondary color
65 // { false, false, 1, { "GL_EXT_secondary_color" }, 2, {
66 // "glSecondaryColor3fvEXT", "glSecondaryColor3ubvEXT" } },
67 
68  // "COMBINE" function for texture environment, these two are basically the same
69  { false, false, 2, { "GL_ARB_texture_env_combine", "GL_EXT_texture_env_combine" }, 0, { NULL } },
70 
71  // lock a vertex array buffer so that OGL can transform it just once with multiple draws
72  { false, false, 1, { "GL_EXT_compiled_vertex_array" }, 2, {
73  "glLockArraysEXT", "glUnlockArraysEXT" } },
74 
75  // allows for row major order matrices rather than the standard column major order
76 // { true, false, 1, { "GL_ARB_transpose_matrix" }, 2, {
77 // "glLoadTransposeMatrixfARB", "glMultTransposeMatrixfARB" } },
78 
79  // this is obsolete with OGL 1.2, which is why the function name is the standard, but we check for the orginal extension name
80  { true, false, 1, { "GL_EXT_draw_range_elements" }, 1, {
81  "glDrawRangeElements" } },
82 
83  // extra texture wrap repeat mode
84  { false, false, 1, { "GL_ARB_texture_mirrored_repeat" }, 0, { NULL } },
85 
86  // allows for non-power-of-two textures, but without any cost to normal functionality or usage
87  { false, false, 1, { "GL_ARB_texture_non_power_of_two" }, 0, { NULL } },
88 
89  // creates buffer objects (cached in hi-speed video card memory) for vertex data
90  { false, false, 1, { "GL_ARB_vertex_buffer_object" }, 6, {
91  "glBindBufferARB", "glDeleteBuffersARB", "glGenBuffersARB", "glBufferDataARB",
92  "glMapBufferARB", "glUnmapBufferARB" } },
93 
94  // allows pixel data to use buffer objects
95  { false, false, 2, { "GL_ARB_pixel_buffer_object", "GL_EXT_pixel_buffer_object" }, 7, {
96  "glBindBufferARB", "glDeleteBuffersARB", "glGenBuffersARB", "glBufferDataARB",
97  "glBufferSubDataARB", "glMapBufferARB", "glUnmapBufferARB" } },
98 
99  // make me some mipmaps!
100  { false, false, 1, { "GL_SGIS_generate_mipmap" }, 0, { NULL } },
101 
102  // framebuffer object gives us render-to-texture support, among other things
103  { false, false, 1, { "GL_EXT_framebuffer_object" }, 16, {
104  "glIsRenderbufferEXT", "glBindRenderbufferEXT", "glDeleteRenderbuffersEXT", "glGenRenderbuffersEXT",
105  "glRenderbufferStorageEXT", "glGetRenderbufferParameterivEXT", "glIsFramebufferEXT", "glBindFramebufferEXT",
106  "glDeleteFramebuffersEXT", "glGenFramebuffersEXT", "glCheckFramebufferStatusEXT", "glFramebufferTexture2DEXT",
107  "glFramebufferRenderbufferEXT", "glGetFramebufferAttachmentParameterivEXT", "glGenerateMipmapEXT", "glDrawBuffers" } },
108 
109  // these next three are almost exactly the same, just different stages of naming.
110  // allows for non-power-of-textures, but at a cost of functionality
111  // (NOTE: the EXT version is usually found only on the Mac)
112  { false, false, 3, { "GL_ARB_texture_rectangle", "GL_EXT_texture_rectangle", "GL_NV_texture_rectangle" }, 0, { NULL } },
113 
114  // for BGRA rather than RGBA support (it's faster in most cases)
115  { true, false, 1, { "GL_EXT_bgra" }, 0, { NULL } },
116 
117  // cube map support (for environment maps, normal maps, bump maps, etc.)
118  { false, false, 2, { "GL_ARB_texture_cube_map", "GL_EXT_texture_cube_map" }, 0, { NULL } },
119 
120  // apply bias to level-of-detail lamda
121  { false, false, 1, { "GL_EXT_texture_lod_bias" }, 0, { NULL } },
122 
123  // point sprites (for particles)
124  { false, false, 2, { "GL_ARB_point_sprite", "NV_point_sprite" }, 0, { NULL } },
125 
126  // OpenGL Shading Language support. If this is present, then GL_ARB_shader_objects, GL_ARB_fragment_shader
127  // and GL_ARB_vertex_shader should also be available.
128  { false, false, 1, { "GL_ARB_shading_language_100" }, 0, { NULL } },
129 
130  // shader objects and program object management
131  { false, false, 1, { "GL_ARB_shader_objects" }, 19, { "glDeleteObjectARB", "glCreateShaderObjectARB", "glShaderSourceARB",
132  "glCompileShaderARB", "glGetObjectParameterivARB", "glGetInfoLogARB", "glCreateProgramObjectARB",
133  "glAttachObjectARB", "glLinkProgramARB", "glUseProgramObjectARB", "glValidateProgramARB", "glGetUniformLocationARB",
134  "glGetUniformivARB", "glUniform1fARB", "glUniform2fARB", "glUniform3fARB", "glUniform4fARB", "glUniform1iARB", "glUniformMatrix4fvARB" } },
135 
136  // programmable vertex level processing
137  // some of functions are provided by GL_ARB_vertex_program
138  { false, false, 1, { "GL_ARB_vertex_shader" }, 4, { "glEnableVertexAttribArrayARB", "glDisableVertexAttribArrayARB",
139  "glGetAttribLocationARB", "glVertexAttribPointerARB" } },
140 
141  // programmable fragment level processing
142  { false, false, 1, { "GL_ARB_fragment_shader" }, 0, { NULL } },
143 
144  // shader version 3.0 detection extensions (if any of these extensions exist then we should have a SM3.0 compatible card, hopefully)
145  { false, false, 3, { "GL_ARB_shader_texture_lod", "GL_NV_vertex_program3", "GL_ATI_shader_texture_lod" }, 0, { NULL } },
146 
147  { false, false, 1, { "GL_ARB_texture_float" }, 0, { NULL } },
148 
149  { false, false, 1, { "GL_ARB_draw_elements_base_vertex" }, 4, { "glDrawElementsBaseVertex", "glDrawRangeElementsBaseVertex",
150  "glDrawElementsInstancedBaseVertex", "glMultiDrawElementsBaseVertex" } },
151 
152  { false, false, 1, {"GL_EXT_framebuffer_blit" }, 1, { "glBlitFramebufferEXT" } },
153 
154  // geometry shaders
155  { false, false, 1, { "GL_EXT_geometry_shader4" }, 2, { "glProgramParameteriEXT", "glFramebufferTextureEXT" } },
156 
157  // array textures
158  { false, false, 1, { "GL_EXT_texture_array" }, 1, { "glTexImage3D" } },
159 
160  { false, false, 1, { "GL_ARB_uniform_buffer_object" }, 7, { "glGetUniformIndices", "glGetActiveUniformsiv", "glGetActiveUniformName",
161  "glGetUniformBlockIndex", "glGetActiveUniformBlockiv", "glGetActiveUniformBlockName", "glUniformBlockBinding" } },
162 
163  { false, false, 1, { "GL_EXT_transform_feedback" }, 7, { "glBeginTransformFeedbackEXT", "glEndTransformFeedbackEXT", "glBindBufferRangeEXT",
164  "glBindBufferOffsetEXT", "glBindBufferBaseEXT", "glTransformFeedbackVaryingsEXT", "glGetTransformFeedbackVaryingEXT" } },
165 
166  { false, false, 1, { "GL_ARB_draw_instanced" }, 2, { "glDrawArraysInstancedARB", "glDrawElementsInstancedARB" } },
167 
168  { false, false, 1, { "GL_ARB_texture_buffer_object" }, 1, { "glTexBufferARB" } }
169 };
170 
171 // ogl_funcion is:
172 // - function name
173 // - pointer for extension
174 
175 // All of the OpenGL functions that the extensions need
177 {
178  { "glFogCoordfEXT", 0 },
179  { "glFogCoordPointerEXT", 0 },
180  { "glMultiTexCoord2fARB", 0 },
181  { "glActiveTextureARB", 0 },
182  { "glClientActiveTextureARB", 0 },
183  { "glCompressedTexImage2D", 0 },
184  { "glCompressedTexSubImage2D", 0 },
185  { "glGetCompressedTexImageARB", 0 },
186 // { "glSecondaryColor3fvEXT", 0 },
187 // { "glSecondaryColor3ubvEXT", 0 },
188  { "glLockArraysEXT", 0 },
189  { "glUnlockArraysEXT", 0 },
190 // { "glLoadTransposeMatrixfARB", 0 },
191 // { "glMultTransposeMatrixfARB", 0 },
192  { "glDrawRangeElements", 0 },
193  { "glBindBufferARB", 0 },
194  { "glDeleteBuffersARB", 0 },
195  { "glGenBuffersARB", 0 },
196  { "glBufferDataARB", 0 },
197  { "glBufferSubDataARB", 0 },
198  { "glMapBufferARB", 0 },
199  { "glUnmapBufferARB", 0 },
200  { "glIsRenderbufferEXT", 0 },
201  { "glBindRenderbufferEXT", 0 },
202  { "glDeleteRenderbuffersEXT", 0 },
203  { "glGenRenderbuffersEXT", 0 },
204  { "glRenderbufferStorageEXT", 0 },
205  { "glGetRenderbufferParameterivEXT", 0 },
206  { "glIsFramebufferEXT", 0 },
207  { "glBindFramebufferEXT", 0 },
208  { "glDeleteFramebuffersEXT", 0 },
209  { "glGenFramebuffersEXT", 0 },
210  { "glCheckFramebufferStatusEXT", 0 },
211  { "glFramebufferTexture2DEXT", 0 },
212  { "glFramebufferRenderbufferEXT", 0 },
213  { "glGetFramebufferAttachmentParameterivEXT", 0 },
214  { "glGenerateMipmapEXT", 0 },
215  { "glDeleteObjectARB", 0 },
216  { "glCreateShaderObjectARB", 0 },
217  { "glShaderSourceARB", 0 },
218  { "glCompileShaderARB", 0 },
219  { "glGetObjectParameterivARB", 0 },
220  { "glGetInfoLogARB", 0 },
221  { "glCreateProgramObjectARB", 0 },
222  { "glAttachObjectARB", 0 },
223  { "glLinkProgramARB", 0 },
224  { "glUseProgramObjectARB", 0 },
225  { "glValidateProgramARB", 0 },
226  { "glEnableVertexAttribArrayARB", 0 },
227  { "glDisableVertexAttribArrayARB", 0 },
228  { "glGetAttribLocationARB", 0 },
229  { "glVertexAttribPointerARB", 0 },
230  { "glGetUniformLocationARB", 0 },
231  { "glGetUniformivARB", 0 },
232  { "glUniform1fARB", 0 },
233  { "glUniform2fARB", 0 },
234  { "glUniform3fARB", 0 },
235  { "glUniform4fARB", 0 },
236  { "glUniform3fvARB", 0 },
237  { "glUniform4fvARB", 0 },
238  { "glUniform1iARB", 0 },
239  { "glUniformMatrix4fvARB", 0 },
240  { "glDrawBuffers", 0 },
241  { "glDrawElementsBaseVertex", 0 },
242  { "glDrawRangeElementsBaseVertex", 0 },
243  { "glDrawElementsInstancedBaseVertex", 0 },
244  { "glMultiDrawElementsBaseVertex", 0 },
245  { "glBlitFramebufferEXT", 0},
246  { "glProgramParameteriEXT", 0 },
247  { "glTexImage3D", 0 },
248  { "glFramebufferTextureEXT", 0 },
249  { "glGetUniformIndices", 0 },
250  { "glGetActiveUniformsiv", 0 },
251  { "glGetActiveUniformName", 0 },
252  { "glGetUniformBlockIndex", 0 },
253  { "glGetActiveUniformBlockiv", 0 },
254  { "glGetActiveUniformBlockName", 0 },
255  { "glUniformBlockBinding", 0 },
256  { "glBeginTransformFeedbackEXT", 0 },
257  { "glEndTransformFeedbackEXT", 0 },
258  { "glBindBufferRangeEXT", 0 },
259  { "glBindBufferOffsetEXT", 0 },
260  { "glBindBufferBaseEXT", 0 },
261  { "glTransformFeedbackVaryingsEXT", 0 },
262  { "glGetTransformFeedbackVaryingEXT", 0 },
263  { "glDrawArraysInstancedARB", 0 },
264  { "glDrawElementsInstancedARB", 0 },
265  { "glTexBufferARB", 0 }
266 };
267 
268 // special extensions (only special functions are supported at the moment)
270  { "wglSwapIntervalEXT", 0 },
271  { "glXSwapIntervalSGI", 0 }
272 };
273 
274 
275 #ifdef _WIN32
276 #define GET_PROC_ADDRESS(x) wglGetProcAddress((x))
277 #else
278 #define GET_PROC_ADDRESS(x) SDL_GL_GetProcAddress((x))
279 #endif
280 
281 //tries to find a certain extension
282 static inline int opengl_find_extension(const char *ext_to_find)
283 {
284  if (OGL_extension_string == NULL)
285  return 0;
286 
287  return ( strstr(OGL_extension_string, ext_to_find) != NULL );
288 }
289 
290 // these extensions may not be listed the normal way so we don't check the extension string for them
291 static int opengl_get_extensions_special()
292 {
293  int i, num_found = 0;
294  ogl_function *func = NULL;
295 
296  for (i = 0; i < NUM_OGL_EXT_SPECIAL; i++) {
297  func = &GL_EXT_Special[i];
298 
299  Assert( func->function_name != NULL );
300 
302 
303  if (func->function_ptr) {
304  mprintf((" Found special extension function \"%s\".\n", func->function_name));
305  num_found++;
306  }
307  }
308 
309  return num_found;
310 }
311 
313 {
314  if (name == NULL) {
315  return NULL;
316  }
317 
318  for (int i = 0; i < NUM_OGL_FUNCTIONS; i++) {
319  if ( !strcmp(GL_Functions[i].function_name, name) ) {
320  return &GL_Functions[i];
321  }
322  }
323 
324  return NULL;
325 }
326 
327 //finds OGL extension functions
328 //returns number found
330 {
331  int i, j, k, num_found = 0;
332  ogl_extension *ext = NULL;
333  ogl_function *func = NULL;
334 
336 
337  for (i = 0; i < NUM_OGL_EXTENSIONS; i++) {
338  ext = &GL_Extensions[i];
339  k = 0;
340 
341  while ( !ext->enabled && (k < ext->num_extensions) ) {
342  if ( opengl_find_extension(ext->extension_name[k]) ) {
343  // some extensions do not have functions
344  if (!ext->num_functions) {
345  mprintf((" Using extension \"%s\".\n", ext->extension_name[k]));
346  ext->enabled = 1;
347  num_found++;
348  goto Next;
349  }
350 
351  // we do have functions so check any/all of them
352  for (j = 0; j < ext->num_functions; j++) {
353  func = get_ogl_function( ext->function_names[j] );
354 
355  if (func == NULL)
356  break;
357 
358  if ( !func->function_ptr )
360 
361  if ( !func->function_ptr )
362  break;
363  }
364 
365  if ( j != ext->num_functions ) {
366  mprintf((" Found extension \"%s\", but can't find the required function \"%s()\". Extension will be disabled!\n", ext->extension_name[k], ext->function_names[j]));
367 
368  if (ext->required_to_run)
369  Error( LOCATION, "The required OpenGL extension '%s' is not fully supported by your current driver version or graphics card.\n", ext->extension_name[k] );
370  } else {
371  mprintf((" Using extension \"%s\".\n", ext->extension_name[k]));
372  ext->enabled = 1;
373  num_found++;
374  }
375  } else {
376  // only report if unable to find when we have checked all available extension name variants
377  if ( k+1 >= ext->num_extensions ) {
378  mprintf((" Unable to find extension \"%s\".\n", ext->extension_name[k]));
379 
380  if (ext->required_to_run)
381  Error( LOCATION, "The required OpenGL extension '%s' is not supported by your current driver version or graphics card.\n", ext->extension_name[k] );
382  }
383  }
384 
385  // now move the the next extension name
386 Next:
387  k++;
388  }
389  }
390 
391  num_found += opengl_get_extensions_special();
392 
393  mprintf(( "\n" ));
394 
395  return num_found;
396 }
397 
398 
399 extern int OGL_fogmode;
400 
402 {
404 
405  // if S3TC compression is found, then "GL_ARB_texture_compression" must be an extension
408  // Swifty put this in, but it's not doing anything. Once he uses it, he can uncomment it.
409  //int use_base_vertex = Is_Extension_Enabled(OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX);
410 
411  //allow VBOs to be used
413  Use_VBOs = 1;
414  }
415 
417  Use_PBOs = 1;
418  }
419 
420  // setup the best fog function found
421  if ( !Fred_running ) {
423  OGL_fogmode = 2;
424  } else {
425  OGL_fogmode = 1;
426  }
427  }
428 
429  // if we can't do cubemaps then turn off Cmdline_env
431  Cmdline_env = 0;
432  }
433 
436  mprintf((" No hardware support for shadow mapping. Shadows will be disabled. \n"));
437  }
438 
441  int ver = 0, major = 0, minor = 0;
442  const char *glsl_ver = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
443 
444  sscanf(glsl_ver, "%d.%d", &major, &minor);
445  ver = (major * 100) + minor;
446 
447  GLSL_version = ver;
448 
449  // we require a minimum GLSL version
450  if (!is_minimum_GLSL_version()) {
451  mprintf((" OpenGL Shading Language version %s is not sufficient to use GLSL mode in FSO. Defaulting to fixed-function renderer.\n", glGetString(GL_SHADING_LANGUAGE_VERSION) ));
452  }
453  }
454 
455  // can't have this stuff without GLSL support
456  if ( !is_minimum_GLSL_version() ) {
457  Cmdline_normal = 0;
458  Cmdline_height = 0;
462  }
463 
465  mprintf((" No hardware support for deferred lighting. Deferred lighting will be disabled. \n"));
467  Cmdline_no_batching = true;
468  }
469 
470  if (is_minimum_GLSL_version()) {
471  GLint max_texture_units;
472  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &max_texture_units);
473 
474  // we need enough texture slots for this stuff to work
475 
476  if (max_texture_units < 6) {
477  mprintf(( "Not enough texture units for height map support. We need at least 6, we found %d.\n", max_texture_units ));
478  Cmdline_height = 0;
479  } else if (max_texture_units < 5) {
480  mprintf(( "Not enough texture units for height and normal map support. We need at least 5, we found %d.\n", max_texture_units ));
481  Cmdline_normal = 0;
482  Cmdline_height = 0;
483  } else if (max_texture_units < 4) {
484  mprintf(( "Not enough texture units found for GLSL support. We need at least 4, we found %d.\n", max_texture_units ));
485  GLSL_version = 0;
486  }
487  }
488 }
#define OGL_EXT_GEOMETRY_SHADER4
int i
Definition: multi_pxo.cpp:466
#define OGL_EXT_FRAMEBUFFER_OBJECT
ogl_function * get_ogl_function(const char *name)
#define NUM_OGL_EXT_SPECIAL
#define OGL_EXT_TEXTURE_ARRAY
int Cmdline_noglsl
Definition: cmdline.cpp:444
int Fred_running
Definition: fred.cpp:44
#define OGL_ARB_FLOATING_POINT_TEXTURES
GLenum func
Definition: Glext.h:5605
Assert(pm!=NULL)
#define mprintf(args)
Definition: pstypes.h:238
ogl_function GL_Functions[NUM_OGL_FUNCTIONS]
#define OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX
#define OGL_ARB_VERTEX_SHADER
int Cmdline_no_pbo
Definition: cmdline.cpp:443
#define NUM_OGL_EXTENSIONS
int Cmdline_env
Definition: cmdline.cpp:323
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB
Definition: Glext.h:1363
#define OGL_EXT_FOG_COORD
bool Cmdline_no_batching
Definition: cmdline.cpp:341
int Cmdline_height
Definition: cmdline.cpp:332
int Cmdline_nohtl
Definition: cmdline.cpp:438
int Texture_compression_available
Definition: ddsutils.cpp:19
void opengl_extensions_init()
int Cmdline_normal
Definition: cmdline.cpp:331
int Use_compressed_textures
Definition: ddsutils.cpp:20
#define OGL_ARB_FRAGMENT_SHADER
ogl_extension GL_Extensions[NUM_OGL_EXTENSIONS]
int opengl_get_extensions()
int Use_PBOs
Definition: gropengl.cpp:77
#define OGL_ARB_TEXTURE_CUBE_MAP
#define GET_PROC_ADDRESS(x)
#define OGL_ARB_PIXEL_BUFFER_OBJECT
#define Is_Extension_Enabled(x)
int Cmdline_shadow_quality
Definition: cmdline.cpp:344
int Cmdline_no_deferred_lighting
Definition: cmdline.cpp:345
int GLSL_version
Definition: gropengl.cpp:58
WINGDIAPI void APIENTRY glGetIntegerv(GLenum pname, GLint *params)
void _cdecl void void _cdecl Error(const char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
const char * extension_name[3]
GLuint const GLchar * name
Definition: Glext.h:5608
ogl_function GL_EXT_Special[NUM_OGL_EXT_SPECIAL]
#define OGL_ARB_VERTEX_BUFFER_OBJECT
char * OGL_extension_string
const char * function_names[20]
unsigned int ptr_u
Definition: pstypes.h:57
int OGL_fogmode
Definition: gropengl.cpp:66
int Use_VBOs
Definition: gropengl.cpp:76
#define NUM_OGL_FUNCTIONS
#define LOCATION
Definition: pstypes.h:245
#define GL_SHADING_LANGUAGE_VERSION
Definition: Glext.h:458
#define OGL_EXT_TEXTURE_COMPRESSION_S3TC
#define OGL_ARB_TEXTURE_COMPRESSION
#define OGL_ARB_SHADER_OBJECTS
WINGDIAPI const GLubyte *APIENTRY glGetString(GLenum name)
bool is_minimum_GLSL_version()
Definition: gropengl.cpp:2064
int Cmdline_postprocess
Definition: cmdline.cpp:335
int Cmdline_novbo
Definition: cmdline.cpp:441
#define OGL_ARB_TEXTURE_ENV_COMBINE
int GLint
Definition: Gl.h:48
const char * function_name
#define GL_EXTENSIONS
Definition: Gl.h:892