EmscriptenGL.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. // Portions Copyright (c) 2014 James S Urquhart
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to
  7. // deal in the Software without restriction, including without limitation the
  8. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9. // sell copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. // IN THE SOFTWARE.
  22. //-----------------------------------------------------------------------------
  23. // Many OSX frameworks include OpenTransport, and OT's new operator conflicts
  24. // with our redefinition of 'new', so we have to pre-include platformAndroid.h,
  25. // which contains the workaround.
  26. #include "platformEmscripten/platformEmscripten.h"
  27. #include "platformEmscripten/platformGL.h"
  28. #include "console/console.h"
  29. #include "graphics/dgl.h"
  30. #define TEST_FOR_OPENGL_ERRORS 0;
  31. GLState gGLState;
  32. bool gOpenGLDisablePT = false;
  33. bool gOpenGLDisableCVA = false;
  34. bool gOpenGLDisableTEC = false;
  35. bool gOpenGLDisableARBMT = false;
  36. bool gOpenGLDisableFC = true; //false;
  37. bool gOpenGLDisableTCompress = false;
  38. bool gOpenGLNoEnvColor = false;
  39. float gOpenGLGammaCorrection = 0.5;
  40. bool gOpenGLNoDrawArraysAlpha = false;
  41. // Find out which extensions are available for this renderer.
  42. void getGLCapabilities( )
  43. {
  44. AssertFatal(platState.engine, "getGLCapabilities() was called before a monitor was chosen!");
  45. // silently create an opengl context on the current display,
  46. // so that we can get valid renderer and capability info.
  47. // we save off the current context so that we can silently restore it.
  48. // the user should not be aware of this little shuffle.
  49. //CGLContextObj curr_ctx = CGLGetCurrentContext ();
  50. //CGLContextObj temp_ctx = getContextForCapsCheck();
  51. /*
  52. if(!temp_ctx)
  53. {
  54. Con::errorf("OpenGL may not be set up correctly!");
  55. return;
  56. }
  57. */
  58. //CGLSetCurrentContext(temp_ctx);
  59. // Get the OpenGL info strings we'll need
  60. const char* pVendString = (const char*) glGetString( GL_VENDOR );
  61. const char* pRendString = (const char*) glGetString( GL_RENDERER );
  62. const char* pVersString = (const char*) glGetString( GL_VERSION );
  63. const char* pExtString = (const char*) glGetString( GL_EXTENSIONS );
  64. // Output some driver info to the console:
  65. Con::printf( "OpenGL driver information:" );
  66. if ( pVendString )
  67. Con::printf( " Vendor: %s", pVendString );
  68. if ( pRendString )
  69. Con::printf( " Renderer: %s", pRendString );
  70. if ( pVersString )
  71. Con::printf( " Version: %s", pVersString );
  72. // pre-clear the structure
  73. dMemset(&gGLState, 0, sizeof(gGLState));
  74. if(pExtString)
  75. {
  76. // EXT_paletted_texture ========================================
  77. if (dStrstr(pExtString, (const char*)"GL_EXT_paletted_texture") != NULL)
  78. gGLState.suppPalettedTexture = true;
  79. // EXT_compiled_vertex_array ========================================
  80. gGLState.suppLockedArrays = false;
  81. if (dStrstr(pExtString, (const char*)"GL_EXT_compiled_vertex_array") != NULL)
  82. gGLState.suppLockedArrays = true;
  83. // ARB_multitexture ========================================
  84. if (dStrstr(pExtString, (const char*)"GL_ARB_multitexture") != NULL)
  85. gGLState.suppARBMultitexture = true;
  86. // EXT_blend_color
  87. if(dStrstr(pExtString, (const char*)"GL_EXT_blend_color") != NULL)
  88. gGLState.suppEXTblendcolor = true;
  89. // EXT_blend_minmax
  90. if(dStrstr(pExtString, (const char*)"GL_EXT_blend_minmax") != NULL)
  91. gGLState.suppEXTblendminmax = true;
  92. // NV_vertex_array_range ========================================
  93. // does not appear to be supported by apple, at all. ( as of 10.4.3 )
  94. // GL_APPLE_vertex_array_range is similar, and may be nearly identical.
  95. if (dStrstr(pExtString, (const char*)"GL_NV_vertex_array_range") != NULL)
  96. gGLState.suppVertexArrayRange = true;
  97. // EXT_fog_coord ========================================
  98. if (dStrstr(pExtString, (const char*)"GL_EXT_fog_coord") != NULL)
  99. gGLState.suppFogCoord = true;
  100. // ARB_texture_compression ========================================
  101. if (dStrstr(pExtString, (const char*)"GL_ARB_texture_compression") != NULL)
  102. gGLState.suppTextureCompression = true;
  103. // 3DFX_texture_compression_FXT1 ========================================
  104. if (dStrstr(pExtString, (const char*)"GL_3DFX_texture_compression_FXT1") != NULL)
  105. gGLState.suppFXT1 = true;
  106. // EXT_texture_compression_S3TC ========================================
  107. if (dStrstr(pExtString, (const char*)"GL_EXT_texture_compression_s3tc") != NULL)
  108. gGLState.suppS3TC = true;
  109. // EXT_vertex_buffer ========================================
  110. // This extension is deprecated, and not supported by Apple. ( 10.4.3 )
  111. // Instead, the ARB Vertex Buffer extension is supported.
  112. // The new extension has a different API, so TGE should be updated to use it.
  113. if (dStrstr(pExtString, (const char*)"GL_EXT_vertex_buffer") != NULL)
  114. gGLState.suppVertexBuffer = true;
  115. // Anisotropic filtering ========================================
  116. gGLState.suppTexAnisotropic = (dStrstr(pExtString, (const char*)"GL_EXT_texture_filter_anisotropic") != NULL);
  117. if (gGLState.suppTexAnisotropic)
  118. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGLState.maxAnisotropy);
  119. // Binary states, i.e., no supporting functions ========================================
  120. // NOTE:
  121. // Some of these have multiple representations, via EXT and|or ARB and|or NV and|or SGIS ... etc.
  122. // Check all relative versions.
  123. gGLState.suppPackedPixels = (dStrstr(pExtString, (const char*)"GL_EXT_packed_pixels") != NULL);
  124. gGLState.suppPackedPixels |= (dStrstr(pExtString, (const char*)"GL_APPLE_packed_pixel") != NULL);
  125. gGLState.suppTextureEnvCombine = (dStrstr(pExtString, (const char*)"GL_EXT_texture_env_combine") != NULL);
  126. gGLState.suppTextureEnvCombine|= (dStrstr(pExtString, (const char*)"GL_ARB_texture_env_combine") != NULL);
  127. gGLState.suppEdgeClamp = (dStrstr(pExtString, (const char*)"GL_EXT_texture_edge_clamp") != NULL);
  128. gGLState.suppEdgeClamp |= (dStrstr(pExtString, (const char*)"GL_SGIS_texture_edge_clamp") != NULL);
  129. gGLState.suppEdgeClamp |= (dStrstr(pExtString, (const char*)"GL_ARB_texture_border_clamp") != NULL);
  130. gGLState.suppEdgeClamp = true;
  131. gGLState.suppTexEnvAdd = (dStrstr(pExtString, (const char*)"GL_ARB_texture_env_add") != NULL);
  132. gGLState.suppTexEnvAdd |= (dStrstr(pExtString, (const char*)"GL_EXT_texture_env_add") != NULL);
  133. }
  134. // Texture combine units ========================================
  135. // if (gGLState.suppARBMultitexture)
  136. // glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gGLState.maxTextureUnits);
  137. gGLState.suppARBMultitexture = false;
  138. gGLState.maxTextureUnits = 1;
  139. // Swap interval ========================================
  140. // Mac inherently supports a swap interval via AGL-set-integer.
  141. gGLState.suppSwapInterval = true;
  142. // FSAA support, TODO: check for ARB multisample support
  143. // multisample support should be checked via CGL
  144. gGLState.maxFSAASamples = 4;
  145. // dump found extensions to the console...
  146. Con::printf("OpenGL Init: Enabled Extensions");
  147. if (gGLState.suppARBMultitexture) Con::printf(" ARB_multitexture (Max Texture Units: %d)", gGLState.maxTextureUnits);
  148. if (gGLState.suppEXTblendcolor) Con::printf(" EXT_blend_color");
  149. if (gGLState.suppEXTblendminmax) Con::printf(" EXT_blend_minmax");
  150. if (gGLState.suppPalettedTexture) Con::printf(" EXT_paletted_texture");
  151. if (gGLState.suppLockedArrays) Con::printf(" EXT_compiled_vertex_array");
  152. if (gGLState.suppVertexArrayRange) Con::printf(" NV_vertex_array_range");
  153. if (gGLState.suppTextureEnvCombine) Con::printf(" EXT_texture_env_combine");
  154. if (gGLState.suppPackedPixels) Con::printf(" EXT_packed_pixels");
  155. if (gGLState.suppFogCoord) Con::printf(" EXT_fog_coord");
  156. if (gGLState.suppTextureCompression) Con::printf(" ARB_texture_compression");
  157. if (gGLState.suppS3TC) Con::printf(" EXT_texture_compression_s3tc");
  158. if (gGLState.suppFXT1) Con::printf(" 3DFX_texture_compression_FXT1");
  159. if (gGLState.suppTexEnvAdd) Con::printf(" (ARB|EXT)_texture_env_add");
  160. if (gGLState.suppTexAnisotropic) Con::printf(" EXT_texture_filter_anisotropic (Max anisotropy: %f)", gGLState.maxAnisotropy);
  161. if (gGLState.suppSwapInterval) Con::printf(" Vertical Sync");
  162. if (gGLState.maxFSAASamples) Con::printf(" ATI_FSAA");
  163. Con::warnf("OpenGL Init: Disabled Extensions");
  164. if (!gGLState.suppARBMultitexture) Con::warnf(" ARB_multitexture");
  165. if (!gGLState.suppEXTblendcolor) Con::warnf(" EXT_blend_color");
  166. if (!gGLState.suppEXTblendminmax) Con::warnf(" EXT_blend_minmax");
  167. if (!gGLState.suppPalettedTexture) Con::warnf(" EXT_paletted_texture");
  168. if (!gGLState.suppLockedArrays) Con::warnf(" EXT_compiled_vertex_array");
  169. if (!gGLState.suppVertexArrayRange) Con::warnf(" NV_vertex_array_range");
  170. if (!gGLState.suppTextureEnvCombine) Con::warnf(" EXT_texture_env_combine");
  171. if (!gGLState.suppPackedPixels) Con::warnf(" EXT_packed_pixels");
  172. if (!gGLState.suppFogCoord) Con::warnf(" EXT_fog_coord");
  173. if (!gGLState.suppTextureCompression) Con::warnf(" ARB_texture_compression");
  174. if (!gGLState.suppS3TC) Con::warnf(" EXT_texture_compression_s3tc");
  175. if (!gGLState.suppFXT1) Con::warnf(" 3DFX_texture_compression_FXT1");
  176. if (!gGLState.suppTexEnvAdd) Con::warnf(" (ARB|EXT)_texture_env_add");
  177. if (!gGLState.suppTexAnisotropic) Con::warnf(" EXT_texture_filter_anisotropic");
  178. if (!gGLState.suppSwapInterval) Con::warnf(" Vertical Sync");
  179. if (!gGLState.maxFSAASamples) Con::warnf(" ATI_FSAA");
  180. Con::printf("");
  181. // Set some console variables:
  182. Con::setBoolVariable( "$FogCoordSupported", gGLState.suppFogCoord );
  183. Con::setBoolVariable( "$TextureCompressionSupported", gGLState.suppTextureCompression );
  184. Con::setBoolVariable( "$AnisotropySupported", gGLState.suppTexAnisotropic );
  185. Con::setBoolVariable( "$PalettedTextureSupported", gGLState.suppPalettedTexture );
  186. Con::setBoolVariable( "$SwapIntervalSupported", gGLState.suppSwapInterval );
  187. if (!gGLState.suppPalettedTexture && Con::getBoolVariable("$pref::OpenGL::forcePalettedTexture",false))
  188. {
  189. Con::setBoolVariable("$pref::OpenGL::forcePalettedTexture", false);
  190. Con::setBoolVariable("$pref::OpenGL::force16BitTexture", true);
  191. }
  192. // get fsaa samples. default to normal, no antialiasing
  193. // TODO: clamp this against ARB_multisample capabilities.
  194. gFSAASamples = Con::getIntVariable("$pref::OpenGL::numFSAASamples", 1);
  195. }
  196. void dglSetFSAASamples(GLint aasamp)
  197. {
  198. if (gGLState.maxFSAASamples < 2)
  199. return;
  200. // fix out of range values
  201. if (aasamp < 1)
  202. aasamp = 1;
  203. else if (aasamp == 3)
  204. aasamp = 2;
  205. else if (aasamp > 4)
  206. aasamp = 4;
  207. /*
  208. THIS IS CARBON
  209. aglSetInteger(platState.ctx, ATI_FSAA_LEVEL, &aasamp);
  210. IT NEEDS OT BE REPLACED WITH SOMETHING LIKE THIS:
  211. const char *glRenderer = (const char *) glGetString(GL_RENDERER);
  212. if (strstr(glRenderer, "ATI"))
  213. {
  214. NSOpenGLContext* testContext; /// <<< Need to get ahold of the current context
  215. [testContext setValues:&aasamp forParameter:ATI_FSAA_LEVEL];
  216. }
  217. */
  218. Con::printf(">>Number of FSAA samples is now [%d].", aasamp);
  219. Con::setIntVariable("$pref::OpenGL::numFSAASamples", aasamp);
  220. }
  221. #ifdef DUMMY_GL
  222. // declare stub functions
  223. #define GL_FUNCTION(fn_return, fn_name, fn_args, fn_value) fn_return fn_name fn_args{ printf(" fn_name \n"); fn_value }
  224. #include "platform/GLCoreFunc.h"
  225. #include "platform/GLExtFunc.h"
  226. #undef GL_FUNCTION
  227. // point gl function pointers at stub functions
  228. /*#define GL_FUNCTION(fn_return,fn_name,fn_args, fn_value) fn_return (*fn_name)fn_args = stub_##fn_name;
  229. #include "platform/GLCoreFunc.h"
  230. #include "platform/GLExtFunc.h"
  231. #undef GL_FUNCTION
  232. */
  233. #else
  234. // stub out these
  235. GLAPI void GLAPIENTRY glPointSize( GLfloat size )
  236. {
  237. }
  238. GLAPI void GLAPIENTRY glClipPlane( GLenum plane, const GLdouble *equation )
  239. {
  240. }
  241. GLAPI GLboolean GLAPIENTRY glAreTexturesResident( GLsizei n, const GLuint *textures, GLboolean *residences )
  242. {
  243. return true;
  244. }
  245. GLAPI void GLAPIENTRY glColor3i( GLint red, GLint green, GLint blue )
  246. {
  247. glColor3f(255.0f/red, 255.0f/green, 255.0f/blue);
  248. }
  249. GLAPI void GLAPIENTRY glRecti( GLint x1, GLint y1, GLint x2, GLint y2 )
  250. {
  251. //glRectf(x1, y2, x2, y2);
  252. }
  253. #endif
  254. void gluOrtho2D( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top )
  255. {
  256. glOrtho( left, right, bottom, top, -1.0f, 1.0f );
  257. int glError;
  258. glError = TEST_FOR_OPENGL_ERRORS
  259. }
  260. GLint gluProject( GLdouble objx, GLdouble objy, GLdouble objz, const F64 *model, const F64 * proj, const GLint * vp, F64 * winx, F64 * winy, F64 * winz )
  261. {
  262. Vector4F v = Vector4F( objx, objy, objz, 1.0f );
  263. MatrixF pmat = MatrixF( false );
  264. for (int i=0; i<16; i++) { ((F32*)pmat)[i] = (float)proj[i]; }
  265. MatrixF mmat = MatrixF( false );
  266. for (int i=0; i<16; i++) { ((F32*)mmat)[i] = (float)model[i]; }
  267. //Luma: Projection fix
  268. mmat.transpose();
  269. pmat.transpose();
  270. (pmat.mul(mmat)).mul(v);
  271. //Luma: Projection fix
  272. if(v.w == 0.0f)
  273. {
  274. return GL_FALSE;
  275. }
  276. F32 invW = 1.0f / v.w;
  277. v.x *= invW;
  278. v.y *= invW;
  279. v.z *= invW;
  280. *winx = (GLfloat)vp[0] + (GLfloat)vp[2] * (v.x + 1.0f) * 0.5f;
  281. *winy = (GLfloat)vp[1] + (GLfloat)vp[3] * (v.y + 1.0f) * 0.5f;
  282. *winz = (v.z + 1.0f) * 0.5f;
  283. int glError;
  284. glError = TEST_FOR_OPENGL_ERRORS
  285. return GL_TRUE;
  286. }
  287. GLint gluUnProject( GLdouble winx, GLdouble winy, GLdouble winz, const F64 *model, const F64 * proj, const GLint * vp, F64 * x, F64 * y, F64 * z )
  288. {
  289. Vector4F v = Vector4F( 2.0f*(winx-vp[0])/vp[2] - 1.0f, 2.0f*(winy-vp[1])/vp[2] - 1.0f, 2.0f*vp[2] - 1.0f, 1.0f );
  290. MatrixF pmat = MatrixF( false );
  291. for (int i=0; i<16; i++) { ((F32*)pmat)[i] = (float)proj[i]; }
  292. MatrixF mmat = MatrixF( false );
  293. for (int i=0; i<16; i++) { ((F32*)mmat)[i] = (float)model[i]; }
  294. mmat = pmat.mul(mmat);
  295. mmat = mmat.inverse();
  296. mmat.mul( v );
  297. *x = v.x;
  298. *y = v.y;
  299. *z = v.z;
  300. int glError;
  301. glError = TEST_FOR_OPENGL_ERRORS
  302. return GL_TRUE;
  303. }