Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 5.0.3 (285c424)
clang version 23.0.0git (https:/github.com/llvm/llvm-project e5927fecf8a6ce89e1a4eac5b828e7d42676452a)
Target: wasm32-unknown-emscripten
Thread model: posix
Minimal example to demonstrate the problem visually
https://gist.github.com/paradust7/cd6610b76939b9756b6ee561a929164d
Compile with:
emcc -g -O0 -s USE_SDL=2 -s FULL_ES2=1 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -o index.html minimal.c
And then serve with python3 -m http.server 8080 (or other).
Explanation
The problem originates from here:
|
glDrawElements: (mode, count, type, indices) => { |
|
#if FULL_ES2 |
|
var buf; |
|
var vertexes = 0; |
|
if (!GLctx.currentElementArrayBufferBinding) { |
|
var size = GL.calcBufLength(1, type, 0, count); |
|
buf = GL.getTempIndexBuffer(size); |
|
GLctx.bindBuffer(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, buf); |
|
GLctx.bufferSubData(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, |
|
0, |
|
HEAPU8.subarray(indices, indices + size)); |
|
|
|
// Calculating vertex count if shader's attribute data is on client side |
|
if (count > 0) { |
|
for (var i = 0; i < GL.currentContext.maxVertexAttribs; ++i) { |
|
var cb = GL.currentContext.clientBuffers[i]; |
|
if (cb.clientside && cb.enabled) { |
|
let arrayClass; |
|
switch(type) { |
|
case 0x1401 /* GL_UNSIGNED_BYTE */: arrayClass = Uint8Array; break; |
|
case 0x1403 /* GL_UNSIGNED_SHORT */: arrayClass = Uint16Array; break; |
|
#if FULL_ES3 |
|
case 0x1405 /* GL_UNSIGNED_INT */: arrayClass = Uint32Array; break; |
|
#endif |
|
default: |
|
GL.recordError(0x502 /* GL_INVALID_OPERATION */); |
|
#if GL_ASSERTIONS |
|
err('type is not supported in glDrawElements'); |
|
#endif |
|
return; |
|
} |
|
|
|
vertexes = new arrayClass(HEAPU8.buffer, indices, count).reduce((max, current) => Math.max(max, current)) + 1; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// the index is now 0 |
|
indices = 0; |
|
} |
|
|
|
// bind any client-side buffers |
|
GL.preDrawHandleClientVertexAttribBindings(vertexes); |
|
#endif |
|
|
|
GLctx.drawElements(mode, count, type, indices); |
|
|
|
#if FULL_ES2 |
|
GL.postDrawHandleClientVertexAttribBindings(count); |
|
|
|
if (!GLctx.currentElementArrayBufferBinding) { |
|
GLctx.bindBuffer(0x8893 /*GL_ELEMENT_ARRAY_BUFFER*/, null); |
|
} |
|
#endif |
|
}, |
When !currentElementArrayBufferBinding, "vertexes" (the maximum vertex count) is calculated using the indices data. Otherwise, vertexes is never calculated and remains 0, so vertex data is never copied.
Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 5.0.3 (285c424)
clang version 23.0.0git (https:/github.com/llvm/llvm-project e5927fecf8a6ce89e1a4eac5b828e7d42676452a)
Target: wasm32-unknown-emscripten
Thread model: posix
Minimal example to demonstrate the problem visually
https://gist.github.com/paradust7/cd6610b76939b9756b6ee561a929164d
Compile with:
emcc -g -O0 -s USE_SDL=2 -s FULL_ES2=1 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -o index.html minimal.cAnd then serve with
python3 -m http.server 8080(or other).Explanation
The problem originates from here:
emscripten/src/lib/libwebgl.js
Lines 3853 to 3908 in cb060ca
When
!currentElementArrayBufferBinding, "vertexes" (the maximum vertex count) is calculated using the indices data. Otherwise,vertexesis never calculated and remains 0, so vertex data is never copied.