1 /*
2 PLIB - A Suite of Portable Game Libraries
3 Copyright (C) 1998,2002 Steve Baker
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 For further information visit http://plib.sourceforge.net
20
21 $Id: ssg.cxx 2125 2007-09-29 17:20:40Z fayjf $
22 */
23
24
25 #define _UL_GENERATE_CODE_
26 #include "ssgLocal.h"
27
28 #if defined(UL_MACINTOSH)
29 # include <agl.h>
30 #elif defined(UL_MAC_OSX)
31 # include <OpenGL/CGLCurrent.h>
32 #elif defined(UL_WIN32)
33 /* Nothing */
34 #else
35 # include <GL/glx.h>
36 #endif
37
glIsValidContext(void)38 static bool glIsValidContext ( void )
39 {
40 #if defined(CONSOLE)
41 return true ;
42 #elif defined(UL_WIN32)
43 return ( wglGetCurrentContext () != NULL ) ;
44 #elif defined(UL_MACINTOSH)
45 return ( aglGetCurrentContext () != NULL ) ;
46 #elif defined(UL_MAC_OSX)
47 return ( CGLGetCurrentContext () != NULL ) ;
48 #else
49 return ( glXGetCurrentContext () != NULL ) ;
50 #endif
51 }
52
53 sgMat4 _ssgOpenGLAxisSwapMatrix =
54 {
55 { 1.0f, 0.0f, 0.0f, 0.0f },
56 { 0.0f, 0.0f, -1.0f, 0.0f },
57 { 0.0f, 1.0f, 0.0f, 0.0f },
58 { 0.0f, 0.0f, 0.0f, 1.0f }
59 } ;
60
61 sgVec3 _ssgVertex000 = { 0.0f, 0.0f, 0.0f } ;
62 sgVec4 _ssgColourWhite = { 1.0f, 1.0f, 1.0f, 1.0f } ;
63 sgVec3 _ssgNormalUp = { 0.0f, 0.0f, 1.0f } ;
64 sgVec2 _ssgTexCoord00 = { 0.0f, 0.0f } ;
65 short _ssgIndex0 = 0;
66 bool _ssgBackFaceCollisions = false ;
67
ssgSetBackFaceCollisions(bool b)68 void ssgSetBackFaceCollisions ( bool b ) { _ssgBackFaceCollisions = b ; }
69
70 static ssgLight _ssgLights [ 8 ] ;
71 static int _ssgFrameCounter = 0 ;
72
ssgGetFrameCounter()73 int ssgGetFrameCounter () { return _ssgFrameCounter ; }
ssgSetFrameCounter(int fc)74 void ssgSetFrameCounter ( int fc ) { _ssgFrameCounter = fc ; }
75
ssgGetVersion()76 const char *ssgGetVersion ()
77 {
78 #ifdef VERSION
79 return VERSION ;
80 #else
81 return "Unknown" ;
82 #endif
83 }
84
ssgDeRefDelete(ssgBase * s)85 void ssgDeRefDelete ( ssgBase *s )
86 {
87 if ( s == NULL ) return ;
88
89 s -> deRef () ;
90
91 if ( s -> getRef () <= 0 )
92 delete s ;
93 }
94
ssgDelete(ssgBranch * br)95 void ssgDelete ( ssgBranch *br )
96 {
97 if ( br == NULL )
98 return ;
99
100 br -> removeAllKids () ;
101 delete br ;
102 }
103
ssgGetLight(int i)104 ssgLight *ssgGetLight ( int i )
105 {
106 return &_ssgLights [ i ] ;
107 }
108
ssgInit()109 void ssgInit ()
110 {
111 if ( ! glIsValidContext () )
112 {
113 ulSetError ( UL_FATAL, "ssgInit called without a valid OpenGL context.");
114 }
115
116 ssgTexturePath ( "." ) ;
117 ssgModelPath ( "." ) ;
118
119 _ssgLights [ 0 ] . setID ( 0 ) ;
120 _ssgLights [ 0 ] . on () ;
121
122 for ( int i = 1 ; i < 8 ; i++ )
123 {
124 _ssgLights [ i ] . setID ( i ) ;
125 _ssgLights [ i ] . off () ;
126 }
127
128 new ssgContext ; /* Sets the current context with defaults */
129
130 ssgAddModelFormat ( ".ssg", ssgLoadSSG , ssgSaveSSG ) ;
131
132 ssgAddModelFormat ( ".3ds", ssgLoad3ds , ssgSave3ds ) ;
133 ssgAddModelFormat ( ".ac" , ssgLoadAC3D , ssgSaveAC ) ;
134 ssgAddModelFormat ( ".ase", ssgLoadASE , ssgSaveASE ) ;
135 ssgAddModelFormat ( ".dof", ssgLoadDOF , NULL ) ;
136 ssgAddModelFormat ( ".dxf", ssgLoadDXF , ssgSaveDXF ) ;
137 ssgAddModelFormat ( ".obj", ssgLoadOBJ , ssgSaveOBJ ) ;
138 ssgAddModelFormat ( ".tri", ssgLoadTRI , ssgSaveTRI ) ;
139 ssgAddModelFormat ( ".md2", ssgLoadMD2 , NULL ) ;
140 ssgAddModelFormat ( ".x" , ssgLoadX , ssgSaveX ) ;
141 ssgAddModelFormat ( ".flt", ssgLoadFLT , ssgSaveFLT ) ;
142 ssgAddModelFormat ( ".strip", ssgLoadStrip, NULL ) ;
143 ssgAddModelFormat ( ".m" , ssgLoadM , ssgSaveM ) ;
144 ssgAddModelFormat ( ".off" , ssgLoadOFF , ssgSaveOFF ) ;
145 ssgAddModelFormat ( ".atg" , ssgLoadATG , ssgSaveATG ) ;
146 ssgAddModelFormat ( ".qhi" , NULL , ssgSaveQHI ) ;
147 ssgAddModelFormat ( ".wrl", ssgLoadVRML1, ssgSaveVRML1 ) ;
148 ssgAddModelFormat ( ".iv", ssgLoadIV , ssgSaveIV ) ;
149 ssgAddModelFormat ( ".asc", ssgLoadASC , ssgSaveASC ) ;
150 //ssgAddModelFormat ( ".pov", NULL , ssgSavePOV ) ;
151
152
153 #ifdef SSG_LOAD_MDL_SUPPORTED
154 ssgAddModelFormat ( ".mdl", ssgLoadMDL , NULL ) ;
155 #endif
156
157 #ifdef SSG_LOAD_TGA_SUPPORTED
158 ssgAddTextureFormat ( ".tga" , ssgLoadTGA ) ;
159 #endif
160
161 #ifdef SSG_LOAD_BMP_SUPPORTED
162 ssgAddTextureFormat ( ".bmp" , ssgLoadBMP ) ;
163 #endif
164
165 #ifdef SSG_LOAD_PNG_SUPPORTED
166 ssgAddTextureFormat ( ".png" , ssgLoadPNG ) ;
167 #endif
168
169 #ifdef SSG_LOAD_PCX_SUPPORTED
170 ssgAddTextureFormat ( ".pcx" , ssgLoadPCX ) ;
171 #endif
172
173 #ifdef SSG_LOAD_SGI_SUPPORTED
174 ssgAddTextureFormat ( ".rgb" , ssgLoadSGI ) ;
175 ssgAddTextureFormat ( ".rgba" , ssgLoadSGI ) ;
176 ssgAddTextureFormat ( ".int" , ssgLoadSGI ) ;
177 ssgAddTextureFormat ( ".inta" , ssgLoadSGI ) ;
178 ssgAddTextureFormat ( ".bw" , ssgLoadSGI ) ;
179 #endif
180
181 #if defined(SSG_LOAD_MDL_SUPPORTED) || defined(SSG_LOAD_MDL_BGL_TEXTURE_SUPPORTED)
182 ssgAddTextureFormat ( ".0af" , ssgLoadMDLTexture ) ;
183 ssgAddTextureFormat ( ".1af" , ssgLoadMDLTexture ) ;
184 ssgAddTextureFormat ( ".2af" , ssgLoadMDLTexture ) ;
185 ssgAddTextureFormat ( ".3af" , ssgLoadMDLTexture ) ;
186 ssgAddTextureFormat ( ".4af" , ssgLoadMDLTexture ) ;
187 ssgAddTextureFormat ( ".5af" , ssgLoadMDLTexture ) ;
188 ssgAddTextureFormat ( ".6af" , ssgLoadMDLTexture ) ;
189 ssgAddTextureFormat ( ".7af" , ssgLoadMDLTexture ) ;
190 ssgAddTextureFormat ( ".8af" , ssgLoadMDLTexture ) ;
191 ssgAddTextureFormat ( ".9af" , ssgLoadMDLTexture ) ;
192 ssgAddTextureFormat ( ".aaf" , ssgLoadMDLTexture ) ;
193 ssgAddTextureFormat ( ".baf" , ssgLoadMDLTexture ) ;
194 ssgAddTextureFormat ( ".caf" , ssgLoadMDLTexture ) ;
195 ssgAddTextureFormat ( ".daf" , ssgLoadMDLTexture ) ;
196 ssgAddTextureFormat ( ".eaf" , ssgLoadMDLTexture ) ;
197 ssgAddTextureFormat ( ".faf" , ssgLoadMDLTexture ) ;
198 ssgAddTextureFormat ( ".gaf" , ssgLoadMDLTexture ) ;
199 ssgAddTextureFormat ( ".haf" , ssgLoadMDLTexture ) ;
200 ssgAddTextureFormat ( ".iaf" , ssgLoadMDLTexture ) ;
201 ssgAddTextureFormat ( ".jaf" , ssgLoadMDLTexture ) ;
202 ssgAddTextureFormat ( ".kaf" , ssgLoadMDLTexture ) ;
203 ssgAddTextureFormat ( ".pat" , ssgLoadMDLTexture ) ;
204 ssgAddTextureFormat ( ".r8" , ssgLoadMDLTexture ) ;
205 ssgAddTextureFormat ( ".naz" , ssgLoadMDLTexture ) ;
206 ssgAddTextureFormat ( ".ktx" , ssgLoadMDLTexture ) ;
207 ssgAddTextureFormat ( ".oav" , ssgLoadMDLTexture ) ;
208 ssgAddTextureFormat ( ".sky" , ssgLoadMDLTexture ) ;
209 ssgAddTextureFormat ( ".ngt" , ssgLoadMDLTexture ) ;
210 #endif
211
212 #ifdef SSG_LOAD_XPL_SUPPORTED
213 ssgAddModelFormat ( ".xpl", ssgLoadXPlaneOBJ , NULL ) ;
214 #endif
215 }
216
217
218
ssgCullAndPick(ssgBranch * r,sgVec2 botleft,sgVec2 topright)219 void ssgCullAndPick ( ssgBranch *r, sgVec2 botleft, sgVec2 topright )
220 {
221 if ( _ssgCurrentContext == NULL )
222 {
223 ulSetError ( UL_FATAL, "ssg: No Current Context: Did you forgot to call ssgInit()?" ) ;
224 }
225
226 ssgForceBasicState () ;
227
228 GLint vp [ 4 ] ;
229 sgVec4 viewport ;
230 sgMat4 mat ;
231
232 float w = (topright[0] - botleft[0]) ;
233 float h = (topright[1] - botleft[1]) ;
234
235 float x = (botleft[0] + topright[0]) / 2.0f ;
236 float y = (botleft[1] + topright[1]) / 2.0f ;
237
238 glGetIntegerv ( GL_VIEWPORT, vp ) ;
239
240 sgSetVec4 ( viewport, (float)vp[0], (float)vp[1],
241 (float)vp[2], (float)vp[3] ) ;
242 sgMakePickMatrix ( mat, x, y, w, h, viewport ) ;
243
244 glMatrixMode ( GL_PROJECTION ) ;
245 glLoadIdentity () ;
246 glMultMatrixf ( (float *) mat ) ;
247
248 _ssgCurrentContext->pushProjectionMatrix () ;
249
250 glMatrixMode ( GL_MODELVIEW ) ;
251 glLoadIdentity () ;
252
253 int i ;
254
255 for ( i = 0 ; i < 8 ; i++ )
256 if ( _ssgLights [ i ] . isHeadlight () )
257 _ssgLights [ i ] . setup () ;
258
259 _ssgCurrentContext->loadModelviewMatrix () ;
260
261 for ( i = 0 ; i < 8 ; i++ )
262 if ( ! _ssgLights [ i ] . isHeadlight () )
263 _ssgLights [ i ] . setup () ;
264
265 _ssgCurrentContext->cull(r) ;
266 _ssgDrawDList () ;
267
268 glMatrixMode ( GL_MODELVIEW ) ;
269 glLoadIdentity () ;
270 }
271
272
ssgCullAndDraw(ssgBranch * r)273 void ssgCullAndDraw ( ssgBranch *r )
274 {
275 if ( _ssgCurrentContext == NULL )
276 {
277 ulSetError ( UL_FATAL, "ssg: No Current Context: Did you forgot to call ssgInit()?" ) ;
278 }
279
280 _ssgStartOfFrameInit () ;
281
282 ssgForceBasicState () ;
283
284 glMatrixMode ( GL_PROJECTION ) ;
285 _ssgCurrentContext->loadProjectionMatrix () ;
286
287 glMatrixMode ( GL_MODELVIEW ) ;
288 glLoadIdentity () ;
289
290 int i ;
291
292 for ( i = 0 ; i < 8 ; i++ )
293 if ( _ssgLights [ i ] . isHeadlight () )
294 _ssgLights [ i ] . setup () ;
295
296 _ssgCurrentContext->loadModelviewMatrix () ;
297 _ssgCurrentContext->applyClipPlanes () ;
298
299 for ( i = 0 ; i < 8 ; i++ )
300 if ( ! _ssgLights [ i ] . isHeadlight () )
301 _ssgLights [ i ] . setup () ;
302
303 _ssgCurrentContext->cull(r) ;
304 _ssgDrawDList () ;
305
306 _ssgCurrentContext->removeClipPlanes () ;
307
308 glMatrixMode ( GL_MODELVIEW ) ;
309 glLoadIdentity () ;
310
311 _ssgEndOfFrameCleanup () ;
312 _ssgFrameCounter++ ;
313 }
314
315
getTypeName(void)316 const char *ssgAxisTransform::getTypeName (void) { return "ssgAxisTransform" ; }
getTypeName(void)317 const char *ssgBase ::getTypeName (void) { return "ssgBase" ; }
getTypeName(void)318 const char *ssgTexture ::getTypeName (void) { return "ssgTexture" ; }
getTypeName(void)319 const char *ssgState ::getTypeName (void) { return "ssgState" ; }
getTypeName(void)320 const char *ssgSimpleState ::getTypeName (void) { return "ssgSimpleState" ; }
getTypeName(void)321 const char *ssgStateSelector::getTypeName (void) { return "ssgStateSelector" ; }
getTypeName(void)322 const char *ssgEntity ::getTypeName (void) { return "ssgEntity" ; }
getTypeName(void)323 const char *ssgLeaf ::getTypeName (void) { return "ssgLeaf" ; }
getTypeName(void)324 const char *ssgVTable ::getTypeName (void) { return "ssgVTable" ; }
getTypeName(void)325 const char *ssgVtxTable ::getTypeName (void) { return "ssgVtxTable" ; }
getTypeName(void)326 const char *ssgVtxArray ::getTypeName (void) { return "ssgVtxArray" ; }
getTypeName(void)327 const char *ssgBranch ::getTypeName (void) { return "ssgBranch" ; }
getTypeName(void)328 const char *ssgSelector ::getTypeName (void) { return "ssgSelector" ; }
getTypeName(void)329 const char *ssgRangeSelector::getTypeName (void) { return "ssgRangeSelector" ; }
getTypeName(void)330 const char *ssgTimedSelector::getTypeName (void) { return "ssgTimedSelector" ; }
getTypeName(void)331 const char *ssgBaseTransform::getTypeName (void) { return "ssgBaseTransform" ; }
getTypeName(void)332 const char *ssgTransform ::getTypeName (void) { return "ssgTransform" ; }
getTypeName(void)333 const char *ssgTexTrans ::getTypeName (void) { return "ssgTexTrans" ; }
getTypeName(void)334 const char *ssgCutout ::getTypeName (void) { return "ssgCutout" ; }
getTypeName(void)335 const char *ssgRoot ::getTypeName (void) { return "ssgRoot" ; }
336
getTypeName(void)337 const char *ssgSimpleList ::getTypeName (void) { return "ssgSimpleList" ; }
getTypeName(void)338 const char *ssgColourArray ::getTypeName (void) { return "ssgColourArray" ; }
getTypeName(void)339 const char *ssgIndexArray ::getTypeName (void) { return "ssgIndexArray" ; }
getTypeName(void)340 const char *ssgTransformArray::getTypeName (void) { return "ssgTransformArray" ; }
getTypeName(void)341 const char *ssgTexCoordArray::getTypeName (void) { return "ssgTexCoordArray" ; }
getTypeName(void)342 const char *ssgVertexArray ::getTypeName (void) { return "ssgVertexArray" ; }
getTypeName(void)343 const char *ssgNormalArray ::getTypeName (void) { return "ssgNormalArray" ; }
getTypeName(void)344 const char *ssgInterleavedArray::getTypeName (void) { return "ssgInterleavedArray"; }
345
346
347
createBase()348 static ssgBase *createBase () { return new ssgBase ; }
349
350 //static ssgBase *createEntity () { return new ssgEntity ; }
351 //static ssgBase *createLeaf () { return new ssgLeaf ; }
createVTable()352 static ssgBase *createVTable () { return new ssgVTable ; }
createVtxTable()353 static ssgBase *createVtxTable () { return new ssgVtxTable ; }
createVtxArray()354 static ssgBase *createVtxArray () { return new ssgVtxArray ; }
createTween()355 static ssgBase *createTween () { return new ssgTween ; }
createBranch()356 static ssgBase *createBranch () { return new ssgBranch ; }
357 //static ssgBase *createBaseTransform () { return new ssgBaseTransform ; }
createTransform()358 static ssgBase *createTransform () { return new ssgTransform ; }
createTexTrans()359 static ssgBase *createTexTrans () { return new ssgTexTrans ; }
createAnimTransform()360 static ssgBase *createAnimTransform() { return new ssgAnimTransform ; }
createAxisTransform()361 static ssgBase *createAxisTransform() { return new ssgAxisTransform ; }
createSelector()362 static ssgBase *createSelector () { return new ssgSelector ; }
createRangeSelector()363 static ssgBase *createRangeSelector () { return new ssgRangeSelector ; }
createTimedSelector()364 static ssgBase *createTimedSelector () { return new ssgTimedSelector ; }
createTweenController()365 static ssgBase *createTweenController () { return new ssgTweenController ; }
createRoot()366 static ssgBase *createRoot () { return new ssgRoot ; }
createCutout()367 static ssgBase *createCutout () { return new ssgCutout ; }
createInvisible()368 static ssgBase *createInvisible () { return new ssgInvisible ; }
369
370 //static ssgBase *createState () { return new ssgState ; }
createSimpleState()371 static ssgBase *createSimpleState () { return new ssgSimpleState ; }
createStateSelector()372 static ssgBase *createStateSelector () { return new ssgStateSelector ; }
373
createSimpleList()374 static ssgBase *createSimpleList () { return new ssgSimpleList ; }
createVertexArray()375 static ssgBase *createVertexArray () { return new ssgVertexArray ; }
createNormalArray()376 static ssgBase *createNormalArray () { return new ssgNormalArray ; }
createTexCoordArray()377 static ssgBase *createTexCoordArray () { return new ssgTexCoordArray ; }
createColourArray()378 static ssgBase *createColourArray () { return new ssgColourArray ; }
createIndexArray()379 static ssgBase *createIndexArray () { return new ssgIndexArray ; }
createTransformArray()380 static ssgBase *createTransformArray () { return new ssgTransformArray ; }
createInterleavedArray()381 static ssgBase *createInterleavedArray () { return new ssgInterleavedArray ; }
382
createTexture()383 static ssgBase *createTexture () { return new ssgTexture ; }
384
385
386 static struct {
387
388 int type ;
389 ssgBase * ( *func ) () ;
390
391 } table[256] = {
392
393 { ssgTypeBase () , createBase },
394
395 //{ ssgTypeEntity () , createEntity },
396 //{ ssgTypeLeaf () , createLeaf },
397 { ssgTypeVTable () , createVTable },
398 { ssgTypeVtxTable () , createVtxTable },
399 { ssgTypeVtxArray () , createVtxArray },
400 { ssgTypeTween () , createTween },
401 { ssgTypeBranch () , createBranch },
402 //{ ssgTypeBaseTransform () , createBaseTransform },
403 { ssgTypeTransform () , createTransform },
404 { ssgTypeAnimTransform () , createAnimTransform },
405 { ssgTypeTexTrans () , createTexTrans },
406 { ssgTypeAxisTransform () , createAxisTransform },
407 { ssgTypeSelector () , createSelector },
408 { ssgTypeRangeSelector () , createRangeSelector },
409 { ssgTypeTimedSelector () , createTimedSelector },
410 { ssgTypeTweenController () , createTweenController },
411 { ssgTypeRoot () , createRoot },
412 { ssgTypeCutout () , createCutout },
413 { ssgTypeInvisible () , createInvisible },
414
415 //{ ssgTypeState () , createState },
416 { ssgTypeSimpleState () , createSimpleState },
417 { ssgTypeStateSelector () , createStateSelector },
418
419 { ssgTypeSimpleList () , createSimpleList },
420 { ssgTypeVertexArray () , createVertexArray },
421 { ssgTypeNormalArray () , createNormalArray },
422 { ssgTypeTexCoordArray () , createTexCoordArray },
423 { ssgTypeColourArray () , createColourArray },
424 { ssgTypeIndexArray () , createIndexArray },
425 { ssgTypeTransformArray () , createTransformArray },
426 { ssgTypeInterleavedArray () , createInterleavedArray },
427
428 { ssgTypeTexture () , createTexture },
429
430 { 0, NULL }
431
432 };
433
ssgRegisterType(int type,ssgBase * (* func)())434 void ssgRegisterType ( int type, ssgBase * ( *func ) () )
435 {
436 if ( type == 0 || func == NULL )
437 {
438 ulSetError ( UL_WARNING, "ssgRegisterType: Bad arguments (type %#x, func %p).",
439 type, func ) ;
440 return ;
441 }
442
443 int i ;
444 for ( i = 0 ; table[i].type != 0 && table[i].type != type ; i++ )
445 ;
446
447 if ( table[i].type == type && table[i].func != func )
448 ulSetError ( UL_WARNING, "ssgRegisterType: Type %#x redefined differently.", type ) ;
449
450 table[i].type = type ;
451 table[i].func = func ;
452 }
453
ssgCreateOfType(int type)454 ssgBase *ssgCreateOfType ( int type )
455 {
456 // XXX linear search
457 int i ;
458
459 for ( i = 0 ; table[i].type != 0 && table[i].type != type ; i++ )
460 ;
461
462 if ( table[i].type == 0 )
463 {
464 ulSetError ( UL_WARNING, "ssgCreateOfType: Unrecognized type %#x.", type ) ;
465 return NULL ;
466 }
467
468 ssgBase *obj = (*table[i].func) () ;
469
470 if ( obj == NULL )
471 ulSetError ( UL_WARNING, "ssgCreateOfType: Got null object for type %#x.", type ) ;
472 else if ( obj -> getType () != type )
473 ulSetError ( UL_WARNING,
474 "ssgCreateOfType: Created object has wrong type %#x (%s), expected %#x.",
475 obj -> getType (), obj -> getTypeName (), type ) ;
476
477 return obj ;
478 }
479
ssgSearchExtensionString(char * extString,char * extName)480 static bool ssgSearchExtensionString(char *extString, char *extName)
481 {
482 // Returns GL_TRUE if the *extName string appears in the *extString string,
483 // surrounded by white spaces, or GL_FALSE otherwise.
484
485 char *p, *end;
486 int n, extNameLen;
487
488 if ( ( extString == NULL ) || ( extName == NULL ) )
489 return false;
490
491 extNameLen = strlen ( extName );
492
493 p = extString;
494 end = p + strlen ( p );
495
496 while ( p < end )
497 {
498 n = strcspn ( p, " " );
499 if ( ( extNameLen == n ) && ( strncmp ( extName, p, n ) == 0 ) )
500 return GL_TRUE;
501
502 p += (n + 1);
503 }
504
505 return GL_FALSE;
506 }
507
ssgIsExtensionSupported(char * extName)508 bool ssgIsExtensionSupported(char *extName)
509 {
510 // Returns GL_TRUE if the OpenGL Extension whose name is *extName
511 // is supported by the system, or GL_FALSE otherwise.
512
513 // The *extName string must follow the OpenGL extensions naming scheme
514 // (ie: "GL_type_extension", like GL_EXT_convolution)
515
516 return ssgSearchExtensionString ( (char *)glGetString(GL_EXTENSIONS), extName );
517 }
518
519