From a19f7df00c5404437412fb037ddded67b03d13f8 Mon Sep 17 00:00:00 2001 From: juj Date: Thu, 29 Aug 2024 17:10:36 +0300 Subject: [PATCH] Add support for WebGL extensions EXT_clip_control, EXT_depth_clamp, ... (#20841) Add support for WebGL extensions EXT_clip_control, EXT_depth_clamp, EXT_polygon_offset_clamp and WEBGL_polygon_mode. --- ChangeLog.md | 2 + src/library_html5_webgl.js | 15 +- src/library_sigs.js | 3 + src/library_webgl.js | 64 +++++- system/include/emscripten/html5_webgl.h | 6 + system/include/webgl/webgl1_ext.h | 206 ++++++++++++++++-- system/lib/gl/webgl1.c | 3 + .../browser/webgl2_simple_enable_extensions.c | 9 + 8 files changed, 284 insertions(+), 24 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 2b625630451d9..1b47dfbe91d09 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -20,6 +20,8 @@ See docs/process.md for more on how version tagging works. 3.1.66 (in development) ----------------------- +- Added support for WebGL extensions EXT_clip_control, EXT_depth_clamp, + EXT_polygon_offset_clamp and WEBGL_polygon_mode (#20841) 3.1.65 - 08/22/24 ----------------- diff --git a/src/library_html5_webgl.js b/src/library_html5_webgl.js index 5b31fa15cca5e..148f8f309d715 100644 --- a/src/library_html5_webgl.js +++ b/src/library_html5_webgl.js @@ -311,6 +311,9 @@ var LibraryHtml5WebGL = { '$webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance', '$webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance', #endif + '$webgl_enable_EXT_polygon_offset_clamp', + '$webgl_enable_EXT_clip_control', + '$webgl_enable_WEBGL_polygon_mode', '$webgl_enable_WEBGL_multi_draw', #endif ], @@ -339,21 +342,23 @@ var LibraryHtml5WebGL = { #endif if (extString == 'WEBGL_multi_draw') webgl_enable_WEBGL_multi_draw(GLctx); + if (extString == 'EXT_polygon_offset_clamp') webgl_enable_EXT_polygon_offset_clamp(GLctx); + if (extString == 'EXT_clip_control') webgl_enable_EXT_clip_control(GLctx); + if (extString == 'WEBGL_polygon_mode') webgl_enable_WEBGL_polygon_mode(GLctx); -#else - -#if ASSERTIONS || GL_ASSERTIONS +#elif ASSERTIONS || GL_ASSERTIONS if (['ANGLE_instanced_arrays', 'OES_vertex_array_object', 'WEBGL_draw_buffers', 'WEBGL_multi_draw', + 'EXT_polygon_offset_clamp', + 'EXT_clip_control', + 'WEBGL_polygon_mode', 'WEBGL_draw_instanced_base_vertex_base_instance', 'WEBGL_multi_draw_instanced_base_vertex_base_instance'].includes(extString)) { err('When building with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=0, function emscripten_webgl_enable_extension() cannot be used to enable extension ' + extString + '! Use one of the functions emscripten_webgl_enable_*() to enable it!'); } -#endif - #endif var ext = context.GLctx.getExtension(extString); diff --git a/src/library_sigs.js b/src/library_sigs.js index c978af4958e6f..de13d90c1cc91 100644 --- a/src/library_sigs.js +++ b/src/library_sigs.js @@ -858,11 +858,14 @@ sigs = { emscripten_webgl_do_create_context__sig: 'ppp', emscripten_webgl_do_get_current_context__sig: 'p', emscripten_webgl_enable_ANGLE_instanced_arrays__sig: 'ip', + emscripten_webgl_enable_EXT_clip_control__sig: 'ip', + emscripten_webgl_enable_EXT_polygon_offset_clamp__sig: 'ip', emscripten_webgl_enable_OES_vertex_array_object__sig: 'ip', emscripten_webgl_enable_WEBGL_draw_buffers__sig: 'ip', emscripten_webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance__sig: 'ip', emscripten_webgl_enable_WEBGL_multi_draw__sig: 'ip', emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance__sig: 'ip', + emscripten_webgl_enable_WEBGL_polygon_mode__sig: 'ip', emscripten_webgl_enable_extension__sig: 'ipp', emscripten_webgl_get_context_attributes__sig: 'ipp', emscripten_webgl_get_current_context__sig: 'p', diff --git a/src/library_webgl.js b/src/library_webgl.js index 6b35a6402fc03..ff07e2a48ae3b 100644 --- a/src/library_webgl.js +++ b/src/library_webgl.js @@ -96,6 +96,9 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; $webgl_enable_ANGLE_instanced_arrays: (ctx) => { // Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2. var ext = ctx.getExtension('ANGLE_instanced_arrays'); + // Because this extension is a core function in WebGL 2, assign the extension entry points in place of + // where the core functions will reside in WebGL 2. This way the calling code can call these without + // having to dynamically branch depending if running against WebGL 1 or WebGL 2. if (ext) { ctx['vertexAttribDivisor'] = (index, divisor) => ext['vertexAttribDivisorANGLE'](index, divisor); ctx['drawArraysInstanced'] = (mode, first, count, primcount) => ext['drawArraysInstancedANGLE'](mode, first, count, primcount); @@ -143,6 +146,27 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; emscripten_webgl_enable_WEBGL_multi_draw__deps: ['$webgl_enable_WEBGL_multi_draw'], emscripten_webgl_enable_WEBGL_multi_draw: (ctx) => webgl_enable_WEBGL_multi_draw(GL.contexts[ctx].GLctx), + $webgl_enable_EXT_polygon_offset_clamp: (ctx) => { + return !!(ctx.extPolygonOffsetClamp = ctx.getExtension('EXT_polygon_offset_clamp')); + }, + + emscripten_webgl_enable_EXT_polygon_offset_clamp__deps: ['$webgl_enable_EXT_polygon_offset_clamp'], + emscripten_webgl_enable_EXT_polygon_offset_clamp: (ctx) => webgl_enable_EXT_polygon_offset_clamp(GL.contexts[ctx].GLctx), + + $webgl_enable_EXT_clip_control: (ctx) => { + return !!(ctx.extClipControl = ctx.getExtension('EXT_clip_control')); + }, + + emscripten_webgl_enable_EXT_clip_control__deps: ['$webgl_enable_EXT_clip_control'], + emscripten_webgl_enable_EXT_clip_control: (ctx) => webgl_enable_EXT_clip_control(GL.contexts[ctx].GLctx), + + $webgl_enable_WEBGL_polygon_mode: (ctx) => { + return !!(ctx.webglPolygonMode = ctx.getExtension('WEBGL_polygon_mode')); + }, + + emscripten_webgl_enable_WEBGL_polygon_mode__deps: ['$webgl_enable_WEBGL_polygon_mode'], + emscripten_webgl_enable_WEBGL_polygon_mode: (ctx) => webgl_enable_WEBGL_polygon_mode(GL.contexts[ctx].GLctx), + $getEmscriptenSupportedExtensions__internal: true, $getEmscriptenSupportedExtensions: (ctx) => { // Restrict the list of advertised extensions to those that we actually @@ -177,9 +201,11 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; 'WEBGL_clip_cull_distance', #endif // WebGL 1 and WebGL 2 extensions + 'EXT_clip_control', 'EXT_color_buffer_half_float', 'EXT_depth_clamp', 'EXT_float_blend', + 'EXT_polygon_offset_clamp', 'EXT_texture_compression_bptc', 'EXT_texture_compression_rgtc', 'EXT_texture_filter_anisotropic', @@ -195,6 +221,7 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; 'WEBGL_debug_shaders', 'WEBGL_lose_context', 'WEBGL_multi_draw', + 'WEBGL_polygon_mode' ]; // .getSupportedExtensions() can return null if context is lost, so coerce to empty array. return (ctx.getSupportedExtensions() || []).filter(ext => supportedExtensions.includes(ext)); @@ -219,6 +246,9 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; '$webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance', '$webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance', #endif + '$webgl_enable_EXT_polygon_offset_clamp', + '$webgl_enable_EXT_clip_control', + '$webgl_enable_WEBGL_polygon_mode', '$webgl_enable_WEBGL_multi_draw', '$getEmscriptenSupportedExtensions', #endif // GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS @@ -802,6 +832,7 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; } disableHalfFloatExtensionIfBroken(ctx); #endif + return handle; }, @@ -1184,6 +1215,11 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; context.anisotropicExt = GLctx.getExtension('EXT_texture_filter_anisotropic'); #endif + // Extensions that are available in both WebGL 1 and WebGL 2 + webgl_enable_WEBGL_multi_draw(GLctx); + webgl_enable_EXT_polygon_offset_clamp(GLctx); + webgl_enable_EXT_clip_control(GLctx); + webgl_enable_WEBGL_polygon_mode(GLctx); #if MIN_WEBGL_VERSION == 1 // Extensions that are only available in WebGL 1 (the calls will be no-ops // if called on a WebGL 2 context active) @@ -1195,9 +1231,7 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; // Extensions that are available from WebGL >= 2 (no-op if called on a WebGL 1 context active) webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx); webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx); -#endif -#if MAX_WEBGL_VERSION >= 2 // On WebGL 2, EXT_disjoint_timer_query is replaced with an alternative // that's based on core APIs, and exposes only the queryCounterEXT() // entrypoint. @@ -1214,8 +1248,6 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query"); } - webgl_enable_WEBGL_multi_draw(GLctx); - getEmscriptenSupportedExtensions(GLctx).forEach((ext) => { // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders // are not enabled by default. @@ -4214,6 +4246,30 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}}; return 1; }, #endif + + glPolygonOffsetClampEXT__sig: 'vfff', + glPolygonOffsetClampEXT: (factor, units, clamp) => { +#if GL_ASSERTIONS + assert(GLctx.extPolygonOffsetClamp, "EXT_polygon_offset_clamp not supported, or not enabled. Before calling glPolygonOffsetClampEXT(), call emscripten_webgl_enable_EXT_polygon_offset_clamp() to enable this extension, and verify that it returns true to indicate support. (alternatively, build with -sGL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS=1 to enable all GL extensions by default)"); +#endif + GLctx.extPolygonOffsetClamp['polygonOffsetClampEXT'](factor, units, clamp); + }, + + glClipControlEXT__sig: 'vii', + glClipControlEXT: (origin, depth) => { +#if GL_ASSERTIONS + assert(GLctx.extClipControl, "EXT_clip_control not supported, or not enabled. Before calling glClipControlEXT(), call emscripten_webgl_enable_EXT_clip_control() to enable this extension, and verify that it returns true to indicate support. (alternatively, build with -sGL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS=1 to enable all GL extensions by default)"); +#endif + GLctx.extClipControl['clipControlEXT'](origin, depth); + }, + + glPolygonModeWEBGL__sig: 'vii', + glPolygonModeWEBGL: (face, mode) => { +#if GL_ASSERTIONS + assert(GLctx.webglPolygonMode, "WEBGL_polygon_mode not supported, or not enabled. Before calling glPolygonModeWEBGL(), call emscripten_webgl_enable_WEBGL_polygon_mode() to enable this extension, and verify that it returns true to indicate support. (alternatively, build with -sGL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS=1 to enable all GL extensions by default)"); +#endif + GLctx.webglPolygonMode['polygonModeWEBGL'](face, mode); + }, }; #if !GL_ENABLE_GET_PROC_ADDRESS diff --git a/system/include/emscripten/html5_webgl.h b/system/include/emscripten/html5_webgl.h index b9d5980afcf2e..5c7e4421ffe85 100644 --- a/system/include/emscripten/html5_webgl.h +++ b/system/include/emscripten/html5_webgl.h @@ -73,6 +73,12 @@ EM_BOOL emscripten_webgl_enable_WEBGL_multi_draw(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE EM_BOOL emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); +EM_BOOL emscripten_webgl_enable_EXT_polygon_offset_clamp(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); + +EM_BOOL emscripten_webgl_enable_EXT_clip_control(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); + +EM_BOOL emscripten_webgl_enable_WEBGL_polygon_mode(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); + typedef EM_BOOL (*em_webgl_context_callback)(int eventType, const void *reserved, void *userData); EMSCRIPTEN_RESULT emscripten_set_webglcontextlost_callback_on_thread(const char *target __attribute__((nonnull)), void *userData, EM_BOOL useCapture, em_webgl_context_callback callback, pthread_t targetThread); EMSCRIPTEN_RESULT emscripten_set_webglcontextrestored_callback_on_thread(const char *target __attribute__((nonnull)), void *userData, EM_BOOL useCapture, em_webgl_context_callback callback, pthread_t targetThread); diff --git a/system/include/webgl/webgl1_ext.h b/system/include/webgl/webgl1_ext.h index 8da7bc047ef27..a5268a375988e 100644 --- a/system/include/webgl/webgl1_ext.h +++ b/system/include/webgl/webgl1_ext.h @@ -1,36 +1,86 @@ #pragma once +/* This header webgl1_ext.h provides static linkage entry points to all WebGL extensions that + the Khronos WebGL registry adds on top of the WebGL 1 API. + + In Emscripten, all GL extension function entry points are provided via static linkage. + For best WebGL performance, call the statically linked gl*() functions in this header + instead of using a dynamic function pointers via the glGetProcAddress() function. + + Include this header instead of the headers GLES2/gl2ext.h or GL/glext.h if you are + developing a WebGL renderer as a first tier platform, and want to get "fail fast" + compiler errors of GL symbols that are not supported on WebGL. + + Other features: + - If you want to use one of the WebGL specific extensions that do not exist in + GLES or desktop GL (such as WEBGL_lose_context or WEBGL_debug_shaders), include + this header to get the function declarations and defines. + + - Unlike GLES and desktop GL, in WebGL one must explicitly enable an extension + before using it. See below in the section of each extension for instructions + on how to enable it, or link with -sGL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS=1 + to automatically enable all non-debugging related WebGL extensions at startup. + + - If you are targeting multiple Emscripten compiler versions (e.g. a rendering + library middleware), you can query whether static linkage to a particular + extension is provided, by including this header and then checking + + #if EMSCRIPTEN_GL_WEBGL_polygon_mode + // we can call glPolygonModeWEBGL() function + #endif + + - To disable a particular WebGL extension from being declared in this header, + you can add e.g. + #define EMSCRIPTEN_GL_OES_texture_float 0 + before including this header. + + - For technical reasons, each function declaration comes in two variants: + a glFoo() declaration, and a second emscripten_glFoo() copy. + The emscripten_glFoo() variants exist for internal *GetProcAddress() and + Emscripten -sOFFSCREEN_FRAMEBUFFER=1 features linkage purposes, and should + be ignored by end users. +*/ #include "webgl1.h" #include // 1. https://www.khronos.org/registry/webgl/extensions/OES_texture_float/ #ifndef EMSCRIPTEN_GL_OES_texture_float #define EMSCRIPTEN_GL_OES_texture_float 1 -// +// To enable: call emscripten_webgl_enable_extension(ctx, "OES_texture_float"); +// #endif /* EMSCRIPTEN_GL_OES_texture_float */ // 2. https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float/ #ifndef EMSCRIPTEN_GL_OES_texture_half_float #define EMSCRIPTEN_GL_OES_texture_half_float 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "OES_texture_half_float"); #define GL_HALF_FLOAT_OES 0x8D61 +// #endif /* EMSCRIPTEN_GL_OES_texture_half_float */ // 3. https://www.khronos.org/registry/webgl/extensions/WEBGL_lose_context/ #ifndef EMSCRIPTEN_GL_WEBGL_lose_context -#define EMSCRIPTEN_GL_WEBGL_lose_context 1 -WEBGL_APICALL EMSCRIPTEN_RESULT GL_APIENTRY emscripten_webgl_loseContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE contextHandle); -WEBGL_APICALL EMSCRIPTEN_RESULT GL_APIENTRY emscripten_webgl_restoreContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE contextHandle); +//#define EMSCRIPTEN_GL_WEBGL_lose_context 1 +// TODO: +//WEBGL_APICALL EMSCRIPTEN_RESULT GL_APIENTRY emscripten_webgl_loseContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE contextHandle); +//WEBGL_APICALL EMSCRIPTEN_RESULT GL_APIENTRY emscripten_webgl_restoreContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE contextHandle); #endif /* EMSCRIPTEN_GL_WEBGL_lose_context */ // 4. https://www.khronos.org/registry/webgl/extensions/OES_standard_derivatives/ #ifndef EMSCRIPTEN_GL_OES_standard_derivatives #define EMSCRIPTEN_GL_OES_standard_derivatives 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "OES_standard_derivatives"); #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +// #endif /* EMSCRIPTEN_GL_OES_standard_derivatives */ // 5. https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/ #ifndef EMSCRIPTEN_GL_OES_vertex_array_object #define EMSCRIPTEN_GL_OES_vertex_array_object 1 +// To enable: call +EM_BOOL emscripten_webgl_enable_OES_vertex_array_object(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); +// or link with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=1 and +// call emscripten_webgl_enable_extension(ctx, "OES_vertex_array_object"); #define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 WEBGL_APICALL void GL_APIENTRY emscripten_glBindVertexArrayOES(GLuint array); WEBGL_APICALL void GL_APIENTRY emscripten_glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays __attribute__((nonnull))); @@ -45,53 +95,69 @@ WEBGL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES(GLuint array); // 6. https://www.khronos.org/registry/webgl/extensions/WEBGL_debug_renderer_info/ #ifndef EMSCRIPTEN_GL_WEBGL_debug_renderer_info #define EMSCRIPTEN_GL_WEBGL_debug_renderer_info 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_debug_renderer_info"); #define GL_UNMASKED_VENDOR_WEBGL 0x9245 #define GL_UNMASKED_RENDERER_WEBGL 0x9246 +// #endif /* EMSCRIPTEN_GL_WEBGL_debug_renderer_info */ // 7. https://www.khronos.org/registry/webgl/extensions/WEBGL_debug_shaders/ #ifndef EMSCRIPTEN_GL_WEBGL_debug_shaders #define EMSCRIPTEN_GL_WEBGL_debug_shaders 1 -WEBGL_APICALL void GL_APIENTRY emscripten_webgl_getTranslatedShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length __attribute__((nonnull)), GLchar *source __attribute__((nonnull))); +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_debug_shaders"); +//TODO: +//WEBGL_APICALL void GL_APIENTRY emscripten_webgl_getTranslatedShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length __attribute__((nonnull)), GLchar *source __attribute__((nonnull))); #endif /* EMSCRIPTEN_GL_WEBGL_debug_shaders */ // 8. https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ #ifndef EMSCRIPTEN_GL_WEBGL_compressed_texture_s3tc #define EMSCRIPTEN_GL_WEBGL_compressed_texture_s3tc 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_s3tc"); #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +// #endif /* EMSCRIPTEN_GL_WEBGL_compressed_texture_s3tc */ // 9. https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/ #ifndef EMSCRIPTEN_GL_WEBGL_depth_texture #define EMSCRIPTEN_GL_WEBGL_depth_texture 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_depth_texture"); #define GL_UNSIGNED_INT_24_8_WEBGL 0x84FA +// #endif /* EMSCRIPTEN_GL_WEBGL_depth_texture */ // 10. https://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/ #ifndef EMSCRIPTEN_GL_OES_element_index_uint #define EMSCRIPTEN_GL_OES_element_index_uint 1 -// +// To enable: call emscripten_webgl_enable_extension(ctx, "OES_element_index_uint"); +// #endif /* EMSCRIPTEN_GL_OES_element_index_uint */ // 11. https://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/ #ifndef EMSCRIPTEN_GL_EXT_texture_filter_anisotropic #define EMSCRIPTEN_GL_EXT_texture_filter_anisotropic 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_texture_filter_anisotropic"); #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +// #endif /* EMSCRIPTEN_GL_EXT_texture_filter_anisotropic */ // 16. https://www.khronos.org/registry/webgl/extensions/EXT_frag_depth/ #ifndef EMSCRIPTEN_GL_EXT_frag_depth #define EMSCRIPTEN_GL_EXT_frag_depth 1 -// +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_frag_depth"); +// #endif /* EMSCRIPTEN_GL_EXT_frag_depth */ // 18. https://www.khronos.org/registry/webgl/extensions/WEBGL_draw_buffers/ #ifndef EMSCRIPTEN_GL_WEBGL_draw_buffers #define EMSCRIPTEN_GL_WEBGL_draw_buffers 1 +// To enable: call +EM_BOOL emscripten_webgl_enable_WEBGL_draw_buffers(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); +// or link with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=1 and +// call emscripten_webgl_enable_extension(ctx, "WEBGL_draw_buffers"); #define GL_COLOR_ATTACHMENT0_WEBGL 0x8CE0 #define GL_COLOR_ATTACHMENT1_WEBGL 0x8CE1 #define GL_COLOR_ATTACHMENT2_WEBGL 0x8CE2 @@ -133,6 +199,10 @@ WEBGL_APICALL void GL_APIENTRY glDrawBuffersWEBGL(GLsizei n, const GLenum *buffe // 19. https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/ #ifndef EMSCRIPTEN_GL_ANGLE_instanced_arrays #define EMSCRIPTEN_GL_ANGLE_instanced_arrays 1 +// To enable: call +EM_BOOL emscripten_webgl_enable_ANGLE_instanced_arrays(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); +// or link with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=1 and +// call emscripten_webgl_enable_extension(ctx, "ANGLE_instanced_arrays"); #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE WEBGL_APICALL void GL_APIENTRY emscripten_glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount); WEBGL_APICALL void GL_APIENTRY emscripten_glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount); @@ -145,69 +215,84 @@ WEBGL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint d // 20. https://www.khronos.org/registry/webgl/extensions/OES_texture_float_linear/ #ifndef EMSCRIPTEN_GL_OES_texture_float_linear #define EMSCRIPTEN_GL_OES_texture_float_linear 1 -// +// To enable: call emscripten_webgl_enable_extension(ctx, "OES_texture_float_linear"); +// #endif /* EMSCRIPTEN_GL_OES_texture_float_linear */ // 21. https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float_linear/ #ifndef EMSCRIPTEN_GL_OES_texture_half_float_linear #define EMSCRIPTEN_GL_OES_texture_half_float_linear 1 -// +// To enable: call emscripten_webgl_enable_extension(ctx, "OES_texture_half_float_linear"); +// #endif /* EMSCRIPTEN_GL_OES_texture_half_float_linear */ // 25. https://www.khronos.org/registry/webgl/extensions/EXT_blend_minmax/ #ifndef EMSCRIPTEN_GL_EXT_blend_minmax #define EMSCRIPTEN_GL_EXT_blend_minmax 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_blend_minmax"); #define GL_MIN_EXT 0x8007 #define GL_MAX_EXT 0x8008 +// #endif /* EMSCRIPTEN_GL_EXT_blend_minmax */ // 27. https://www.khronos.org/registry/webgl/extensions/EXT_shader_texture_lod/ #ifndef EMSCRIPTEN_GL_EXT_shader_texture_lod #define EMSCRIPTEN_GL_EXT_shader_texture_lod 1 -// +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_shader_texture_lod"); +// #endif /* EMSCRIPTEN_GL_EXT_shader_texture_lod */ // 13. https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/ #ifndef EMSCRIPTEN_GL_WEBGL_compressed_texture_pvrtc #define EMSCRIPTEN_GL_WEBGL_compressed_texture_pvrtc 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_pvrtc"); #define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 #define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 #define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +// #endif /* EMSCRIPTEN_GL_WEBGL_compressed_texture_pvrtc */ // 14. https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_half_float/ #ifndef EMSCRIPTEN_GL_EXT_color_buffer_half_float #define EMSCRIPTEN_GL_EXT_color_buffer_half_float 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_color_buffer_half_float"); #define GL_RGBA16F_EXT 0x881A #define GL_RGB16F_EXT 0x881B #define GL_RG16F_EXT 0x822F #define GL_R16F_EXT 0x822D #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 #define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +// #endif /* EMSCRIPTEN_GL_EXT_color_buffer_half_float */ // 15. https://www.khronos.org/registry/webgl/extensions/WEBGL_color_buffer_float/ #ifndef EMSCRIPTEN_GL_WEBGL_color_buffer_float #define EMSCRIPTEN_GL_WEBGL_color_buffer_float 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_color_buffer_float"); #define GL_RGBA32F_EXT 0x8814 #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 #define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +// #endif /* EMSCRIPTEN_GL_WEBGL_color_buffer_float */ // 17. https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/ #ifndef EMSCRIPTEN_GL_EXT_sRGB #define EMSCRIPTEN_GL_EXT_sRGB 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_sRGB"); #define GL_SRGB_EXT 0x8C40 #define GL_SRGB_ALPHA_EXT 0x8C42 #define GL_SRGB8_ALPHA8_EXT 0x8C43 #define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +// #endif /* EMSCRIPTEN_GL_EXT_sRGB */ // 24. https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/ #ifndef EMSCRIPTEN_GL_WEBGL_compressed_texture_etc1 #define EMSCRIPTEN_GL_WEBGL_compressed_texture_etc1 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc1"); #define GL_COMPRESSED_RGB_ETC1_WEBGL 0x8D64 +// #endif /* EMSCRIPTEN_GL_WEBGL_compressed_texture_etc1 */ // 26. https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query/ @@ -247,6 +332,7 @@ WEBGL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT(GLuint id, GLenum pname, // 29. https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/ #ifndef EMSCRIPTEN_GL_WEBGL_compressed_texture_etc #define EMSCRIPTEN_GL_WEBGL_compressed_texture_etc 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc"); #define GL_COMPRESSED_R11_EAC 0x9270 #define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 #define GL_COMPRESSED_RG11_EAC 0x9272 @@ -257,11 +343,13 @@ WEBGL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT(GLuint id, GLenum pname, #define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 #define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +// #endif /* EMSCRIPTEN_GL_WEBGL_compressed_texture_etc */ // 30. https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/ #ifndef EMSCRIPTEN_GL_WEBGL_compressed_texture_astc #define EMSCRIPTEN_GL_WEBGL_compressed_texture_astc 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_astc"); #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 #define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 #define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 @@ -290,33 +378,43 @@ WEBGL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT(GLuint id, GLenum pname, #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC #define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD -WEBGL_APICALL void GL_APIENTRY emscripten_webgl_getSupportedAstcProfiles(GLsizei bufSize, GLsizei *length __attribute__((nonnull)), GLchar *buf __attribute__((nonnull))); +//TODO: +//WEBGL_APICALL void GL_APIENTRY emscripten_webgl_getSupportedAstcProfiles(GLsizei bufSize, GLsizei *length __attribute__((nonnull)), GLchar *buf __attribute__((nonnull))); #endif /* EMSCRIPTEN_GL_WEBGL_compressed_texture_astc */ // 31. https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/ #ifndef EMSCRIPTEN_GL_EXT_color_buffer_float #define EMSCRIPTEN_GL_EXT_color_buffer_float 1 -// +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_color_buffer_float"); +// #endif /* EMSCRIPTEN_GL_EXT_color_buffer_float */ // 32. https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc_srgb/ #ifndef EMSCRIPTEN_GL_WEBGL_compressed_texture_s3tc_srgb #define EMSCRIPTEN_GL_WEBGL_compressed_texture_s3tc_srgb 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_s3tc_srgb"); #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +// #endif /* EMSCRIPTEN_GL_WEBGL_compressed_texture_s3tc_srgb */ // 37. https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/ -#ifndef EMSCRIPTEN_GL_KHR_PARALLEL_SHADER_COMPILE -#define EMSCRIPTEN_GL_KHR_PARALLEL_SHADER_COMPILE 1 +#ifndef EMSCRIPTEN_GL_KHR_parallel_shader_compile +#define EMSCRIPTEN_GL_KHR_parallel_shader_compile 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "KHR_parallel_shader_compile"); #define GL_COMPLETION_STATUS_KHR 0x91B1 +// #endif // 40. https://www.khronos.org/registry/webgl/extensions/WEBGL_multi_draw/ #ifndef EMSCRIPTEN_GL_WEBGL_multi_draw #define EMSCRIPTEN_GL_WEBGL_multi_draw 1 +// To enable: call +EM_BOOL emscripten_webgl_enable_WEBGL_multi_draw(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); +// or link with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=1 and +// call emscripten_webgl_enable_extension(ctx, "WEBGL_multi_draw"); WEBGL_APICALL void GL_APIENTRY emscripten_glMultiDrawArraysWEBGL(GLenum mode, const GLint* firsts __attribute__((nonnull)), const GLsizei* counts __attribute__((nonnull)), @@ -362,6 +460,7 @@ WEBGL_APICALL void GL_APIENTRY glMultiDrawElementsInstancedWEBGL(GLenum mode, // 44. https://www.khronos.org/registry/webgl/extensions/EXT_texture_norm16/ #ifndef EMSCRIPTEN_GL_EXT_texture_norm16 #define EMSCRIPTEN_GL_EXT_texture_norm16 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_texture_norm16"); #define GL_R16_EXT 0x822A #define GL_RG16_EXT 0x822C #define GL_RGB16_EXT 0x8054 @@ -370,9 +469,86 @@ WEBGL_APICALL void GL_APIENTRY glMultiDrawElementsInstancedWEBGL(GLenum mode, #define GL_RG16_SNORM_EXT 0x8F99 #define GL_RGB16_SNORM_EXT 0x8F9A #define GL_RGBA16_SNORM_EXT 0x8F9B +// #endif /* EMSCRIPTEN_GL_EXT_texture_norm16 */ // EMSCRIPTEN_explicit_uniform_location -#ifndef GL_MAX_UNIFORM_LOCATIONS +// https://github.com/emscripten-core/emscripten/blob/main/docs/EMSCRIPTEN_explicit_uniform_location.txt +#ifndef EMSCRIPTEN_explicit_uniform_location +#define EMSCRIPTEN_explicit_uniform_location 1 +// To enable: link with -sGL_EXPLICIT_UNIFORM_LOCATION=1 #define GL_MAX_UNIFORM_LOCATIONS 0x826E +// #endif + +// EMSCRIPTEN_explicit_uniform_binding +// https://github.com/emscripten-core/emscripten/blob/main/docs/EMSCRIPTEN_explicit_uniform_binding.txt +#ifndef EMSCRIPTEN_explicit_uniform_binding +#define EMSCRIPTEN_explicit_uniform_binding 1 +// To enable: link with -sGL_EXPLICIT_UNIFORM_BINDING=1 +// +#endif + +// 50. https://registry.khronos.org/webgl/extensions/EXT_polygon_offset_clamp/ +#ifndef EMSCRIPTEN_GL_EXT_polygon_offset_clamp +#define EMSCRIPTEN_GL_EXT_polygon_offset_clamp 1 +// To enable: call +EM_BOOL emscripten_webgl_enable_EXT_polygon_offset_clamp(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); +// or link with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=1 and +// call emscripten_webgl_enable_extension(ctx, "EXT_polygon_offset_clamp"); +#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B +WEBGL_APICALL void GL_APIENTRY emscripten_glPolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp); +WEBGL_APICALL void GL_APIENTRY glPolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp); +#endif + +// 51. https://registry.khronos.org/webgl/extensions/EXT_clip_control/ +#ifndef EMSCRIPTEN_GL_EXT_clip_control +#define EMSCRIPTEN_GL_EXT_clip_control 1 +// To enable: call +EM_BOOL emscripten_webgl_enable_EXT_clip_control(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); +// or link with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=1 and +// call emscripten_webgl_enable_extension(ctx, "EXT_clip_control"); +#define GL_LOWER_LEFT_EXT 0x8CA1 +#define GL_UPPER_LEFT_EXT 0x8CA2 +#define GL_NEGATIVE_ONE_TO_ONE_EXT 0x935E +#define GL_ZERO_TO_ONE_EXT 0x935F +#define GL_CLIP_ORIGIN_EXT 0x935C +#define GL_CLIP_DEPTH_MODE_EXT 0x935D +WEBGL_APICALL void GL_APIENTRY emscripten_glClipControlEXT(GLenum origin, GLenum depth); +WEBGL_APICALL void GL_APIENTRY glClipControlEXT(GLenum origin, GLenum depth); +#endif + +// 52. https://registry.khronos.org/webgl/extensions/EXT_depth_clamp/ +#ifndef EMSCRIPTEN_GL_EXT_depth_clamp +#define EMSCRIPTEN_GL_EXT_depth_clamp 1 +// To enable: call emscripten_webgl_enable_extension(ctx, "EXT_depth_clamp"); +#define GL_DEPTH_CLAMP_EXT 0x864F +// +#endif + +// 53. https://registry.khronos.org/webgl/extensions/WEBGL_polygon_mode/ +#ifndef EMSCRIPTEN_GL_WEBGL_polygon_mode +#define EMSCRIPTEN_GL_WEBGL_polygon_mode 1 +// To enable: call +EM_BOOL emscripten_webgl_enable_WEBGL_polygon_mode(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context); +// or link with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=1 and +// call emscripten_webgl_enable_extension(ctx, "WEBGL_polygon_mode"); +#define GL_POLYGON_MODE_WEBGL 0x0B40 +#define GL_POLYGON_OFFSET_LINE_WEBGL 0x2A02 +#define GL_LINE_WEBGL 0x1B01 +#define GL_FILL_WEBGL 0x1B02 +WEBGL_APICALL void GL_APIENTRY emscripten_glPolygonModeWEBGL(GLenum face, GLenum mode); +WEBGL_APICALL void GL_APIENTRY glPolygonModeWEBGL(GLenum face, GLenum mode); +#endif + +/* To add a new GL extension here, follow the template + +// . +#ifndef EMSCRIPTEN_GL_ +#ifndef EMSCRIPTEN_GL_ 1 +// To enable: + + + +#endif +*/ diff --git a/system/lib/gl/webgl1.c b/system/lib/gl/webgl1.c index cbe6f4693d94e..5368d57a76384 100644 --- a/system/lib/gl/webgl1.c +++ b/system/lib/gl/webgl1.c @@ -818,6 +818,9 @@ void *emscripten_webgl1_get_proc_address(const char *name) { RETURN_FN(glGetQueryObjectuivEXT); RETURN_FN(glGetQueryObjecti64vEXT); RETURN_FN(glGetQueryObjectui64vEXT); + RETURN_FN(glPolygonOffsetClampEXT); + RETURN_FN(glClipControlEXT); + RETURN_FN(glPolygonModeWEBGL); return 0; } diff --git a/test/browser/webgl2_simple_enable_extensions.c b/test/browser/webgl2_simple_enable_extensions.c index 54f769b168158..03fa26b9b9031 100644 --- a/test/browser/webgl2_simple_enable_extensions.c +++ b/test/browser/webgl2_simple_enable_extensions.c @@ -61,6 +61,15 @@ int main() if (hasext(exts, "WEBGL_multi_draw_instanced_base_vertex_base_instance")) assert(emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(context)); + if (hasext(exts, "EXT_polygon_offset_clamp")) + assert(emscripten_webgl_enable_EXT_polygon_offset_clamp(context)); + + if (hasext(exts, "EXT_clip_control")) + assert(emscripten_webgl_enable_EXT_clip_control(context)); + + if (hasext(exts, "WEBGL_polygon_mode")) + assert(emscripten_webgl_enable_WEBGL_polygon_mode(context)); + #if WEBGL_SIMPLE_ENABLE_EXTENSION assert(hasext(exts, "ANGLE_instanced_arrays") == emscripten_webgl_enable_extension(context, "ANGLE_instanced_arrays")); assert(hasext(exts, "OES_vertex_array_object") == emscripten_webgl_enable_extension(context, "OES_vertex_array_object"));