winGL.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platformWin32/platformWin32.h"
  23. #include "platformWin32/platformGL.h"
  24. #include "graphics/dgl.h"
  25. #include "platform/platformVideo.h"
  26. #include "string/unicode.h"
  27. #include "console/console.h"
  28. #include "console/consoleTypes.h"
  29. GLState gGLState;
  30. bool gOpenGLDisablePT = false;
  31. bool gOpenGLDisableCVA = false;
  32. bool gOpenGLDisableTEC = false;
  33. bool gOpenGLDisableARBMT = false;
  34. bool gOpenGLDisableFC = false;
  35. bool gOpenGLDisableTCompress = false;
  36. bool gOpenGLNoEnvColor = false;
  37. float gOpenGLGammaCorrection = 0.5;
  38. bool gOpenGLNoDrawArraysAlpha = false;
  39. //------------------------------------------------------------------
  40. //bind functions for each function prototype
  41. //------------------------------------------------------------------
  42. //GL_EXT/ARB
  43. enum {
  44. ARB_multitexture = BIT(0),
  45. ARB_texture_compression = BIT(1),
  46. EXT_compiled_vertex_array = BIT(2),
  47. EXT_fog_coord = BIT(3),
  48. EXT_paletted_texture = BIT(4),
  49. NV_vertex_array_range = BIT(5),
  50. EXT_blend_color = BIT(6),
  51. EXT_blend_minmax = BIT(7)
  52. };
  53. //WGL_ARB
  54. enum {
  55. WGL_ARB_extensions_string = BIT(0),
  56. WGL_EXT_swap_control = BIT(1),
  57. WGL_3DFX_gamma_control = BIT(2)
  58. };
  59. //------------------------------------------------------------------
  60. //create dummy functions and set real functions to dummies for:
  61. // -core GL
  62. // -core WGL
  63. // -WGL extensions
  64. //------------------------------------------------------------------
  65. //defines...
  66. //-------------
  67. // we want to declare/define all GL functions here and set them all to a "stub"
  68. // function so that if they're called before they're initialized, they'll spew
  69. // some console spam to make it easier to debug. We also need to declare/define
  70. // a "dll" version, which will ALWAYS point to the function defined in the dll.
  71. // This for special functionality like wireframe, logging, and performance metrics
  72. // that will override the normal function and do some additional work. We'll make
  73. // the dll versions extern so that we can seperate out all the performance/logging
  74. // functionality to a seperate file to keep this one a little bit cleaner. So,
  75. // our macros look like this for the most part (although a lot uglier in practice):
  76. // type name##_t(params) { console_warning; return ret; }
  77. // type name(params) = name##_t;
  78. // extern type dll##name(params = name##_t
  79. #ifndef TORQUE_LIB
  80. #define GL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY fn_name##_t)fn_args \
  81. { Con::printf("Could not load this GL function: %s", #fn_name); fn_body } \
  82. fn_type (APIENTRY * fn_name)fn_args = fn_name##_t; \
  83. extern fn_type (APIENTRY * dll##fn_name)fn_args = fn_name##_t;
  84. #define WGL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY d##fn_name##_t)fn_args \
  85. { Con::printf("Could not load this WGL function: %s", #fn_name); fn_body } \
  86. fn_type (APIENTRY * d##fn_name)fn_args = d##fn_name##_t; \
  87. extern fn_type (APIENTRY * dlld##fn_name)fn_args = d##fn_name##_t;
  88. #define WGLD3D_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY dwgl##fn_name##_t)fn_args \
  89. { Con::printf("Could not load this WGLD3D function: wgl%s", #fn_name); fn_body } \
  90. fn_type (APIENTRY * dwgl##fn_name)fn_args = dwgl##fn_name##_t; \
  91. extern fn_type (APIENTRY * dlldwgl##fn_name)fn_args = dwgl##fn_name##_t;
  92. #define WGLEXT_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY d##fn_name##_t)fn_args \
  93. { Con::printf("Could not load this WGLEXT function: %s", #fn_name); fn_body } \
  94. fn_type (APIENTRY * d##fn_name)fn_args = d##fn_name##_t;
  95. #else
  96. #define GL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY fn_name##_t)fn_args \
  97. { fn_body } \
  98. fn_type (APIENTRY * fn_name)fn_args = fn_name##_t; \
  99. extern fn_type (APIENTRY * dll##fn_name)fn_args = fn_name##_t;
  100. #define WGL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY d##fn_name##_t)fn_args \
  101. { fn_body } \
  102. fn_type (APIENTRY * d##fn_name)fn_args = d##fn_name##_t; \
  103. extern fn_type (APIENTRY * dlld##fn_name)fn_args = d##fn_name##_t;
  104. #define WGLD3D_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY dwgl##fn_name##_t)fn_args \
  105. { fn_body } \
  106. fn_type (APIENTRY * dwgl##fn_name)fn_args = dwgl##fn_name##_t; \
  107. extern fn_type (APIENTRY * dlldwgl##fn_name)fn_args = dwgl##fn_name##_t;
  108. #define WGLEXT_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_type (APIENTRY d##fn_name##_t)fn_args \
  109. { fn_body } \
  110. fn_type (APIENTRY * d##fn_name)fn_args = d##fn_name##_t;
  111. #endif
  112. //includes...
  113. #include "platform/GLCoreFunc.h"
  114. #include "platform/GLExtFunc.h"
  115. #include "platform/GLUFunc.h"
  116. #include "platformWin32/GLWinFunc.h"
  117. #include "platformWin32/GLWinExtFunc.h"
  118. //undefs...
  119. #undef GL_FUNCTION
  120. #undef WGL_FUNCTION
  121. #undef WGLD3D_FUNCTION
  122. #undef WGLEXT_FUNCTION
  123. // These functions won't be in the normal OGL dll, so don't give
  124. // errors about them because we know we'll be ok without them
  125. static bool isFnOk(const char* name)
  126. {
  127. if (dStrcmp(name, "glAvailableVertexBufferEXT") == 0 ||
  128. dStrcmp(name, "glAllocateVertexBufferEXT") == 0 ||
  129. dStrcmp(name, "glLockVertexBufferEXT") == 0 ||
  130. dStrcmp(name, "glUnlockVertexBufferEXT") == 0 ||
  131. dStrcmp(name, "glSetVertexBufferEXT") == 0 ||
  132. dStrcmp(name, "glOffsetVertexBufferEXT") == 0 ||
  133. dStrcmp(name, "glFillVertexBufferEXT") == 0 ||
  134. dStrcmp(name, "glFreeVertexBufferEXT") == 0)
  135. return true;
  136. return false;
  137. }
  138. //------------------------------------------------------------------
  139. //bind functions for each function prototype
  140. //------------------------------------------------------------------
  141. static bool bindGLFunction( void *&fnAddress, const char *name )
  142. {
  143. void* addr = (void*)(GetProcAddress( winState.hinstOpenGL, name ));
  144. bool ok = (bool)addr;
  145. if( !ok )
  146. {
  147. if (!isFnOk(name))
  148. Con::errorf(ConsoleLogEntry::General, " Missing OpenGL function '%s'", name);
  149. else
  150. ok = true;
  151. }
  152. else
  153. fnAddress = addr;
  154. return ok;
  155. }
  156. static bool bindGLUFunction( void *&fnAddress, const char *name )
  157. {
  158. void* addr = (void*)(GetProcAddress( winState.hinstGLU, name ));
  159. if( !addr )
  160. Con::errorf(ConsoleLogEntry::General, " Missing GLU function '%s'", name);
  161. else
  162. fnAddress = addr;
  163. return (addr != NULL);
  164. }
  165. static bool bindEXTFunction( void *&fnAddress, const char *name )
  166. {
  167. void* addr = (void*)(dwglGetProcAddress( name ));
  168. if( !addr )
  169. Con::errorf(ConsoleLogEntry::General, " Missing OpenGL extension '%s'", name);
  170. else
  171. fnAddress = addr;
  172. return (addr != NULL);
  173. }
  174. static bool bindWGLFunction( void *&fnAddress, const char *name )
  175. {
  176. void* addr = (void*)(GetProcAddress( winState.hinstOpenGL, name ));
  177. if( !addr )
  178. Con::errorf(ConsoleLogEntry::General, " Missing WGL function '%s'", name);
  179. else
  180. fnAddress = addr;
  181. return (addr != NULL);
  182. }
  183. static bool bindWGLEXTFunction( void *&fnAddress, const char *name )
  184. {
  185. void* addr = (void*)(dwglGetProcAddress( name ));
  186. if( !addr )
  187. Con::errorf(ConsoleLogEntry::General, " Missing WGLEXT function '%s'", name);
  188. else
  189. fnAddress = addr;
  190. return (addr != NULL);
  191. }
  192. //------------------------------------------------------------------
  193. //binds for each function group
  194. //------------------------------------------------------------------
  195. static bool bindGLFunctions()
  196. {
  197. bool result = true;
  198. #define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
  199. result &= bindGLFunction( *(void**)&dll##fn_name, #fn_name); \
  200. fn_name = dll##fn_name;
  201. #include "platform/GLCoreFunc.h"
  202. #undef GL_FUNCTION
  203. return result;
  204. }
  205. static bool bindGLUFunctions()
  206. {
  207. bool result = true;
  208. #define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
  209. result &= bindGLUFunction( *(void**)&dll##fn_name, #fn_name); \
  210. fn_name = dll##fn_name;
  211. #include "platform/GLUFunc.h"
  212. #undef GL_FUNCTION
  213. return result;
  214. }
  215. static bool bindEXTFunctions(U32 extMask)
  216. {
  217. bool result = true;
  218. #define GL_GROUP_BEGIN( flag ) \
  219. if( extMask & flag ) {
  220. #define GL_GROUP_END() }
  221. #define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
  222. result &= bindEXTFunction( *(void**)&dll##fn_name, #fn_name); \
  223. fn_name = dll##fn_name;
  224. #include "platform/GLExtFunc.h"
  225. #undef GL_FUNCTION
  226. #undef GL_GROUP_BEGIN
  227. #undef GL_GROUP_END
  228. return result;
  229. }
  230. static bool bindWGLFunctions(const char* prefix)
  231. {
  232. //ugh... the stupid D3D wrapper prefixes some functions
  233. //with either wd3d or wgl, so we have to account for that
  234. static char buff[200];
  235. bool result = true;
  236. #define WGLD3D_FUNCTION(fn_return, fn_name, fn_args, fn_value) \
  237. dSprintf(buff, 200, "%s%s", prefix, #fn_name); \
  238. result &= bindWGLFunction( *(void**)&dlldwgl##fn_name, buff); \
  239. dwgl##fn_name = dlldwgl##fn_name;
  240. #define WGL_FUNCTION(fn_return, fn_name, fn_args, fn_valud) \
  241. result &= bindWGLFunction( *(void**)&dlld##fn_name, #fn_name); \
  242. d##fn_name = dlld##fn_name;
  243. #include "platformWin32/GLWinFunc.h"
  244. #undef WGLD3D_FUNCTION
  245. #undef WGL_FUNCTION
  246. return result;
  247. }
  248. static bool bindWGLEXTFunctions(U32 extMask)
  249. {
  250. bool result = true;
  251. #define WGL_GROUP_BEGIN( flag ) \
  252. if( extMask & flag ) {
  253. #define WGL_GROUP_END() }
  254. #define WGLEXT_FUNCTION(fn_return, fn_name, fn_args, fn_value) result &= bindWGLEXTFunction( *(void**)&d##fn_name, #fn_name);
  255. #include "platformWin32/GLWinExtFunc.h"
  256. #undef WGLEXT_FUNCTION
  257. #undef WGL_GROUP_BEGIN
  258. #undef WGL_GROUP_END
  259. return result;
  260. }
  261. //------------------------------------------------------------------
  262. //unbind functions
  263. //------------------------------------------------------------------
  264. //GL core, GL_EXT/ARB, and GLU can all be done in one shot
  265. static void unbindGLFunctions()
  266. {
  267. #define GL_FUNCTION(fn_type, fn_name, fn_args, fn_body) fn_name = dll##fn_name = fn_name##_t;
  268. #include "platform/GLCoreFunc.h"
  269. #include "platform/GLExtFunc.h"
  270. #include "platform/GLUFunc.h"
  271. #undef GL_FUNCTION
  272. }
  273. static void unbindWGLFunctions()
  274. {
  275. #define WGL_FUNCTION(fn_type, fn_name, fn_args, fn_body) d##fn_name = dlld##fn_name = d##fn_name##_t;
  276. #define WGLD3D_FUNCTION(fn_type, fn_name, fn_args, fn_body) dwgl##fn_name = dlldwgl##fn_name = dwgl##fn_name##_t;
  277. #include "platformWin32/GLWinFunc.h"
  278. #undef WGLD3D_FUNCTION
  279. #undef WGL_FUNCTION
  280. }
  281. static void unbindWGLEXTFunctions()
  282. {
  283. #define WGLEXT_FUNCTION(fn_type, fn_name, fn_args, fn_body) d##fn_name = d##fn_name##_t;
  284. #include "platformWin32/GLWinExtFunc.h"
  285. #undef WGLEXT_FUNCTION
  286. }
  287. //------------------------------------------------------------------
  288. // GL_Shutdown - unbind all functions and unload libraries
  289. //------------------------------------------------------------------
  290. void GL_Shutdown( void )
  291. {
  292. if ( winState.hinstOpenGL )
  293. FreeLibrary( winState.hinstOpenGL );
  294. winState.hinstOpenGL = NULL;
  295. if ( winState.hinstGLU )
  296. FreeLibrary( winState.hinstGLU );
  297. winState.hinstGLU = NULL;
  298. unbindGLFunctions(); //we can do GL, GLU, and EXTs in the same function
  299. unbindWGLFunctions();//these have to be seperate
  300. unbindWGLEXTFunctions();
  301. gGLState.suppSwapInterval = false;
  302. }
  303. //---------------------------------------------------------
  304. // GL_Init - load OpenGL library and bind core GL/GLU/WGL functions
  305. //---------------------------------------------------------
  306. bool GL_Init( const char *dllname_gl, const char *dllname_glu )
  307. {
  308. if ( winState.hinstOpenGL && winState.hinstGLU)
  309. return true;
  310. #ifdef UNICODE
  311. UTF16 dn_gl[1024], dn_glu[1024];
  312. convertUTF8toUTF16((UTF8 *)dllname_gl, dn_gl, sizeof(dn_gl));
  313. convertUTF8toUTF16((UTF8 *)dllname_glu, dn_glu, sizeof(dn_glu));
  314. #endif
  315. // Load OpenGL DLL
  316. if (!winState.hinstOpenGL)
  317. {
  318. #ifdef UNICODE
  319. if ( ( winState.hinstOpenGL = LoadLibrary( dn_gl ) ) == 0 )
  320. #else
  321. if ( ( winState.hinstOpenGL = LoadLibrary( dllname_gl ) ) == 0 )
  322. #endif
  323. return false;
  324. }
  325. // Load OpenGL GLU DLL
  326. if ( !winState.hinstGLU )
  327. {
  328. #ifdef UNICODE
  329. if ( ( winState.hinstGLU = LoadLibrary( dn_glu ) ) == 0 )
  330. #else
  331. if ( ( winState.hinstGLU = LoadLibrary( dllname_glu ) ) == 0 )
  332. #endif
  333. return false;
  334. }
  335. if (!bindGLFunctions())
  336. Con::errorf("You are missing some OpenGL functions. That's bad.");
  337. if (!bindGLUFunctions())
  338. Con::errorf("You are missing some GLU functions. That's bad.");
  339. // these will have already been bound thru the OGL version
  340. if (dStrstr(dllname_gl, "d3d") == NULL)
  341. {
  342. if (!bindWGLFunctions("wgl"))
  343. Con::errorf("You are missing some WGL Functions. That's REALLY bad.");
  344. }
  345. else
  346. if (!bindWGLFunctions("wd3d"))
  347. Con::errorf("You are missing some WGL Functions. That's REALLY bad.");
  348. return true;
  349. }
  350. //---------------------------------------------------------
  351. // GL_EXT_Init - Initialize all GL/WGL extensions
  352. //---------------------------------------------------------
  353. bool GL_EXT_Init( )
  354. {
  355. // Load extensions...
  356. //
  357. const char* pExtString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
  358. gGLState.primMode = 0;
  359. U32 extBitMask = 0;
  360. // GL_EXT_paletted_texture
  361. if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_paletted_texture") != NULL)
  362. {
  363. extBitMask |= EXT_paletted_texture;
  364. gGLState.suppPalettedTexture = true;
  365. }
  366. else
  367. gGLState.suppPalettedTexture = false;
  368. // EXT_compiled_vertex_array
  369. if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_compiled_vertex_array") != NULL)
  370. {
  371. extBitMask |= EXT_compiled_vertex_array;
  372. gGLState.suppLockedArrays = true;
  373. }
  374. else
  375. {
  376. gGLState.suppLockedArrays = false;
  377. }
  378. // ARB_multitexture
  379. if (pExtString && dStrstr(pExtString, (const char*)"GL_ARB_multitexture") != NULL)
  380. {
  381. extBitMask |= ARB_multitexture;
  382. gGLState.suppARBMultitexture = true;
  383. } else {
  384. gGLState.suppARBMultitexture = false;
  385. }
  386. // EXT_blend_color
  387. if(pExtString && dStrstr(pExtString, (const char*)"GL_EXT_blend_color") != NULL)
  388. {
  389. extBitMask |= EXT_blend_color;
  390. gGLState.suppEXTblendcolor = true;
  391. } else {
  392. gGLState.suppEXTblendcolor = false;
  393. }
  394. // EXT_blend_minmax
  395. if(pExtString && dStrstr(pExtString, (const char*)"GL_EXT_blend_minmax") != NULL)
  396. {
  397. extBitMask |= EXT_blend_color;
  398. gGLState.suppEXTblendminmax = true;
  399. } else {
  400. gGLState.suppEXTblendminmax = false;
  401. }
  402. // EXT_fog_coord
  403. if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_fog_coord") != NULL)
  404. {
  405. extBitMask |= EXT_fog_coord;
  406. gGLState.suppFogCoord = true;
  407. } else {
  408. gGLState.suppFogCoord = false;
  409. }
  410. // EXT_texture_compression_s3tc
  411. if (pExtString && dStrstr(pExtString, (const char*)"GL_EXT_texture_compression_s3tc") != NULL)
  412. gGLState.suppS3TC = true;
  413. else
  414. gGLState.suppS3TC = false;
  415. // ARB_texture_compression
  416. if (pExtString && dStrstr(pExtString, (const char*)"GL_ARB_texture_compression") != NULL)
  417. {
  418. extBitMask |= ARB_texture_compression;
  419. gGLState.suppTextureCompression = true;
  420. } else {
  421. gGLState.suppTextureCompression = false;
  422. }
  423. // NV_vertex_array_range
  424. if (pExtString && dStrstr(pExtString, (const char*)"NV_vertex_array_range") != NULL)
  425. {
  426. extBitMask |= NV_vertex_array_range;
  427. gGLState.suppVertexArrayRange = true;
  428. }
  429. else
  430. gGLState.suppVertexArrayRange = false;
  431. // 3DFX_texture_compression_FXT1
  432. if (pExtString && dStrstr(pExtString, (const char*)"3DFX_texture_compression_FXT1") != NULL)
  433. gGLState.suppFXT1 = true;
  434. else
  435. gGLState.suppFXT1 = false;
  436. if (!bindEXTFunctions(extBitMask))
  437. Con::warnf("You are missing some OpenGL Extensions. This is bad.");
  438. // Binary states, i.e., no supporting functions
  439. // EXT_packed_pixels
  440. // EXT_texture_env_combine
  441. //
  442. // dhc note: a number of these can have multiple matching 'versions', private, ext, and arb.
  443. gGLState.suppPackedPixels = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_packed_pixels") != NULL) : false;
  444. gGLState.suppTextureEnvCombine = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_env_combine") != NULL) : false;
  445. gGLState.suppEdgeClamp = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_edge_clamp") != NULL) : false;
  446. gGLState.suppEdgeClamp |= pExtString? (dStrstr(pExtString, (const char*)"GL_SGIS_texture_edge_clamp") != NULL) : false;
  447. gGLState.suppTexEnvAdd = pExtString? (dStrstr(pExtString, (const char*)"GL_ARB_texture_env_add") != NULL) : false;
  448. gGLState.suppTexEnvAdd |= pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_env_add") != NULL) : false;
  449. // Anisotropic filtering
  450. gGLState.suppTexAnisotropic = pExtString? (dStrstr(pExtString, (const char*)"GL_EXT_texture_filter_anisotropic") != NULL) : false;
  451. if (gGLState.suppTexAnisotropic)
  452. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGLState.maxAnisotropy);
  453. if (gGLState.suppARBMultitexture)
  454. glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gGLState.maxTextureUnits);
  455. else
  456. gGLState.maxTextureUnits = 1;
  457. //----------------------
  458. //WGL extensions....
  459. U32 wglExtMask = 0;
  460. // Swap interval
  461. if (pExtString && dStrstr(pExtString, (const char*)"WGL_EXT_swap_control") != NULL)
  462. {
  463. wglExtMask |= WGL_EXT_swap_control;
  464. gGLState.suppSwapInterval = true;
  465. }
  466. else
  467. {
  468. gGLState.suppSwapInterval = false;
  469. }
  470. if (!bindWGLEXTFunctions(wglExtMask))
  471. {
  472. Con::warnf("You are missing some WGLEXT Functions. That's possibly VERY bad.");
  473. }
  474. Con::printf("OpenGL Init: Enabled Extensions");
  475. if (gGLState.suppARBMultitexture) Con::printf(" ARB_multitexture (Max Texture Units: %d)", gGLState.maxTextureUnits);
  476. if (gGLState.suppEXTblendcolor) Con::printf(" EXT_blend_color");
  477. if (gGLState.suppEXTblendminmax) Con::printf(" EXT_blend_minmax");
  478. if (gGLState.suppPalettedTexture) Con::printf(" EXT_paletted_texture");
  479. if (gGLState.suppLockedArrays) Con::printf(" EXT_compiled_vertex_array");
  480. if (gGLState.suppVertexArrayRange) Con::printf(" NV_vertex_array_range");
  481. if (gGLState.suppTextureEnvCombine) Con::printf(" EXT_texture_env_combine");
  482. if (gGLState.suppPackedPixels) Con::printf(" EXT_packed_pixels");
  483. if (gGLState.suppFogCoord) Con::printf(" EXT_fog_coord");
  484. if (gGLState.suppTextureCompression) Con::printf(" ARB_texture_compression");
  485. if (gGLState.suppS3TC) Con::printf(" EXT_texture_compression_s3tc");
  486. if (gGLState.suppFXT1) Con::printf(" 3DFX_texture_compression_FXT1");
  487. if (gGLState.suppTexEnvAdd) Con::printf(" (ARB|EXT)_texture_env_add");
  488. if (gGLState.suppTexAnisotropic) Con::printf(" EXT_texture_filter_anisotropic (Max anisotropy: %g)", gGLState.maxAnisotropy);
  489. if (gGLState.suppSwapInterval) Con::printf(" WGL_EXT_swap_control");
  490. Con::warnf("OpenGL Init: Disabled Extensions");
  491. if (!gGLState.suppARBMultitexture) Con::warnf(" ARB_multitexture");
  492. if (!gGLState.suppEXTblendcolor) Con::warnf(" EXT_blend_color");
  493. if (!gGLState.suppEXTblendminmax) Con::warnf(" EXT_blend_minmax");
  494. if (!gGLState.suppPalettedTexture) Con::warnf(" EXT_paletted_texture");
  495. if (!gGLState.suppLockedArrays) Con::warnf(" EXT_compiled_vertex_array");
  496. if (!gGLState.suppVertexArrayRange) Con::warnf(" NV_vertex_array_range");
  497. if (!gGLState.suppTextureEnvCombine) Con::warnf(" EXT_texture_env_combine");
  498. if (!gGLState.suppPackedPixels) Con::warnf(" EXT_packed_pixels");
  499. if (!gGLState.suppFogCoord) Con::warnf(" EXT_fog_coord");
  500. if (!gGLState.suppTextureCompression) Con::warnf(" ARB_texture_compression");
  501. if (!gGLState.suppS3TC) Con::warnf(" EXT_texture_compression_s3tc");
  502. if (!gGLState.suppFXT1) Con::warnf(" 3DFX_texture_compression_FXT1");
  503. if (!gGLState.suppTexEnvAdd) Con::warnf(" (ARB|EXT)_texture_env_add");
  504. if (!gGLState.suppTexAnisotropic) Con::warnf(" EXT_texture_filter_anisotropic");
  505. if (!gGLState.suppSwapInterval) Con::warnf(" WGL_EXT_swap_control");
  506. Con::printf("");
  507. // Set some console variables:
  508. Con::setBoolVariable( "$FogCoordSupported", gGLState.suppFogCoord );
  509. Con::setBoolVariable( "$TextureCompressionSupported", gGLState.suppTextureCompression );
  510. Con::setBoolVariable( "$AnisotropySupported", gGLState.suppTexAnisotropic );
  511. Con::setBoolVariable( "$PalettedTextureSupported", gGLState.suppPalettedTexture );
  512. Con::setBoolVariable( "$SwapIntervalSupported", gGLState.suppSwapInterval );
  513. if (!gGLState.suppPalettedTexture && Con::getBoolVariable("$pref::OpenGL::forcePalettedTexture",false))
  514. {
  515. Con::setBoolVariable("$pref::OpenGL::forcePalettedTexture", false);
  516. Con::setBoolVariable("$pref::OpenGL::force16BitTexture", true);
  517. }
  518. return true;
  519. }