Skip to content

Commit a19f7df

Browse files
authored
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.
1 parent aec91e5 commit a19f7df

File tree

8 files changed

+284
-24
lines changed

8 files changed

+284
-24
lines changed

ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ See docs/process.md for more on how version tagging works.
2020

2121
3.1.66 (in development)
2222
-----------------------
23+
- Added support for WebGL extensions EXT_clip_control, EXT_depth_clamp,
24+
EXT_polygon_offset_clamp and WEBGL_polygon_mode (#20841)
2325

2426
3.1.65 - 08/22/24
2527
-----------------

src/library_html5_webgl.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ var LibraryHtml5WebGL = {
311311
'$webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance',
312312
'$webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance',
313313
#endif
314+
'$webgl_enable_EXT_polygon_offset_clamp',
315+
'$webgl_enable_EXT_clip_control',
316+
'$webgl_enable_WEBGL_polygon_mode',
314317
'$webgl_enable_WEBGL_multi_draw',
315318
#endif
316319
],
@@ -339,21 +342,23 @@ var LibraryHtml5WebGL = {
339342
#endif
340343

341344
if (extString == 'WEBGL_multi_draw') webgl_enable_WEBGL_multi_draw(GLctx);
345+
if (extString == 'EXT_polygon_offset_clamp') webgl_enable_EXT_polygon_offset_clamp(GLctx);
346+
if (extString == 'EXT_clip_control') webgl_enable_EXT_clip_control(GLctx);
347+
if (extString == 'WEBGL_polygon_mode') webgl_enable_WEBGL_polygon_mode(GLctx);
342348

343-
#else
344-
345-
#if ASSERTIONS || GL_ASSERTIONS
349+
#elif ASSERTIONS || GL_ASSERTIONS
346350
if (['ANGLE_instanced_arrays',
347351
'OES_vertex_array_object',
348352
'WEBGL_draw_buffers',
349353
'WEBGL_multi_draw',
354+
'EXT_polygon_offset_clamp',
355+
'EXT_clip_control',
356+
'WEBGL_polygon_mode',
350357
'WEBGL_draw_instanced_base_vertex_base_instance',
351358
'WEBGL_multi_draw_instanced_base_vertex_base_instance'].includes(extString)) {
352359
err('When building with -sGL_SUPPORT_SIMPLE_ENABLE_EXTENSIONS=0, function emscripten_webgl_enable_extension() cannot be used to enable extension '
353360
+ extString + '! Use one of the functions emscripten_webgl_enable_*() to enable it!');
354361
}
355-
#endif
356-
357362
#endif
358363

359364
var ext = context.GLctx.getExtension(extString);

src/library_sigs.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,11 +858,14 @@ sigs = {
858858
emscripten_webgl_do_create_context__sig: 'ppp',
859859
emscripten_webgl_do_get_current_context__sig: 'p',
860860
emscripten_webgl_enable_ANGLE_instanced_arrays__sig: 'ip',
861+
emscripten_webgl_enable_EXT_clip_control__sig: 'ip',
862+
emscripten_webgl_enable_EXT_polygon_offset_clamp__sig: 'ip',
861863
emscripten_webgl_enable_OES_vertex_array_object__sig: 'ip',
862864
emscripten_webgl_enable_WEBGL_draw_buffers__sig: 'ip',
863865
emscripten_webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance__sig: 'ip',
864866
emscripten_webgl_enable_WEBGL_multi_draw__sig: 'ip',
865867
emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance__sig: 'ip',
868+
emscripten_webgl_enable_WEBGL_polygon_mode__sig: 'ip',
866869
emscripten_webgl_enable_extension__sig: 'ipp',
867870
emscripten_webgl_get_context_attributes__sig: 'ipp',
868871
emscripten_webgl_get_current_context__sig: 'p',

src/library_webgl.js

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
9696
$webgl_enable_ANGLE_instanced_arrays: (ctx) => {
9797
// Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
9898
var ext = ctx.getExtension('ANGLE_instanced_arrays');
99+
// Because this extension is a core function in WebGL 2, assign the extension entry points in place of
100+
// where the core functions will reside in WebGL 2. This way the calling code can call these without
101+
// having to dynamically branch depending if running against WebGL 1 or WebGL 2.
99102
if (ext) {
100103
ctx['vertexAttribDivisor'] = (index, divisor) => ext['vertexAttribDivisorANGLE'](index, divisor);
101104
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 }}};
143146
emscripten_webgl_enable_WEBGL_multi_draw__deps: ['$webgl_enable_WEBGL_multi_draw'],
144147
emscripten_webgl_enable_WEBGL_multi_draw: (ctx) => webgl_enable_WEBGL_multi_draw(GL.contexts[ctx].GLctx),
145148

149+
$webgl_enable_EXT_polygon_offset_clamp: (ctx) => {
150+
return !!(ctx.extPolygonOffsetClamp = ctx.getExtension('EXT_polygon_offset_clamp'));
151+
},
152+
153+
emscripten_webgl_enable_EXT_polygon_offset_clamp__deps: ['$webgl_enable_EXT_polygon_offset_clamp'],
154+
emscripten_webgl_enable_EXT_polygon_offset_clamp: (ctx) => webgl_enable_EXT_polygon_offset_clamp(GL.contexts[ctx].GLctx),
155+
156+
$webgl_enable_EXT_clip_control: (ctx) => {
157+
return !!(ctx.extClipControl = ctx.getExtension('EXT_clip_control'));
158+
},
159+
160+
emscripten_webgl_enable_EXT_clip_control__deps: ['$webgl_enable_EXT_clip_control'],
161+
emscripten_webgl_enable_EXT_clip_control: (ctx) => webgl_enable_EXT_clip_control(GL.contexts[ctx].GLctx),
162+
163+
$webgl_enable_WEBGL_polygon_mode: (ctx) => {
164+
return !!(ctx.webglPolygonMode = ctx.getExtension('WEBGL_polygon_mode'));
165+
},
166+
167+
emscripten_webgl_enable_WEBGL_polygon_mode__deps: ['$webgl_enable_WEBGL_polygon_mode'],
168+
emscripten_webgl_enable_WEBGL_polygon_mode: (ctx) => webgl_enable_WEBGL_polygon_mode(GL.contexts[ctx].GLctx),
169+
146170
$getEmscriptenSupportedExtensions__internal: true,
147171
$getEmscriptenSupportedExtensions: (ctx) => {
148172
// 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 }}};
177201
'WEBGL_clip_cull_distance',
178202
#endif
179203
// WebGL 1 and WebGL 2 extensions
204+
'EXT_clip_control',
180205
'EXT_color_buffer_half_float',
181206
'EXT_depth_clamp',
182207
'EXT_float_blend',
208+
'EXT_polygon_offset_clamp',
183209
'EXT_texture_compression_bptc',
184210
'EXT_texture_compression_rgtc',
185211
'EXT_texture_filter_anisotropic',
@@ -195,6 +221,7 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
195221
'WEBGL_debug_shaders',
196222
'WEBGL_lose_context',
197223
'WEBGL_multi_draw',
224+
'WEBGL_polygon_mode'
198225
];
199226
// .getSupportedExtensions() can return null if context is lost, so coerce to empty array.
200227
return (ctx.getSupportedExtensions() || []).filter(ext => supportedExtensions.includes(ext));
@@ -219,6 +246,9 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
219246
'$webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance',
220247
'$webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance',
221248
#endif
249+
'$webgl_enable_EXT_polygon_offset_clamp',
250+
'$webgl_enable_EXT_clip_control',
251+
'$webgl_enable_WEBGL_polygon_mode',
222252
'$webgl_enable_WEBGL_multi_draw',
223253
'$getEmscriptenSupportedExtensions',
224254
#endif // GL_SUPPORT_AUTOMATIC_ENABLE_EXTENSIONS
@@ -802,6 +832,7 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
802832
}
803833
disableHalfFloatExtensionIfBroken(ctx);
804834
#endif
835+
805836
return handle;
806837
},
807838

@@ -1184,6 +1215,11 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
11841215
context.anisotropicExt = GLctx.getExtension('EXT_texture_filter_anisotropic');
11851216
#endif
11861217

1218+
// Extensions that are available in both WebGL 1 and WebGL 2
1219+
webgl_enable_WEBGL_multi_draw(GLctx);
1220+
webgl_enable_EXT_polygon_offset_clamp(GLctx);
1221+
webgl_enable_EXT_clip_control(GLctx);
1222+
webgl_enable_WEBGL_polygon_mode(GLctx);
11871223
#if MIN_WEBGL_VERSION == 1
11881224
// Extensions that are only available in WebGL 1 (the calls will be no-ops
11891225
// if called on a WebGL 2 context active)
@@ -1195,9 +1231,7 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
11951231
// Extensions that are available from WebGL >= 2 (no-op if called on a WebGL 1 context active)
11961232
webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx);
11971233
webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx);
1198-
#endif
11991234

1200-
#if MAX_WEBGL_VERSION >= 2
12011235
// On WebGL 2, EXT_disjoint_timer_query is replaced with an alternative
12021236
// that's based on core APIs, and exposes only the queryCounterEXT()
12031237
// entrypoint.
@@ -1214,8 +1248,6 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
12141248
GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query");
12151249
}
12161250

1217-
webgl_enable_WEBGL_multi_draw(GLctx);
1218-
12191251
getEmscriptenSupportedExtensions(GLctx).forEach((ext) => {
12201252
// WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders
12211253
// are not enabled by default.
@@ -4214,6 +4246,30 @@ for (/**@suppress{duplicate}*/var i = 0; i <= {{{ GL_POOL_TEMP_BUFFERS_SIZE }}};
42144246
return 1;
42154247
},
42164248
#endif
4249+
4250+
glPolygonOffsetClampEXT__sig: 'vfff',
4251+
glPolygonOffsetClampEXT: (factor, units, clamp) => {
4252+
#if GL_ASSERTIONS
4253+
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)");
4254+
#endif
4255+
GLctx.extPolygonOffsetClamp['polygonOffsetClampEXT'](factor, units, clamp);
4256+
},
4257+
4258+
glClipControlEXT__sig: 'vii',
4259+
glClipControlEXT: (origin, depth) => {
4260+
#if GL_ASSERTIONS
4261+
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)");
4262+
#endif
4263+
GLctx.extClipControl['clipControlEXT'](origin, depth);
4264+
},
4265+
4266+
glPolygonModeWEBGL__sig: 'vii',
4267+
glPolygonModeWEBGL: (face, mode) => {
4268+
#if GL_ASSERTIONS
4269+
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)");
4270+
#endif
4271+
GLctx.webglPolygonMode['polygonModeWEBGL'](face, mode);
4272+
},
42174273
};
42184274

42194275
#if !GL_ENABLE_GET_PROC_ADDRESS

system/include/emscripten/html5_webgl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ EM_BOOL emscripten_webgl_enable_WEBGL_multi_draw(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE
7373

7474
EM_BOOL emscripten_webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context);
7575

76+
EM_BOOL emscripten_webgl_enable_EXT_polygon_offset_clamp(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context);
77+
78+
EM_BOOL emscripten_webgl_enable_EXT_clip_control(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context);
79+
80+
EM_BOOL emscripten_webgl_enable_WEBGL_polygon_mode(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context);
81+
7682
typedef EM_BOOL (*em_webgl_context_callback)(int eventType, const void *reserved, void *userData);
7783
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);
7884
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);

0 commit comments

Comments
 (0)