glfw 的基本设置导致关于 emscripten 生成的 js 文件中的事件监听器的运行时错误
Basic setup for glfw causes a runtime error with regards to eventlistener in emscripten generated js file
长话短说,我尝试为 opengl c++ 演示创建最简单的设置,我遇到的问题似乎与
canvas 与在 wasm 文件的 javascript 包装器中找到的事件侦听器有关的初始化。我是新手,所以我会 post
cpp 中的代码、html 文件和用于编译项目的命令行以及 chromium 中的错误。
这是glfw.cpp
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
#define GLFW_INCLUDE_ES3
#include <GLFW/glfw3.h>
#include <GLES3/gl3.h>
void initialize()
{
// Initialise GLFW
if( !glfwInit() )
{
EM_ASM_({
console.log(' failed: ');
}, 0);
}
EM_ASM_({
console.log(' end initialization: ');
}, 0);
}
EMSCRIPTEN_BINDINGS(glfw)
{
function("initialize", &initialize);
}
这是glfw.html
<!doctype html>
<html>
<head>
</head>
<body>
<canvas id="canvas" oncontextmenu="event.preventDefault()" style = "height: 100%; width: 100%; background-color:red;"></canvas>
<script>
var Module =
{
canvas: function()
{
console.log("canvas");
var canvas = document.getElementById('canvas');
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
},
onRuntimeInitialized: function()
{
Module.initialize();
}
};
</script>
<script type="text/javascript" src="glfw.js"> </script>
</body>
</html>
编译项目的命令
emcc --bind -o glfw.js glfw.cpp -s USE_GLFW=3
这是 chromiumconsole.log 中的完整错误
glfw.js:1645 Fetch finished loading: GET "http://localhost:8080/glfw.wasm".
doNativeWasm @ glfw.js:1645
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:1650 wasm streaming compile failed: TypeError: Module.canvas.addEventListener is not a function
(anonymous) @ glfw.js:1650
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:1651 falling back to ArrayBuffer instantiation
(anonymous) @ glfw.js:1651
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:1560 Fetch finished loading: GET "http://localhost:8080/glfw.wasm".
getBinaryPromise @ glfw.js:1560
instantiateArrayBuffer @ glfw.js:1633
(anonymous) @ glfw.js:1652
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:5228 Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?
glfw.js:5229 Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?
abort @ glfw.js:5229
assert @ glfw.js:434
receiveInstantiatedSource @ glfw.js:1628
Promise.then (async)
instantiateArrayBuffer @ glfw.js:1635
(anonymous) @ glfw.js:1652
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:1636 failed to asynchronously prepare wasm: abort("Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?") at Error
at jsStackTrace (http://localhost:8080/glfw.js:1033:13)
at stackTrace (http://localhost:8080/glfw.js:1050:12)
at abort (http://localhost:8080/glfw.js:5239:44)
at assert (http://localhost:8080/glfw.js:434:5)
at receiveInstantiatedSource (http://localhost:8080/glfw.js:1628:7)
(anonymous) @ glfw.js:1636
Promise.catch (async)
instantiateArrayBuffer @ glfw.js:1635
(anonymous) @ glfw.js:1652
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:5228 abort("Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?") at Error
at jsStackTrace (http://localhost:8080/glfw.js:1033:13)
at stackTrace (http://localhost:8080/glfw.js:1050:12)
at abort (http://localhost:8080/glfw.js:5239:44)
at assert (http://localhost:8080/glfw.js:434:5)
at receiveInstantiatedSource (http://localhost:8080/glfw.js:1628:7)
glfw.js:5229 abort("Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?") at Error
at jsStackTrace (http://localhost:8080/glfw.js:1033:13)
at stackTrace (http://localhost:8080/glfw.js:1050:12)
at abort (http://localhost:8080/glfw.js:5239:44)
at assert (http://localhost:8080/glfw.js:434:5)
at receiveInstantiatedSource (http://localhost:8080/glfw.js:1628:7)
abort @ glfw.js:5229
(anonymous) @ glfw.js:1637
Promise.catch (async)
instantiateArrayBuffer @ glfw.js:1635
(anonymous) @ glfw.js:1652
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.html:1 Uncaught (in promise) abort("abort(\"Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?\") at Error\n at jsStackTrace (http://localhost:8080/glfw.js:1033:13)\n at stackTrace (http://localhost:8080/glfw.js:1050:12)\n at abort (http://localhost:8080/glfw.js:5239:44)\n at assert (http://localhost:8080/glfw.js:434:5)\n at receiveInstantiatedSource (http://localhost:8080/glfw.js:1628:7)") at Error
at jsStackTrace (http://localhost:8080/glfw.js:1033:13)
at stackTrace (http://localhost:8080/glfw.js:1050:12)
at abort (http://localhost:8080/glfw.js:5239:44)
at http://localhost:8080/glfw.js:1637:9
我设法对一个工作示例进行了逆向工程,并以此为基础给出了我的答案,所以下面的工作代码编译得很好,没有给出任何错误,只有 JavaScript 文件中的两个警告。
emcc -std=c++11 glfw.cpp -o glfw.js -s USE_WEBGL2=3 -s FULL_ES3=3 -s USE_GLFW =3 -s WASM=3
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Emscripten-Generated Code</title>
<style>
body
{
font-family: arial;
margin: 0;
padding: none;
}
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
canvas.emscripten { border: 0px none; background-color: black; }
</style>
</head>
<body>
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<script type='text/javascript'>
var Module =
{
canvas: (function() {
var canvas = document.getElementById('canvas');
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})()
};
</script>
<script async type="text/javascript" src="glfw.js"></script>
</body>
</html>
bind.h 并不是真正需要的,除非它不包含在命名空间中。
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
#define GLFW_INCLUDE_ES3
#include <GLFW/glfw3.h>
#include <GLES3/gl3.h>
using namespace emscripten;
int main()
{
// Initialise GLFW
if( !glfwInit() )
{
EM_ASM_({
console.log(' failed: ');
}, 0);
}
EM_ASM_({
console.log(' end initialization: ');
}, 0);
return 0;
}
长话短说,我尝试为 opengl c++ 演示创建最简单的设置,我遇到的问题似乎与 canvas 与在 wasm 文件的 javascript 包装器中找到的事件侦听器有关的初始化。我是新手,所以我会 post cpp 中的代码、html 文件和用于编译项目的命令行以及 chromium 中的错误。
这是glfw.cpp
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
#define GLFW_INCLUDE_ES3
#include <GLFW/glfw3.h>
#include <GLES3/gl3.h>
void initialize()
{
// Initialise GLFW
if( !glfwInit() )
{
EM_ASM_({
console.log(' failed: ');
}, 0);
}
EM_ASM_({
console.log(' end initialization: ');
}, 0);
}
EMSCRIPTEN_BINDINGS(glfw)
{
function("initialize", &initialize);
}
这是glfw.html
<!doctype html>
<html>
<head>
</head>
<body>
<canvas id="canvas" oncontextmenu="event.preventDefault()" style = "height: 100%; width: 100%; background-color:red;"></canvas>
<script>
var Module =
{
canvas: function()
{
console.log("canvas");
var canvas = document.getElementById('canvas');
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
},
onRuntimeInitialized: function()
{
Module.initialize();
}
};
</script>
<script type="text/javascript" src="glfw.js"> </script>
</body>
</html>
编译项目的命令
emcc --bind -o glfw.js glfw.cpp -s USE_GLFW=3
这是 chromiumconsole.log 中的完整错误
glfw.js:1645 Fetch finished loading: GET "http://localhost:8080/glfw.wasm".
doNativeWasm @ glfw.js:1645
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:1650 wasm streaming compile failed: TypeError: Module.canvas.addEventListener is not a function
(anonymous) @ glfw.js:1650
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:1651 falling back to ArrayBuffer instantiation
(anonymous) @ glfw.js:1651
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:1560 Fetch finished loading: GET "http://localhost:8080/glfw.wasm".
getBinaryPromise @ glfw.js:1560
instantiateArrayBuffer @ glfw.js:1633
(anonymous) @ glfw.js:1652
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:5228 Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?
glfw.js:5229 Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?
abort @ glfw.js:5229
assert @ glfw.js:434
receiveInstantiatedSource @ glfw.js:1628
Promise.then (async)
instantiateArrayBuffer @ glfw.js:1635
(anonymous) @ glfw.js:1652
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:1636 failed to asynchronously prepare wasm: abort("Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?") at Error
at jsStackTrace (http://localhost:8080/glfw.js:1033:13)
at stackTrace (http://localhost:8080/glfw.js:1050:12)
at abort (http://localhost:8080/glfw.js:5239:44)
at assert (http://localhost:8080/glfw.js:434:5)
at receiveInstantiatedSource (http://localhost:8080/glfw.js:1628:7)
(anonymous) @ glfw.js:1636
Promise.catch (async)
instantiateArrayBuffer @ glfw.js:1635
(anonymous) @ glfw.js:1652
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.js:5228 abort("Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?") at Error
at jsStackTrace (http://localhost:8080/glfw.js:1033:13)
at stackTrace (http://localhost:8080/glfw.js:1050:12)
at abort (http://localhost:8080/glfw.js:5239:44)
at assert (http://localhost:8080/glfw.js:434:5)
at receiveInstantiatedSource (http://localhost:8080/glfw.js:1628:7)
glfw.js:5229 abort("Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?") at Error
at jsStackTrace (http://localhost:8080/glfw.js:1033:13)
at stackTrace (http://localhost:8080/glfw.js:1050:12)
at abort (http://localhost:8080/glfw.js:5239:44)
at assert (http://localhost:8080/glfw.js:434:5)
at receiveInstantiatedSource (http://localhost:8080/glfw.js:1628:7)
abort @ glfw.js:5229
(anonymous) @ glfw.js:1637
Promise.catch (async)
instantiateArrayBuffer @ glfw.js:1635
(anonymous) @ glfw.js:1652
Promise.catch (async)
doNativeWasm @ glfw.js:1647
Module.asm @ glfw.js:1735
(anonymous) @ glfw.js:4813
glfw.html:1 Uncaught (in promise) abort("abort(\"Assertion failed: the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?\") at Error\n at jsStackTrace (http://localhost:8080/glfw.js:1033:13)\n at stackTrace (http://localhost:8080/glfw.js:1050:12)\n at abort (http://localhost:8080/glfw.js:5239:44)\n at assert (http://localhost:8080/glfw.js:434:5)\n at receiveInstantiatedSource (http://localhost:8080/glfw.js:1628:7)") at Error
at jsStackTrace (http://localhost:8080/glfw.js:1033:13)
at stackTrace (http://localhost:8080/glfw.js:1050:12)
at abort (http://localhost:8080/glfw.js:5239:44)
at http://localhost:8080/glfw.js:1637:9
我设法对一个工作示例进行了逆向工程,并以此为基础给出了我的答案,所以下面的工作代码编译得很好,没有给出任何错误,只有 JavaScript 文件中的两个警告。
emcc -std=c++11 glfw.cpp -o glfw.js -s USE_WEBGL2=3 -s FULL_ES3=3 -s USE_GLFW =3 -s WASM=3
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Emscripten-Generated Code</title>
<style>
body
{
font-family: arial;
margin: 0;
padding: none;
}
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
canvas.emscripten { border: 0px none; background-color: black; }
</style>
</head>
<body>
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<script type='text/javascript'>
var Module =
{
canvas: (function() {
var canvas = document.getElementById('canvas');
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
return canvas;
})()
};
</script>
<script async type="text/javascript" src="glfw.js"></script>
</body>
</html>
bind.h 并不是真正需要的,除非它不包含在命名空间中。
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
#define GLFW_INCLUDE_ES3
#include <GLFW/glfw3.h>
#include <GLES3/gl3.h>
using namespace emscripten;
int main()
{
// Initialise GLFW
if( !glfwInit() )
{
EM_ASM_({
console.log(' failed: ');
}, 0);
}
EM_ASM_({
console.log(' end initialization: ');
}, 0);
return 0;
}