我的应用程序是使用OpenGL API用C ++编写的,我使用Emscripten为桌面操作系统和Web构建它。不久前出现了一个奇怪的错误:一切都在桌面上运行正常(有任何优化,valgrind-clean),但在WebGL中崩溃时出现以下错误:
抛出异常:TypeError:参数2 of WebGLRenderingContext.uniform4fv无法转换为以下任何一项: Float32Array,UnrestrictedFloatSequence。
我使用-g4
构建它(生成带有调试信息的可读JS代码),并发现有时glUniform4fv
因其count
参数而变为零。 Emscripten生成的OpenGL调用包装器如下:
function _glUniform4fv(location, count, value) {
var view;
if (4*count <= GL.MINI_TEMP_BUFFER_SIZE) {
// avoid allocation when uploading few enough uniforms
view = GL.miniTempBufferViews[4*count-1];
for (var i = 0; i < 4*count; i += 4) {
view[i] = HEAPF32[(((value)+(4*i))>>2)];
view[i+1] = HEAPF32[(((value)+(4*i+4))>>2)];
view[i+2] = HEAPF32[(((value)+(4*i+8))>>2)];
view[i+3] = HEAPF32[(((value)+(4*i+12))>>2)];
}
} else {
view = HEAPF32.subarray((value)>>2,(value+count*16)>>2);
}
GLctx.uniform4fv(GL.uniforms[location], view);
}
因此,当此包装器变为零count
并进入第一个分支时,它将执行view = GL.miniTempBufferViews[-1];
,即undefined
。此值转到GLctx.uniform4fv
,产生上述错误。
好的,让我们来看看OpenGL documentation,ES 2.0版本,它是WebGL1的基础:
计数的
指定要的元素数 被修改。如果是目标,这应该是1 uniform变量不是数组,如果是,则为1或更多 一个数组。
...
错误
...
如果count小于0,则生成GL_INVALID_VALUE。
所以当count
为零时,我无法看到OpenGL应该做什么。当我们没有任何东西传递到着色器时,我认为它是一个正确的值。至少,它不应该崩溃。
所以我有以下问题:
1)从GLES 2.0规范的角度来看,它是未定义的还是实现定义的行为?
2)Emscripten的正确反应应该是什么?绝对不允许设置错误状态,因为规格中没有这样的错误。但也许将零大小的Float32Array
传递给GLctx.uniform4fv
更为正确,让浏览器的Webgl实现处理它?我应该向Emscripten开发人员报告问题吗?