glcaps.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. /*=============================================================================
  2. Name : glcaps.c
  3. Purpose : determine the capabilities of the GL currently in use
  4. Created 19/06/1998 by khent
  5. Copyright Relic Entertainment, Inc. All rights reserved.
  6. =============================================================================*/
  7. #include <string.h>
  8. #include "glcaps.h"
  9. #include "glext.h"
  10. #include "debug.h"
  11. #include "texreg.h"
  12. #include "strings.h"
  13. #include "devstats.h"
  14. #include "sstglide.h"
  15. #include "main.h"
  16. /*-----------------------------------------------------------------------------
  17. data
  18. -----------------------------------------------------------------------------*/
  19. extern unsigned int gDevcaps;
  20. extern unsigned int gDevcaps2;
  21. char const* GLC_VENDOR;
  22. char const* GLC_RENDERER;
  23. char const* GLC_EXTENSIONS;
  24. unsigned int RGL;
  25. unsigned int RGLtype;
  26. static sdword glCapTexFormat[] =
  27. {
  28. GL_RGB, 1,
  29. GL_RGBA, 1,
  30. GL_RGBA16, 1,
  31. 0, 0,
  32. };
  33. static bool glCapVertexArray;
  34. static bool glCapPointSmooth;
  35. static bool glCapLineSmooth;
  36. static bool glCapPointSize;
  37. static bool glCapDoubleBuffer;
  38. static bool glCapSwapFriendly;
  39. static bool glRescaleNormal;
  40. static bool glPalettedTexture;
  41. static bool glSharedTexturePalette;
  42. static bool glLitTexturePalette;
  43. static bool glCompiledVertexArrays;
  44. static bool glClippingHint;
  45. bool gl3Dfx;
  46. bool glNT;
  47. bool gl95;
  48. GLenum glCapDepthFunc;
  49. int NULL_rglINT(void)
  50. {
  51. __asm int 3 ;
  52. return 0;
  53. }
  54. void NULL_rglVOID(void)
  55. {
  56. __asm int 3 ;
  57. }
  58. char* NULL_rglPCHAR(void)
  59. {
  60. __asm int 3 ;
  61. return NULL;
  62. }
  63. #define RGLINT { return NULL_rglINT(); }
  64. #define RGLVOID { NULL_rglVOID(); }
  65. #define RGLBYTE { return (unsigned char)NULL_rglINT(); }
  66. #define RGLUINT { return (unsigned int)NULL_rglINT(); }
  67. #define RGLPCHAR { return NULL_rglPCHAR(); }
  68. #define RGLPVOID { return (void*)NULL_rglPCHAR(); }
  69. int (*rglFeature)(unsigned int feature);
  70. int NULL_rglFeature(unsigned int feature) RGLINT
  71. void (*rglSpecExp)(GLint index, GLfloat exp);
  72. void NULL_rglSpecExp(GLint index, GLfloat exp) RGLVOID
  73. void (*rglLightingAdjust)(GLfloat adj);
  74. void NULL_rglLightingAdjust(GLfloat adj) RGLVOID
  75. void (*rglSaveCursorUnder)(GLubyte* data, GLsizei width, GLsizei height, GLint x, GLint y);
  76. void NULL_rglSaveCursorUnder(GLubyte* data, GLsizei width, GLsizei height, GLint x, GLint y) RGLVOID
  77. void (*rglRestoreCursorUnder)(GLubyte* data, GLsizei width, GLsizei height, GLint x, GLint y);
  78. void NULL_rglRestoreCursorUnder(GLubyte* data, GLsizei width, GLsizei height, GLint x, GLint y) RGLVOID
  79. unsigned char (*rglIsFast)(unsigned int feature);
  80. unsigned char NULL_rglIsFast(unsigned int feature) RGLBYTE
  81. unsigned char (*rglCreateWindow)(GLint ihwnd, GLint width, GLint depth);
  82. unsigned char NULL_rglCreateWindow(GLint ihwnd, GLint width, GLint depth) RGLBYTE
  83. void (*rglDeleteWindow)(GLint);
  84. void NULL_rglDeleteWindow(GLint a) RGLVOID
  85. unsigned char (*rglIsClipped)(GLfloat*, GLfloat, GLfloat, GLfloat);
  86. unsigned char NULL_rglIsClipped(GLfloat* a, GLfloat b, GLfloat c, GLfloat d) RGLBYTE
  87. GLuint (*rglNumPolys)(void);
  88. GLuint NULL_rglNumPolys(void) RGLUINT
  89. GLuint (*rglCulledPolys)(void);
  90. GLuint NULL_rglCulledPolys(void) RGLUINT
  91. void (*rglBackground)(GLubyte* pixels);
  92. void NULL_rglBackground(GLubyte* pixels) RGLVOID
  93. void (*rglSetAllocs)(MemAllocFunc allocFunc, MemFreeFunc freeFunc);
  94. void NULL_rglSetAllocs(MemAllocFunc allocFunc, MemFreeFunc freeFunc) RGLVOID
  95. void (*rglSuperClear)(void);
  96. void NULL_rglSuperClear(void) RGLVOID
  97. void (*rglEnable)(GLint);
  98. void NULL_rglEnable(GLint a) RGLVOID
  99. void (*rglDisable)(GLint);
  100. void NULL_rglDisable(GLint a) RGLVOID
  101. void (*rglListSpec)(GLint pname, GLint param, GLint n, GLenum format);
  102. void NULL_rglListSpec(GLint pname, GLint param, GLint n, GLenum format) RGLVOID
  103. void (*rglList)(GLint pname, GLvoid const* list);
  104. void NULL_rglList(GLint pname, GLvoid const* list) RGLVOID
  105. void (*rglNormal)(GLint param);
  106. void NULL_rglNormal(GLint param) RGLVOID
  107. void (*rglTriangle)(GLint iPoly);
  108. void NULL_rglTriangle(GLint iPoly) RGLVOID
  109. void (*rglTexturedTriangle)(GLint iPoly);
  110. void NULL_rglTexturedTriangle(GLint iPoly) RGLVOID
  111. void (*rglSmoothTriangle)(GLint iPoly);
  112. void NULL_rglSmoothTriangle(GLint iPoly) RGLVOID
  113. void (*rglSmoothTexturedTriangle)(GLint iPoly);
  114. void NULL_rglSmoothTexturedTriangle(GLint iPoly) RGLVOID
  115. void (*rglMeshRender)(GLint n, void (*callback)(GLint material), GLint* meshPolyMode);
  116. void NULL_rglMeshRender(GLint n, void (*callback)(GLint material), GLint* meshPolyMode) RGLVOID
  117. void (*rglSelectDevice)(char* name, char* data);
  118. void NULL_rglSelectDevice(char* name, char* data) RGLVOID
  119. void (*rglD3DSetDevice)(char* dev);
  120. void NULL_rglD3DSetDevice(char* dev) RGLVOID
  121. char* (*rglD3DGetDevice)(void);
  122. char* NULL_rglD3DGetDevice(void) RGLPCHAR
  123. void* (*rglGetFramebuffer)(GLint* pitch);
  124. void* NULL_rglGetFramebuffer(GLint* pitch) RGLPVOID
  125. void (*rglDrawPitchedPixels)(GLint x0, GLint y0,
  126. GLint x1, GLint y1,
  127. GLsizei width, GLsizei height, GLsizei pitch,
  128. GLvoid const* pixels);
  129. void NULL_rglDrawPitchedPixels(GLint x0, GLint y0, GLint x1, GLint y1,
  130. GLsizei width, GLsizei height, GLsizei pitch,
  131. GLvoid const* pixels) RGLVOID
  132. /*-----------------------------------------------------------------------------
  133. code
  134. -----------------------------------------------------------------------------*/
  135. typedef int (*RGLFEATUREPROC)(unsigned int);
  136. typedef void (*RGLSPECEXPPROC)(GLint, GLfloat);
  137. typedef void (*RGLLIGHTINGADJUSTPROC)(GLfloat);
  138. typedef void (*RGLSAVECURSORUNDERPROC)(GLubyte*, GLsizei, GLsizei, GLint, GLint);
  139. typedef void (*RGLRESTORECURSORUNDERPROC)(GLubyte*, GLsizei, GLsizei, GLint, GLint);
  140. typedef unsigned char (*RGLISFASTPROC)(unsigned int);
  141. typedef unsigned char (*RGLCREATEWINDOWPROC)(GLint, GLint, GLint);
  142. typedef void (*RGLDELETEWINDOWPROC)(GLint);
  143. typedef unsigned char (*RGLISCLIPPEDPROC)(GLfloat*, GLfloat, GLfloat, GLfloat);
  144. typedef GLuint (*RGLNUMPOLYSPROC)(void);
  145. typedef GLuint (*RGLCULLEDPOLYSPROC)(void);
  146. typedef void (*RGLBACKGROUNDPROC)(GLubyte*);
  147. typedef void (*RGLSETALLOCSPROC)(MemAllocFunc, MemFreeFunc);
  148. typedef void (*RGLSUPERCLEARPROC)(void);
  149. typedef void (*RGLENABLEPROC)(GLint);
  150. typedef void (*RGLDISABLEPROC)(GLint);
  151. typedef void (*RGLLISTSPECPROC)(GLint, GLint, GLint, GLenum);
  152. typedef void (*RGLLISTPROC)(GLint, GLvoid const*);
  153. typedef void (*RGLNORMALPROC)(GLint);
  154. typedef void (*RGLTRIANGLEPROC)(GLint);
  155. typedef void (*RGLTEXTUREDTRIANGLEPROC)(GLint);
  156. typedef void (*RGLSMOOTHTRIANGLEPROC)(GLint);
  157. typedef void (*RGLSMOOTHTEXTUREDTRIANGLEPROC)(GLint);
  158. typedef void (*RGLMESHRENDERPROC)(GLint, void (*)(GLint), GLint*);
  159. typedef void (*RGLSELECTDEVICEPROC)(char*, char*);
  160. typedef void (*RGLD3DSETDEVICEPROC)(char*);
  161. typedef char* (*RGLD3DGETDEVICEPROC)(void);
  162. typedef void* (*RGLGETFRAMEBUFFERPROC)(GLint*);
  163. typedef void (*RGLDRAWPITCHEDPIXELSPROC)(GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLvoid const*);
  164. /*-----------------------------------------------------------------------------
  165. Name : glCapGetRGLAddresses
  166. Description :
  167. Inputs :
  168. Outputs :
  169. Return :
  170. ----------------------------------------------------------------------------*/
  171. void glCapGetRGLAddresses()
  172. {
  173. rglFeature = (RGLFEATUREPROC)rwglGetProcAddress("rglFeature");
  174. rglSpecExp = (RGLSPECEXPPROC)rwglGetProcAddress("rglSpecExp");
  175. rglLightingAdjust = (RGLLIGHTINGADJUSTPROC)rwglGetProcAddress("rglLightingAdjust");
  176. rglSaveCursorUnder = (RGLSAVECURSORUNDERPROC)rwglGetProcAddress("rglSaveCursorUnder");
  177. rglRestoreCursorUnder = (RGLRESTORECURSORUNDERPROC)rwglGetProcAddress("rglRestoreCursorUnder");
  178. rglIsFast = (RGLISFASTPROC)rwglGetProcAddress("rglIsFast");
  179. rglCreateWindow = (RGLCREATEWINDOWPROC)rwglGetProcAddress("rglCreateWindow");
  180. rglDeleteWindow = (RGLDELETEWINDOWPROC)rwglGetProcAddress("rglDeleteWindow");
  181. rglIsClipped = (RGLISCLIPPEDPROC)rwglGetProcAddress("rglIsClipped");
  182. rglNumPolys = (RGLNUMPOLYSPROC)rwglGetProcAddress("rglNumPolys");
  183. rglCulledPolys = (RGLCULLEDPOLYSPROC)rwglGetProcAddress("rglCulledPolys");
  184. rglBackground = (RGLBACKGROUNDPROC)rwglGetProcAddress("rglBackground");
  185. rglSetAllocs = (RGLSETALLOCSPROC)rwglGetProcAddress("rglSetAllocs");
  186. rglSuperClear = (RGLSUPERCLEARPROC)rwglGetProcAddress("rglSuperClear");
  187. rglEnable = (RGLENABLEPROC)rwglGetProcAddress("rglEnable");
  188. rglDisable = (RGLDISABLEPROC)rwglGetProcAddress("rglDisable");
  189. rglListSpec = (RGLLISTSPECPROC)rwglGetProcAddress("rglListSpec");
  190. rglList = (RGLLISTPROC)rwglGetProcAddress("rglList");
  191. rglNormal = (RGLNORMALPROC)rwglGetProcAddress("rglNormal");
  192. rglTriangle = (RGLTRIANGLEPROC)rwglGetProcAddress("rglTriangle");
  193. rglTexturedTriangle = (RGLTEXTUREDTRIANGLEPROC)rwglGetProcAddress("rglTexturedTriangle");
  194. rglSmoothTriangle = (RGLSMOOTHTRIANGLEPROC)rwglGetProcAddress("rglSmoothTriangle");
  195. rglSmoothTexturedTriangle = (RGLSMOOTHTEXTUREDTRIANGLEPROC)rwglGetProcAddress("rglSmoothTexturedTriangle");
  196. rglMeshRender = (RGLMESHRENDERPROC)rwglGetProcAddress("rglMeshRender");
  197. rglSelectDevice = (RGLSELECTDEVICEPROC)rwglGetProcAddress("rglSelectDevice");
  198. rglD3DSetDevice = (RGLD3DSETDEVICEPROC)rwglGetProcAddress("rglD3DSetDevice");
  199. rglD3DGetDevice = (RGLD3DGETDEVICEPROC)rwglGetProcAddress("rglD3DGetDevice");
  200. rglGetFramebuffer = (RGLGETFRAMEBUFFERPROC)rwglGetProcAddress("rglGetFramebuffer");
  201. rglDrawPitchedPixels = (RGLDRAWPITCHEDPIXELSPROC)rwglGetProcAddress("rglDrawPitchedPixels");
  202. }
  203. /*-----------------------------------------------------------------------------
  204. Name : glCapResetRGLAddresses
  205. Description :
  206. Inputs :
  207. Outputs :
  208. Return :
  209. ----------------------------------------------------------------------------*/
  210. void glCapResetRGLAddresses(void)
  211. {
  212. RGL = 0;
  213. rglFeature = NULL_rglFeature;
  214. rglSpecExp = NULL_rglSpecExp;
  215. rglLightingAdjust = NULL_rglLightingAdjust;
  216. rglSaveCursorUnder = NULL_rglSaveCursorUnder;
  217. rglRestoreCursorUnder = NULL_rglRestoreCursorUnder;
  218. rglIsFast = NULL_rglIsFast;
  219. rglCreateWindow = NULL_rglCreateWindow;
  220. rglDeleteWindow = NULL_rglDeleteWindow;
  221. rglIsClipped = NULL_rglIsClipped;
  222. rglNumPolys = NULL_rglNumPolys;
  223. rglCulledPolys = NULL_rglCulledPolys;
  224. rglBackground = NULL_rglBackground;
  225. rglSetAllocs = NULL_rglSetAllocs;
  226. rglSuperClear = NULL_rglSuperClear;
  227. rglEnable = NULL_rglEnable;
  228. rglDisable = NULL_rglDisable;
  229. rglListSpec = NULL_rglListSpec;
  230. rglList = NULL_rglList;
  231. rglNormal = NULL_rglNormal;
  232. rglTriangle = NULL_rglTriangle;
  233. rglTexturedTriangle = NULL_rglTexturedTriangle;
  234. rglSmoothTriangle = NULL_rglSmoothTriangle;
  235. rglSmoothTexturedTriangle = NULL_rglSmoothTexturedTriangle;
  236. rglMeshRender = NULL_rglMeshRender;
  237. rglSelectDevice = NULL_rglSelectDevice;
  238. rglD3DSetDevice = NULL_rglD3DSetDevice;
  239. rglD3DGetDevice = NULL_rglD3DGetDevice;
  240. rglGetFramebuffer = NULL_rglGetFramebuffer;
  241. rglDrawPitchedPixels = NULL_rglDrawPitchedPixels;
  242. }
  243. /*-----------------------------------------------------------------------------
  244. Name : glCapFastFeature
  245. Description : "decides" whether a feature of the GL (limited subset) is "fast"
  246. Inputs : feature - the GL capability (or "feature") to examine
  247. Outputs :
  248. Return : 0 (FALSE) or !0 (TRUE)
  249. ----------------------------------------------------------------------------*/
  250. bool glCapFastFeature(GLenum feature)
  251. {
  252. switch (feature)
  253. {
  254. case GL_BLEND:
  255. return RGL ? rglIsFast(RGL_FEATURE_BLEND) : TRUE;
  256. case GL_SRC_ALPHA_SATURATE:
  257. return RGL ? rglIsFast(RGL_FEATURE_BLEND) : FALSE;
  258. case GL_LINE_STIPPLE:
  259. return RGL ? TRUE : FALSE;
  260. default:
  261. return FALSE;
  262. }
  263. }
  264. /*-----------------------------------------------------------------------------
  265. Name : glCapFeatureExists
  266. Description : "decides" whether a feature of the GL exists
  267. Inputs : feature - the GL capability (or "feature") to examine
  268. Outputs :
  269. Return : 0 (FALSE) or !0 (TRUE)
  270. ----------------------------------------------------------------------------*/
  271. bool glCapFeatureExists(GLenum feature)
  272. {
  273. switch (feature)
  274. {
  275. case GL_VERTEX_ARRAY:
  276. return glCapVertexArray;
  277. case GL_SRC_ALPHA_SATURATE:
  278. return glCapFastFeature(feature);
  279. case GL_DOUBLEBUFFER:
  280. return glCapDoubleBuffer;
  281. case GL_SWAPFRIENDLY:
  282. return glCapSwapFriendly;
  283. case GL_RESCALE_NORMAL:
  284. return glRescaleNormal;
  285. case GL_COLOR_TABLE_FORMAT_EXT:
  286. return glPalettedTexture;
  287. case GL_SHARED_TEXTURE_PALETTE_EXT:
  288. return RGL ? rglFeature(GL_SHARED_TEXTURE_PALETTE_EXT) : glSharedTexturePalette;
  289. case GL_LIT_TEXTURE_PALETTE_EXT:
  290. return glLitTexturePalette;
  291. case GL_COMPILED_ARRAYS_EXT:
  292. return glCompiledVertexArrays;
  293. case GL_CLIP_VOLUME_CLIPPING_HINT_EXT:
  294. return glClippingHint;
  295. case GL_POINT_SMOOTH:
  296. return glCapPointSmooth;
  297. case GL_LINE_SMOOTH:
  298. return glCapLineSmooth;
  299. case RGL_BROKEN_MIXED_DEPTHTEST:
  300. if (RGLtype == D3Dtype)
  301. {
  302. if (bitTest(gDevcaps2, DEVSTAT2_BROKEN_DEPTH))
  303. {
  304. return TRUE;
  305. }
  306. else
  307. {
  308. return FALSE;
  309. }
  310. }
  311. else
  312. {
  313. return FALSE;
  314. }
  315. case RGL_COLOROP_ADD:
  316. return RGL ? rglFeature(RGL_COLOROP_ADD) : FALSE;
  317. case RGL_D3D_FULLSCENE:
  318. return (RGLtype == D3Dtype) ? rglFeature(RGL_D3D_FULLSCENE) : FALSE;
  319. case GL_POINT_SIZE:
  320. return glCapPointSize;
  321. case GL_SCISSOR_TEST:
  322. return !(RGLtype == D3Dtype);
  323. case GL_COLOR_CLEAR_VALUE:
  324. if (bitTest(gDevcaps, DEVSTAT_NO_BGCOLOUR))
  325. {
  326. return FALSE;
  327. }
  328. else if (RGLtype == D3Dtype)
  329. {
  330. #if 1
  331. return FALSE;
  332. #else
  333. if (bitTest(gDevcaps, DEVSTAT_NOD3D_BGCOLOUR))
  334. {
  335. return FALSE;
  336. }
  337. else
  338. {
  339. return TRUE;
  340. }
  341. #endif
  342. }
  343. else
  344. {
  345. return !gl3Dfx;
  346. }
  347. default:
  348. return FALSE;
  349. }
  350. }
  351. /*-----------------------------------------------------------------------------
  352. Name : glCapTexSupport
  353. Description : determines whether the GL supports a given texture format
  354. Inputs : format - the format to query
  355. Outputs :
  356. Return : TRUE or FALSE (!0 or 0)
  357. ----------------------------------------------------------------------------*/
  358. bool glCapTexSupport(GLenum format)
  359. {
  360. sdword i;
  361. for (i = 0;; i += 2)
  362. {
  363. if (glCapTexFormat[i] == 0)
  364. {
  365. break;
  366. }
  367. if (glCapTexFormat[i] == format)
  368. {
  369. return glCapTexFormat[i+1];
  370. }
  371. }
  372. return FALSE;
  373. }
  374. /*-----------------------------------------------------------------------------
  375. Name : glCapNumBuffers
  376. Description : return the number of active buffers for swapfriendly-ness
  377. Inputs :
  378. Outputs :
  379. Return : number of buffers in use for page flipping
  380. ----------------------------------------------------------------------------*/
  381. sdword glCapNumBuffers(void)
  382. {
  383. extern bool mainDoubleIsTriple;
  384. // if ((RGLtype == GLtype) && bitTest(gDevcaps, DEVSTAT_GL_TRIPLE))
  385. if (RGLtype == GLtype)
  386. {
  387. return 3;
  388. }
  389. else
  390. {
  391. return mainDoubleIsTriple ? 3 : 2;
  392. }
  393. }
  394. /*-----------------------------------------------------------------------------
  395. Name : glCapLoadOpenGL
  396. Description :
  397. Inputs : dllName - name of the .DLL
  398. Outputs :
  399. Return : 0 (failure) or !0 (success)
  400. ----------------------------------------------------------------------------*/
  401. bool glCapLoadOpenGL(char* dllName)
  402. {
  403. bool rval;
  404. rval = glDLLGetProcs(dllName);
  405. if (rval && (_stricmp(dllName, "rgl.dll") == 0))
  406. {
  407. glCapGetRGLAddresses();
  408. }
  409. return rval;
  410. }
  411. /*-----------------------------------------------------------------------------
  412. Name : haveExtension
  413. Description : determines whether a given GL extension is supported
  414. Inputs : extName - full name of the extension
  415. extString - GL_EXTENSIONS string
  416. Outputs :
  417. Return : TRUE (have) or FALSE (have not)
  418. ----------------------------------------------------------------------------*/
  419. static bool haveExtension(char* extName, char const* extString)
  420. {
  421. char* p;
  422. char* end;
  423. sdword extNameLen;
  424. p = (char*)extString;
  425. extNameLen = strlen(extName);
  426. end = p + strlen(p);
  427. while (p < end)
  428. {
  429. sdword n = strcspn(p, " ");
  430. if ((extNameLen == n) && (strncmp(extName, p, n) == 0))
  431. {
  432. return TRUE;
  433. }
  434. p += (n + 1);
  435. }
  436. return FALSE;
  437. }
  438. /*-----------------------------------------------------------------------------
  439. Name : glCapNT
  440. Description : determines whether running NT <= 4
  441. Inputs :
  442. Outputs :
  443. Return : TRUE or FALSE (NT <= 4 or not)
  444. ----------------------------------------------------------------------------*/
  445. bool glCapNT(void)
  446. {
  447. OSVERSIONINFO osVer;
  448. osVer.dwOSVersionInfoSize = sizeof(osVer);
  449. if (!GetVersionEx(&osVer))
  450. {
  451. return TRUE;
  452. }
  453. if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT &&
  454. osVer.dwMajorVersion <= 4)
  455. {
  456. return TRUE;
  457. }
  458. else
  459. {
  460. return FALSE;
  461. }
  462. }
  463. /*-----------------------------------------------------------------------------
  464. Name : glCap95
  465. Description : determines whether running 95, or something less than "Windows 4.10"
  466. Inputs :
  467. Outputs :
  468. Return : TRUE or FALSE ('95 or not)
  469. ----------------------------------------------------------------------------*/
  470. bool glCap95(void)
  471. {
  472. OSVERSIONINFO osVer;
  473. osVer.dwOSVersionInfoSize = sizeof(osVer);
  474. if (!GetVersionEx(&osVer))
  475. {
  476. return TRUE;
  477. }
  478. if (osVer.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS &&
  479. osVer.dwMinorVersion < 10)
  480. {
  481. return TRUE;
  482. }
  483. else
  484. {
  485. return FALSE;
  486. }
  487. }
  488. /*-----------------------------------------------------------------------------
  489. Name : glCapValidGL
  490. Description : check to see if GetString is returning something sane,
  491. to determine whether the GL is in a sane state
  492. Inputs :
  493. Outputs :
  494. Return : TRUE or FALSE
  495. ----------------------------------------------------------------------------*/
  496. bool glCapValidGL(void)
  497. {
  498. GLC_RENDERER = (char const*)glGetString(GL_RENDERER);
  499. if (GLC_RENDERER == NULL)
  500. {
  501. dbgMessage("\nglCapValidGL: !INVALID!");
  502. return FALSE;
  503. }
  504. else
  505. {
  506. dbgMessagef("\nglCapValidGL: VALID '%s'", GLC_RENDERER);
  507. return TRUE;
  508. }
  509. }
  510. /*-----------------------------------------------------------------------------
  511. Name : glCapStartup
  512. Description : actually queries the GL to test support for the varying texture formats
  513. and extensions, and whatnot
  514. Inputs :
  515. Outputs : glCapTexFormat[] is modified
  516. Return :
  517. ----------------------------------------------------------------------------*/
  518. static char voodoo2Extensions[] = "GL_EXT_paletted_texture GL_EXT_shared_texture_palette GL_SGIS_multitexture ";
  519. static char voodooExtensions[] = "GL_EXT_paletted_texture GL_EXT_shared_texture_palette ";
  520. static char voodooRenderer[] = "3Dfx";
  521. static char voodooVendor[] = "3Dfx Interactive Inc.";
  522. char GENERIC_OPENGL_RENDERER[128];
  523. void glCapStartup(void)
  524. {
  525. sdword i;
  526. GLubyte data[4*16*16];
  527. GLint param;
  528. char* str;
  529. extern bool mainFastFrontend;
  530. extern bool mainNoPalettes;
  531. GLC_EXTENSIONS = (char const*)glGetString(GL_EXTENSIONS);
  532. GLC_RENDERER = (char const*)glGetString(GL_RENDERER);
  533. GLC_VENDOR = (char const*)glGetString(GL_VENDOR);
  534. if (GLC_EXTENSIONS == NULL)
  535. {
  536. RGL = 0;
  537. RGLtype = GLtype;
  538. return;
  539. }
  540. //obtain Microsoft generic rasterizer RENDERER string
  541. str = strGetString(strGDIGenericRenderer);
  542. if (str == NULL)
  543. {
  544. strcpy(GENERIC_OPENGL_RENDERER, "GDI Generic");
  545. }
  546. else
  547. {
  548. strncpy(GENERIC_OPENGL_RENDERER, str, 127);
  549. }
  550. GENERIC_OPENGL_RENDERER[127] = '\0';
  551. //see if we're using rGL or OpenGL
  552. if (haveExtension("GL_RGL_rgl_feature", GLC_EXTENSIONS))
  553. {
  554. RGL = TRUE;
  555. if (strstr(GLC_EXTENSIONS, "direct3d"))
  556. {
  557. RGLtype = D3Dtype;
  558. }
  559. else
  560. {
  561. RGLtype = SWtype;
  562. }
  563. glCapGetRGLAddresses();
  564. }
  565. else
  566. {
  567. RGL = 0;
  568. RGLtype = GLtype;
  569. glCapResetRGLAddresses();
  570. }
  571. //determine texture format support
  572. for (i = 0;; i += 2)
  573. {
  574. if (glCapTexFormat[i] == 0)
  575. {
  576. break;
  577. }
  578. if (RGL)
  579. {
  580. if ((RGLtype == SWtype) && (glCapTexFormat[i] == GL_RGBA16))
  581. {
  582. glCapTexFormat[i+1] = 0;
  583. }
  584. else
  585. {
  586. glCapTexFormat[i+1] = 1;
  587. }
  588. }
  589. else
  590. {
  591. glTexImage2D(GL_PROXY_TEXTURE_2D, 0, glCapTexFormat[i], 16, 16,
  592. 0, glCapTexFormat[i], GL_UNSIGNED_BYTE, data);
  593. glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &param);
  594. if (param == glCapTexFormat[i])
  595. {
  596. glCapTexFormat[i+1] = 1;
  597. }
  598. else
  599. {
  600. glCapTexFormat[i+1] = 0;
  601. }
  602. }
  603. }
  604. //determine supported extensions
  605. glRescaleNormal = haveExtension("GL_EXT_rescale_normal", GLC_EXTENSIONS);
  606. glPalettedTexture = haveExtension("GL_EXT_paletted_texture", GLC_EXTENSIONS);
  607. glSharedTexturePalette = haveExtension("GL_EXT_shared_texture_palette", GLC_EXTENSIONS);
  608. if (RGLtype == D3Dtype)
  609. {
  610. //Direct3D doesn't get palette support, ever
  611. glPalettedTexture = FALSE;
  612. glSharedTexturePalette = FALSE;
  613. trNoPalettes = TRUE;
  614. }
  615. else if (mainNoPalettes || bitTest(gDevcaps, DEVSTAT_NOPAL))
  616. {
  617. //no palettes if globally disabled, or for this device
  618. trNoPalettes = TRUE;
  619. }
  620. else
  621. {
  622. if (glPalettedTexture && glSharedTexturePalette)
  623. {
  624. //palette extensions detected
  625. trNoPalettes = FALSE;
  626. }
  627. else
  628. {
  629. //no palette extensions available
  630. trNoPalettes = TRUE;
  631. }
  632. }
  633. if (RGLtype == GLtype)
  634. {
  635. //3dfx is the only vendor currently known to properly
  636. //support paletted textures
  637. if (strstr(GLC_VENDOR, "3dfx") == NULL &&
  638. strstr(GLC_VENDOR, "3Dfx") == NULL)
  639. {
  640. //3dfx is not the vendor, no palette support
  641. trNoPalettes = TRUE;
  642. }
  643. }
  644. //palettes are not "safe"
  645. if (mainSafeGL && (RGLtype == GLtype))
  646. {
  647. trNoPalettes = TRUE;
  648. }
  649. //determine DrawArrays & DrawElements support
  650. if (strstr(GLC_RENDERER, "Savage") != NULL)
  651. {
  652. //Savage 3/4 crash on interleaved vertex arrays
  653. glCapVertexArray = FALSE;
  654. }
  655. #if 0
  656. else if (strstr(GLC_VENDOR, "3dfx") != NULL ||
  657. strstr(GLC_VENDOR, "3Dfx") != NULL)
  658. {
  659. //3dfx OpenGL, see if K3D instructions are enabled
  660. if (strstr(GLC_RENDERER, "3DNow") != NULL)
  661. {
  662. //K3D instructions detected, can't assume vertex array support
  663. glCapVertexArray = FALSE;
  664. }
  665. else if (strstr(GLC_RENDERER, "KNI") != NULL ||
  666. strstr(GLC_RENDERER, "SSE") != NULL)
  667. {
  668. //KNI instructions detected, can't assume vertex array support
  669. glCapVertexArray = FALSE;
  670. }
  671. else
  672. {
  673. //vertex array support ok w/o extended instructions
  674. glCapVertexArray = TRUE;
  675. }
  676. }
  677. #endif
  678. else
  679. {
  680. //everything else seems ok
  681. glCapVertexArray = TRUE;
  682. }
  683. if (mainSafeGL && (RGLtype == GLtype))
  684. {
  685. //vertex array extensions are not "safe"
  686. glCapVertexArray = FALSE;
  687. }
  688. glCompiledVertexArrays = haveExtension("GL_EXT_compiled_vertex_array", GLC_EXTENSIONS);
  689. glClippingHint = haveExtension("GL_EXT_clip_volume_hint", GLC_EXTENSIONS);
  690. glLitTexturePalette = haveExtension("GL_RGL_lit_texture_palette", GLC_EXTENSIONS);
  691. if (mainSafeGL && (RGLtype == GLtype))
  692. {
  693. //compiled vertex arrays are not "safe"
  694. glCompiledVertexArrays = FALSE;
  695. }
  696. gl3Dfx = FALSE;
  697. glCapSwapFriendly = FALSE;
  698. glCapPointSize = TRUE;
  699. if (RGL)
  700. {
  701. glCapDoubleBuffer = TRUE;
  702. if (RGLtype != SWtype)
  703. {
  704. glLitTexturePalette = FALSE;
  705. }
  706. //recommended depthbuffer function
  707. glCapDepthFunc = (RGLtype == D3Dtype) ? GL_LEQUAL : GL_LESS;
  708. }
  709. else
  710. {
  711. //determine double buffering support
  712. glGetIntegerv(GL_DOUBLEBUFFER, &param);
  713. glCapDoubleBuffer = param ? TRUE : FALSE;
  714. //is this a 3dfx GL?
  715. if (_stricmp(GLC_VENDOR, voodooVendor) == 0)
  716. {
  717. //3dfxgl.dll w/ voodoo graphics or voodoo 2 ?
  718. if (_stricmp(GLC_EXTENSIONS, voodooExtensions) == 0 ||
  719. _stricmp(GLC_EXTENSIONS, voodoo2Extensions) == 0)
  720. {
  721. //we're using 3dfxgl.dll and a voodoo 1 or 2
  722. gl3Dfx = TRUE;
  723. glCapPointSize = FALSE;
  724. }
  725. }
  726. //recommended depthbuffer function
  727. glCapDepthFunc = GL_LEQUAL;
  728. }
  729. if (gl3Dfx)
  730. {
  731. //load the Glide stuff if we can use it
  732. sstStartup();
  733. }
  734. //enable/disable linesmoothing as per devcaps et al
  735. glCapLineSmooth = TRUE;
  736. if (bitTest(gDevcaps, DEVSTAT_NO_AA))
  737. {
  738. //explicitly disabled
  739. glCapLineSmooth = FALSE;
  740. }
  741. else if (RGL)
  742. {
  743. //rGL+sw and rGL+D3D don't support aa lines
  744. glCapLineSmooth = FALSE;
  745. }
  746. else
  747. {
  748. //OpenGL by default supports antialiasing
  749. glCapLineSmooth = TRUE;
  750. }
  751. //enable/disable pointsmoothing as per devcaps et al
  752. glCapPointSmooth = !RGL;
  753. if (!glCapLineSmooth)
  754. {
  755. //no pointsmoothing if no linesmoothing
  756. glCapPointSmooth = FALSE;
  757. }
  758. else if (strstr(GLC_RENDERER, "Savage") != NULL)
  759. {
  760. //Savage 3/4 doesn't want pointsmoothing
  761. glCapPointSmooth = FALSE;
  762. }
  763. else if (bitTest(gDevcaps, DEVSTAT_NO_POINTSMOOTH))
  764. {
  765. //check devcaps bit
  766. glCapPointSmooth = FALSE;
  767. }
  768. if (mainSafeGL && (RGLtype == GLtype))
  769. {
  770. //antialiasing is not "safe"
  771. glCapLineSmooth = FALSE;
  772. glCapPointSmooth = FALSE;
  773. }
  774. //enable/disable fast frontend as per devcaps
  775. if (mainFastFrontend)
  776. {
  777. glCapSwapFriendly = TRUE;
  778. }
  779. else
  780. {
  781. glCapSwapFriendly = FALSE;
  782. }
  783. if (RGLtype == SWtype)
  784. {
  785. //software is always swapfriendly
  786. glCapSwapFriendly = TRUE;
  787. }
  788. else if (RGLtype == D3Dtype)
  789. {
  790. if (bitTest(gDevcaps, DEVSTAT_NOFFE) ||
  791. bitTest(gDevcaps, DEVSTAT_NOFFE_D3D))
  792. {
  793. //disabled as per devcaps
  794. glCapSwapFriendly = FALSE;
  795. }
  796. }
  797. else
  798. {
  799. if (bitTest(gDevcaps, DEVSTAT_NOFFE) ||
  800. bitTest(gDevcaps, DEVSTAT_NOFFE_GL))
  801. {
  802. //disabled as per devcaps
  803. glCapSwapFriendly = FALSE;
  804. }
  805. }
  806. }