00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00023 #include <string.h>
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <math.h>
00027
00028 #include "OpenGLExtensions.h"
00029 #include "Inform.h"
00030 #include "utilities.h"
00031 #include "vmddlopen.h"
00032
00033 #if !defined(_MSC_VER) && !(defined(__APPLE__) && !defined (VMDMESA)) && !defined(VMDEGLPBUFFER)
00034 #include <GL/glx.h>
00035 #endif
00036
00037 #if defined(__APPLE__)
00038 #import <mach-o/dyld.h> // needed by the getProcAddress code
00039 #import <string.h>
00040 #include <AvailabilityMacros.h>
00041 #endif
00042
00044
00045 OpenGLExtensions::OpenGLExtensions(void) {
00046
00047 gllibraryhandle = NULL;
00048
00049
00050 multitextureunits = 0;
00051 hasmultisample = 0;
00052 hasmultidrawext = 0;
00053 hasstencilbuffer = 0;
00054 hastex2d = 0;
00055 hastex3d = 0;
00056 hasrescalenormalext = 0;
00057 hasglarbtexnonpoweroftwo = 0;
00058 hascompiledvertexarrayext = 0;
00059 hasglpointparametersext = 0;
00060 hasglpointspritearb = 0;
00061 hasglshaderobjectsarb = 0;
00062 hasglshadinglangarb = 0;
00063 hasglvertexshaderarb = 0;
00064 hasglfragmentshaderarb = 0;
00065 hasglgeometryshader4arb = 0;
00066 hasglsampleshadingarb = 0;
00067 }
00068
00069
00070 OpenGLExtensions::~OpenGLExtensions(void) {
00071 if (gllibraryhandle != NULL)
00072 vmddlclose(gllibraryhandle);
00073 }
00074
00075 int OpenGLExtensions::vmdQueryExtension(const char *extname) {
00076 char *excl = getenv("VMD_EXCL_GL_EXTENSIONS");
00077 if (!extname)
00078 return 0;
00079
00080
00081 if (excl != NULL) {
00082 char *endexcl = excl + strlen(excl);
00083 while (excl < endexcl) {
00084 size_t n = strcspn(excl, " ");
00085 if ((strlen(extname) == n) && (strncmp(extname, excl, n) == 0)) {
00086 return 0;
00087 }
00088 excl += (n + 1);
00089 }
00090 }
00091
00092
00093 char *ext = (char *) glGetString(GL_EXTENSIONS);
00094 if (ext != NULL) {
00095 char *endext = ext + strlen(ext);
00096 while (ext < endext) {
00097 size_t n = strcspn(ext, " ");
00098 if ((strlen(extname) == n) && (strncmp(extname, ext, n) == 0)) {
00099 return 1;
00100 break;
00101 }
00102 ext += (n + 1);
00103 }
00104 }
00105
00106 return 0;
00107 }
00108
00109 VMDGLXextFuncPtr OpenGLExtensions::vmdGetProcAddress(const char * procname) {
00110 if (!procname)
00111 return NULL;
00112
00113 #if defined(_MSC_VER)
00114
00115
00116
00117 return (VMDGLXextFuncPtr) wglGetProcAddress((LPCSTR) procname);
00118 #endif
00119
00120 #if defined(__APPLE__)
00121 #if defined(ARCH_MACOSX)
00122
00123
00124
00125 if (getenv("VMDMACENABLEEEXTENSIONS") == NULL) {
00126 return NULL;
00127 }
00128 #endif
00129
00130
00131
00132 #if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
00133
00134
00135
00136 if (gllibraryhandle == NULL) {
00137
00138 static const char * glLibPath =
00139 "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
00140 gllibraryhandle = vmddlopen(glLibPath);
00141 }
00142
00143 if (gllibraryhandle != NULL) {
00144 return (VMDGLXextFuncPtr) vmddlsym(gllibraryhandle, procname);
00145 }
00146 #else
00147
00148
00149
00150
00151 NSSymbol symbol;
00152 char *symbolName;
00153
00154 symbolName = (char *) calloc(1, strlen(procname) + 2);
00155 strcpy(symbolName+1, procname);
00156 symbolName[0] = '_';
00157 symbol = NULL;
00158 if (NSIsSymbolNameDefined(symbolName))
00159 symbol = NSLookupAndBindSymbol (symbolName);
00160 free(symbolName);
00161 return (VMDGLXextFuncPtr) (symbol ? NSAddressOfSymbol(symbol) : NULL);
00162 #endif
00163 #endif
00164
00165 #if !defined(_MSC_VER) && !defined(__APPLE__)
00166 #if !defined(__linux) && !defined(ARCH_FREEBSD) && !defined(ARCH_FREEBSDAMD64) && !defined(ARCH_SOLARISX86) && !defined(ARCH_SOLARISX86_64) && (defined(GLX_VERSION_1_4) || defined(ARCH_SOLARIS2))
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 return glXGetProcAddress((const GLubyte *) procname);
00178 #else
00179
00180
00181 #if defined(VMDEGLPBUFFER)
00182 #if 0
00183
00184
00185 if (gllibraryhandle == NULL) {
00186
00187 static const char * glLibPath = "/usr/lib64/libGL.so";
00188 gllibraryhandle = vmddlopen(glLibPath);
00189 }
00190
00191 if (gllibraryhandle != NULL) {
00192 VMDGLXextFuncPtr fctn;
00193 fctn = (VMDGLXextFuncPtr) vmddlsym(gllibraryhandle, procname);
00194 #if 0
00195 printf("proc: '%s' ptr: %p\n", procname, fctn);
00196 #endif
00197 return fctn;
00198 }
00199 #else
00200
00201 {
00202 VMDGLXextFuncPtr fctn;
00203 fctn = (VMDGLXextFuncPtr) eglGetProcAddress((const char *) procname);
00204 #if 0
00205 printf("proc: '%s' ptr: %p\n", procname, fctn);
00206 #endif
00207 return fctn;
00208 }
00209 #endif
00210 #else
00211 #if defined(GLX_ARB_get_proc_address)
00212
00213
00214
00215 return glXGetProcAddressARB((const GLubyte *) procname);
00216 #endif
00217 #endif
00218
00219 #endif
00220 #endif
00221
00222 return NULL;
00223 }
00224
00225 void OpenGLExtensions::vmdQueryGLVersion(int *major, int *minor, int *release) {
00226 const char *p = (char *) glGetString(GL_VERSION);
00227
00228 *major = 1;
00229 *minor = 0;
00230 *release = 0;
00231
00232 if (p != NULL) {
00233 char *cp;
00234 cp = (char *) calloc(1, strlen(p) + 1);
00235 strcpy(cp, p);
00236
00237 char *np=cp;
00238 char *ep=cp;
00239
00240 while (np < (np + strlen(p))) {
00241 if (*np == ' ' || *np == '\0') {
00242 *np = '\0';
00243 ep = np;
00244 break;
00245 }
00246 np++;
00247 }
00248
00249 np = cp;
00250 char *lp=cp;
00251 int x=0;
00252 while (np <= ep) {
00253 if (*np == '.' || *np == '\0') {
00254 *np = '\0';
00255
00256 switch(x) {
00257 case 0:
00258 *major = atoi(lp);
00259 break;
00260
00261 case 1:
00262 *minor = atoi(lp);
00263 break;
00264
00265 case 2:
00266 *release = atoi(lp);
00267 break;
00268 }
00269 np++;
00270 lp = np;
00271 x++;
00272 continue;
00273 }
00274
00275 np++;
00276 }
00277
00278 free(cp);
00279 }
00280 }
00281
00282
00283 void OpenGLExtensions::find_renderer(void) {
00284
00285 oglrenderer = GENERIC;
00286 const char * rs = (const char *) glGetString(GL_RENDERER);
00287 const char * rv = (const char *) glGetString(GL_VENDOR);
00288 if ((rs != NULL) && (rv != NULL)) {
00289 if (strstr(rv, "ATI") != NULL) {
00290 oglrenderer = ATI;
00291 }
00292 if (strstr(rv, "NVIDIA") != NULL) {
00293 oglrenderer = NVIDIA;
00294 }
00295 if (strstr(rs, "GDI Generic") != NULL) {
00296 oglrenderer = MSOFTGDI;
00297 }
00298 if (strstr(rs, "Mesa") != NULL) {
00299 oglrenderer = MESAGL;
00300 }
00301 if (strstr(rs, "WireGL") != NULL) {
00302 oglrenderer = WIREGL;
00303 }
00304 if ((strstr(rv, "Intel") != NULL) && (strstr(rs, "SWR") != NULL)) {
00305 oglrenderer = INTELSWR;
00306 }
00307 }
00308 }
00309
00310
00311 void OpenGLExtensions::find_extensions(void) {
00312
00313 p_glLockArraysEXT = NULL;
00314 p_glUnlockArraysEXT = NULL;
00315 p_glMultiDrawElementsEXT = NULL;
00316 p_glGlobalAlphaFactorfSUN = NULL;
00317 p_glPointParameterfARB = NULL;
00318 p_glPointParameterfvARB = NULL;
00319
00320 #if defined(GL_ARB_shader_objects)
00321
00322 p_glCreateShaderObjectARB = NULL;
00323 p_glCreateProgramObjectARB = NULL;
00324 p_glUseProgramObjectARB = NULL;
00325 p_glDetachObjectARB = NULL;
00326 p_glGetInfoLogARB = NULL;
00327 p_glGetObjectParameterivARB = NULL;
00328 p_glLinkProgramARB = NULL;
00329 p_glDeleteObjectARB = NULL;
00330 p_glAttachObjectARB = NULL;
00331 p_glCompileShaderARB = NULL;
00332 p_glShaderSourceARB = NULL;
00333 p_glGetUniformLocationARB = NULL;
00334 p_glUniform1iARB = NULL;
00335 p_glUniform1fvARB = NULL;
00336 p_glUniform2fvARB = NULL;
00337 p_glUniform3fvARB = NULL;
00338 p_glUniform4fvARB = NULL;
00339 #endif
00340
00341 vmdQueryGLVersion(&oglmajor, &oglminor, &oglrelease);
00342
00343
00344 GLint stencilbits;
00345 glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
00346 if (stencilbits > 0) {
00347 hasstencilbuffer = 1;
00348 }
00349
00350
00351 find_renderer();
00352
00353 #if defined(GL_ARB_multitexture)
00354
00355
00356 if (((oglmajor >= 1) && (oglminor >= 2)) ||
00357 ((oglmajor >= 2) && (oglminor >= 0))) {
00358
00359 if (vmdQueryExtension("GL_ARB_multitexture")) {
00360 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &multitextureunits);
00361 }
00362 }
00363 #endif
00364
00365 #if defined(GL_VERSION_1_1)
00366
00367
00368 if (((oglmajor >= 1) && (oglminor >= 1)) ||
00369 ((oglmajor >= 2) && (oglminor >= 0))) {
00370 hastex2d = 1;
00371 }
00372 #endif
00373
00374 #if defined(GL_VERSION_1_2)
00375
00376
00377 if (((oglmajor >= 1) && (oglminor >= 2)) ||
00378 ((oglmajor >= 2) && (oglminor >= 0))) {
00379 #if defined(VMDUSEGETPROCADDRESS) && !defined(__linux) && !defined(__APPLE__)
00380 p_glTexImage3D = (void (APIENTRY *)(GLenum, GLint, GLint,
00381 GLsizei, GLsizei, GLsizei, GLint,
00382 GLenum, GLenum, const GLvoid *)) vmdGetProcAddress("glTexImage3D");
00383 if (p_glTexImage3D != NULL) {
00384 hastex3d = 1;
00385 }
00386 #else
00387 hastex3d = 1;
00388 #endif
00389 }
00390 #endif
00391
00392 #if defined(GL_ARB_texture_non_power_of_two)
00393
00394 if (vmdQueryExtension("GL_ARB_texture_non_power_of_two")) {
00395 hasglarbtexnonpoweroftwo = 1;
00396 }
00397 #endif
00398
00399 #if defined(GL_EXT_multi_draw_arrays)
00400
00401 if (vmdQueryExtension("GL_EXT_multi_draw_arrays")) {
00402 #if defined(VMDUSEGETPROCADDRESS)
00403 p_glMultiDrawElementsEXT = (void (APIENTRY *)(GLenum, const GLsizei *, GLenum, const GLvoid**, GLsizei)) vmdGetProcAddress("glMultiDrawElementsEXT");
00404 if (p_glMultiDrawElementsEXT != NULL) {
00405 hasmultidrawext = 1;
00406 }
00407 #else
00408 hasmultidrawext = 1;
00409 #endif
00410 }
00411 #endif
00412
00413 #if defined(GL_ARB_shading_language_100)
00414
00415 if (vmdQueryExtension("GL_ARB_shading_language_100")) {
00416 hasglshadinglangarb = 1;
00417 }
00418 #endif
00419
00420 #if defined(GL_ARB_shader_objects)
00421 if (vmdQueryExtension("GL_ARB_shader_objects")) {
00422 #if defined(VMDUSEGETPROCADDRESS)
00423 p_glCreateShaderObjectARB = (GLhandleARB (APIENTRY *)(GLenum)) vmdGetProcAddress("glCreateShaderObjectARB");
00424 p_glCreateProgramObjectARB = (GLhandleARB (APIENTRY *)(void)) vmdGetProcAddress("glCreateProgramObjectARB");
00425 p_glUseProgramObjectARB = (void (APIENTRY *)(GLhandleARB)) vmdGetProcAddress("glUseProgramObjectARB");
00426 p_glDetachObjectARB = (void (APIENTRY *)(GLhandleARB, GLhandleARB)) vmdGetProcAddress("glDetachObjectARB");
00427 p_glGetInfoLogARB = (void (APIENTRY *)(GLhandleARB, GLsizei, GLsizei *, GLcharARB *)) vmdGetProcAddress("glGetInfoLogARB");
00428 p_glGetObjectParameterivARB = (void (APIENTRY *)(GLhandleARB, GLenum, GLint *)) vmdGetProcAddress("glGetObjectParameterivARB");
00429 p_glLinkProgramARB = (void (APIENTRY *)(GLhandleARB)) vmdGetProcAddress("glLinkProgramARB");
00430 p_glDeleteObjectARB = (void (APIENTRY *)(GLhandleARB)) vmdGetProcAddress("glDeleteObjectARB");
00431 p_glAttachObjectARB = (void (APIENTRY *)(GLhandleARB, GLhandleARB)) vmdGetProcAddress("glAttachObjectARB");
00432 p_glCompileShaderARB = (void (APIENTRY *)(GLhandleARB)) vmdGetProcAddress("glCompileShaderARB");
00433 p_glShaderSourceARB = (void (APIENTRY *)(GLhandleARB, GLsizei, const GLcharARB **, const GLint *)) vmdGetProcAddress("glShaderSourceARB");
00434 p_glGetUniformLocationARB = (GLint (APIENTRY *)(GLhandleARB programObject, const GLcharARB *name)) vmdGetProcAddress("glGetUniformLocationARB");
00435 p_glUniform1iARB = (void (APIENTRY *)(GLint location, GLint v0)) vmdGetProcAddress("glUniform1iARB");
00436 p_glUniform1fvARB = (void (APIENTRY *)(GLint location, GLsizei count, GLfloat *value)) vmdGetProcAddress("glUniform1fvARB");
00437 p_glUniform2fvARB = (void (APIENTRY *)(GLint location, GLsizei count, GLfloat *value)) vmdGetProcAddress("glUniform2fvARB");
00438 p_glUniform3fvARB = (void (APIENTRY *)(GLint location, GLsizei count, GLfloat *value)) vmdGetProcAddress("glUniform3fvARB");
00439 p_glUniform4fvARB = (void (APIENTRY *)(GLint location, GLsizei count, GLfloat *value)) vmdGetProcAddress("glUniform4fvARB");
00440
00441 if (p_glCreateShaderObjectARB != NULL && p_glCreateProgramObjectARB != NULL &&
00442 p_glUseProgramObjectARB != NULL && p_glDetachObjectARB != NULL &&
00443 p_glGetInfoLogARB != NULL && p_glGetObjectParameterivARB != NULL &&
00444 p_glLinkProgramARB != NULL && p_glDeleteObjectARB != NULL &&
00445 p_glAttachObjectARB != NULL && p_glCompileShaderARB != NULL &&
00446 p_glShaderSourceARB != NULL && p_glGetUniformLocationARB != NULL &&
00447 p_glUniform1iARB != NULL && p_glUniform1fvARB != NULL &&
00448 p_glUniform2fvARB != NULL && p_glUniform3fvARB != NULL &&
00449 p_glUniform4fvARB != NULL) {
00450 hasglshaderobjectsarb = 1;
00451 } else {
00452 hasglshaderobjectsarb = 0;
00453 }
00454 #else
00455 hasglshaderobjectsarb = 1;
00456 #endif
00457 }
00458 #endif
00459
00460 #if defined(GL_ARB_vertex_shader)
00461 if (vmdQueryExtension("GL_ARB_vertex_shader")) {
00462 hasglvertexshaderarb = 1;
00463 }
00464 #endif
00465
00466 #if defined(GL_ARB_fragment_shader)
00467 if (vmdQueryExtension("GL_ARB_fragment_shader")) {
00468 hasglfragmentshaderarb = 1;
00469 }
00470 #endif
00471
00472 #if defined(GL_ARB_geometry_shader4)
00473 if (vmdQueryExtension("GL_ARB_geometry_shader4")) {
00474 hasglgeometryshader4arb = 1;
00475 }
00476 #endif
00477
00478 if (vmdQueryExtension("GL_ARB_sample_shading")) {
00479 hasglsampleshadingarb = 1;
00480 }
00481
00482
00483 #if defined(GL_EXT_compiled_vertex_array)
00484
00485 if (vmdQueryExtension("GL_EXT_compiled_vertex_array")) {
00486 #if defined(VMDUSEGETPROCADDRESS)
00487 p_glLockArraysEXT = (void (APIENTRY *)(GLint, GLsizei)) vmdGetProcAddress("glLockArraysEXT");
00488 p_glUnlockArraysEXT = (void (APIENTRY *)(void)) vmdGetProcAddress("glUnlockArraysEXT");
00489 if ((p_glLockArraysEXT != NULL) && (p_glUnlockArraysEXT != NULL)) {
00490 hascompiledvertexarrayext = 1;
00491 }
00492 #else
00493 hascompiledvertexarrayext = 1;
00494 #endif
00495 }
00496 #endif
00497
00498 #if defined(GL_ARB_point_parameters)
00499
00500 if (vmdQueryExtension("GL_ARB_point_parameters")) {
00501 #if defined(VMDUSEGETPROCADDRESS)
00502 p_glPointParameterfARB = (void (APIENTRY *)(GLenum, GLfloat)) vmdGetProcAddress("glPointParameterfARB");
00503 p_glPointParameterfvARB = (void (APIENTRY *)(GLenum, const GLfloat *)) vmdGetProcAddress("glPointParameterfvARB");
00504 if (p_glPointParameterfARB != NULL && p_glPointParameterfvARB != NULL) {
00505 hasglpointparametersext = 1;
00506 }
00507 #else
00508 hasglpointparametersext = 1;
00509 #endif
00510 }
00511 #endif
00512
00513 #if defined(GL_ARB_point_sprite)
00514 if (vmdQueryExtension("GL_ARB_point_sprite")) {
00515 hasglpointspritearb = 1;
00516 }
00517 #endif
00518
00519 }
00520
00521
00522 void OpenGLExtensions::PrintExtensions(void) {
00523 const char * rs = (const char *) glGetString(GL_RENDERER);
00524 if (rs == NULL)
00525 rs = "ErrorUnknown";
00526
00527
00528 msgInfo << "OpenGL renderer: " << rs << sendmsg;
00529
00530
00531 msgInfo << " Features: ";
00532 if (hasstencilbuffer)
00533 msgInfo << "STENCIL ";
00534
00535 if (hasstereo)
00536 msgInfo << "STEREO ";
00537
00538 if (hasmultisample)
00539 msgInfo << "MSAA(" << nummultisamples << ") ";
00540
00541 if (hasrescalenormalext)
00542 msgInfo << "RN ";
00543
00544 if (hasmultidrawext)
00545 msgInfo << "MDE ";
00546
00547 if (hascompiledvertexarrayext)
00548 msgInfo << "CVA ";
00549
00550 if (multitextureunits > 0)
00551 msgInfo << "MTX ";
00552
00553 if (hasglarbtexnonpoweroftwo)
00554 msgInfo << "NPOT ";
00555
00556 if (hasglpointparametersext)
00557 msgInfo << "PP ";
00558
00559 if (hasglpointspritearb)
00560 msgInfo << "PS ";
00561
00562
00563
00564
00565 if (hasglshadinglangarb) {
00566 msgInfo << "GLSL(";
00567
00568 if (hasglshaderobjectsarb)
00569 msgInfo << "O";
00570
00571 if (hasglvertexshaderarb)
00572 msgInfo << "V";
00573
00574 if (hasglfragmentshaderarb)
00575 msgInfo << "F";
00576
00577 if (hasglgeometryshader4arb)
00578 msgInfo << "G";
00579
00580 if (hasglsampleshadingarb)
00581 msgInfo << "S";
00582
00583 msgInfo << ") ";
00584 }
00585 msgInfo << sendmsg;
00586 }
00587