Emscripten可以从C/C++生成比用手写的JS代码更快的代码,这是否意味着我们应该用C/C++编写新代码并编译它们以在Web上运行?
我阅读了Emscripten FAQ,它说"通过各种方式编写新的JavaScript代码.",为什么会这样?
据我所知,Asm.js只是一个严格的JavaScript规范,它使用JavaScript功能,它不是一种新语言.
例如var a = e;,它提供而不是使用var a = e|0;.
我的问题是,如果asm.js只是一个定义,并且可以通过改变使用和声明变量和动态类型的方式来实现,那么它"use asm";实际上做了什么?在声明函数体之前是否需要将此字符串放入?
运行从C++编译的asmjs\emscripten应用程序时,它突然开始记录:"run() called, but dependencies remain, so not running"到Web控制台,没有其他事情发生.我在主要的绝对开始时添加了一些cout,但即使它们没有达到.
该应用程序之前已成功执行,但突然间这种情况开始发生,我不知道是什么变化触发了这一点.
有谁知道如何调试这个?
更新
在尽可能多地删除源代码之后,只要我#include就会发生这种情况,即使由于我的主要只包含一个cout.
我有一个C程序,它通过命令行接受一个参数(一个char数组/字符串),并从stdin读取.我使用emscripten将其编译为JavaScript.这是成功的,我可以像使用node.js的普通C程序一样运行它:
emcc -O2 translate.c
node translate.js "foo" < bar.txt
Run Code Online (Sandbox Code Playgroud)
如您所见,我提供字符串"foo"作为参数,bar.txt的内容为stdin.现在我希望这是一个自包含的HTML文件.
通过将输出更改为HTML:
emcc -O2 translate.c -o trans.html
Run Code Online (Sandbox Code Playgroud)
我通过添加arguments: ['foo'],到中的定义来提供参数var Module.这按预期工作,程序正确接收参数.
现在,我如何为此程序提供stdin输入?我不需要动态地这样做.只需在HTML中的某个地方声明一个包含所需stdin内容的字符串即可.
刚刚找到了适合我的解决方案.在生成HTML的JS文件中,prompt()当没有定义其他输入方法时,有一个默认的输入处理程序是用户.只需编辑变量result或调用您自己的函数:
} else if (typeof window != 'undefined' &&
typeof window.prompt == 'function') {
// Browser.
// REPLACE THIS CODE:
result = window.prompt('Input: '); // returns null on cancel
if (result !== null) {
result += '\n';
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试从Rust创建一个Web worker,在worker文件中调用一个函数并将一些数据传递给主线程.
main.rs
mod externs;
extern crate libc;
fn main() {
println!("starting worker");
let worker = externs::create_worker("./worker.js");
externs::call_worker(worker, "worker_fn", "", 0);
println!("worker called");
}
Run Code Online (Sandbox Code Playgroud)
worker.rs
#![feature(link_args)]
#[link_args = "-s EXPORTED_FUNCTIONS=['_worker_fn'] -s BUILD_AS_WORKER=1"]
extern crate libc;
mod externs;
extern {}
fn main() {
println!("worker main");
}
#[no_mangle]
pub extern fn worker_fn() {
println!("hello from the other side!");
}
Run Code Online (Sandbox Code Playgroud)
当我编译工作文件和主文件时,我能够在工作文件中看到来自main.rs甚至"工作者主"消息的消息.我还可以看到浏览器发送请求worker.js,但似乎主线程没有调用worker_fnworker文件内部.
这是externs文件:
use std::ffi::CString;
use libc::*;
use std::str::FromStr;
/// Creating web worker
pub fn create_worker(url: …Run Code Online (Sandbox Code Playgroud) 我有一个HTML页面大致分为30% - 70%分为两个垂直列.左列包含聊天提要(通过Node和Socket.io处理),右列包含emscripten生成的canvas(ID为ID canvas).画布包含一个基本的3D世界,用户可以使用标准的第一人称控件进行导航(WASD用于移动,鼠标用于"外观").
默认情况下,画布会吞下所有键盘事件.我已在canvas初始化过程中使用以下代码修复此问题:
Module.preRun.push(function () {
ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = "#canvas";
});
Run Code Online (Sandbox Code Playgroud)
这允许我手动关注聊天框,键入消息并提交.
我遇到的问题是,一旦聊天消息被提交,我尝试使用以下代码将焦点返回到画布(允许玩家使用WASD导航3D世界):
$('#canvas').focus();
Run Code Online (Sandbox Code Playgroud)
这名义上将焦点返回到画布,但鼠标和键盘移动不起作用.奇怪的是,单击选项卡/浏览器窗口然后进入画布似乎工作 - 焦点返回到画布,我可以再次导航.手动呼叫$(window).blur().focus()不起作用.
有人知道如何在发送聊天消息后将焦点强制回到画布吗?
- 更新 -
我hiddenField在画布后面添加了一个文本输入字段(ID为),我使用preRun函数将画布的关键事件分配给该字段(画布由于某种原因不能一致地工作).
这个工作正常,直到用户点击画布 - 例如,进入聊天字段 - 因此画布停止响应任何键盘或鼠标输入,即使我正在触发焦点回到hiddenField(并且可以看到它正在获取它) .
似乎在页面上做任何事情都与emscripten的聚焦行为(我相信与窗口对象相关)发生冲突,并阻止画布重新获得焦点.
当然有一些方法可以让emscripten画布与其他HTML元素一起生活吗?
我有一个简单的程序,请说如下:
#include <stdio.h>
int main()
{
char buf[100];
while (fgets(buf, sizeof(buf), stdin) != NULL) {
printf("You typed: %s", buf);
}
}
Run Code Online (Sandbox Code Playgroud)
我用Emscripten编译了它:
emcc -o hello.html hello.cpp
Run Code Online (Sandbox Code Playgroud)
这给了我一个非常基本的Emscripten生成的网页,其中包含一个简单的程序输出窗口.但是,该fgets()调用会导致浏览器弹出窗口,大概来自prompt().我可以输入内容,结果最终会显示在输出窗口中.这不是一个理想的互动体验.
我想要的是更传统的"控制台"界面,用户可以在终端窗口中交互式输入以向交互式程序提供输入.
我怀疑解决方案可能存在于JQueryTerminal,Hyper或Xterm.js之类的内容中,但我目前还不清楚如何将其中任何一个实际连接到Emscripten编译的程序.
如何为我的Emscripten代码提供"控制台"界面?
我正在尝试在Ubuntu上安装Emscripten,但Emscripten 的官方安装指南并没有提供在Linux上安装Emscripten的任何说明.安装指南提供的唯一建议是:
If you are on Linux, things should be very simple for you and there is no need for any additional guide.
我也阅读了Emscripten存储库中的README.md文件,它也没有为Ubuntu提供任何指令.为了在Ubuntu上设置Emscripten,我需要遵循哪些步骤?
我已经编写了一个基于磁贴的引擎 - 只要在WebGL中禁用了抗锯齿,一切看起来都很好.
启用抗锯齿时,有时会渲染图块边缘的像素,这些像素主要显示为背景像素并适当填充深度缓冲区.当更强烈(更高的α)像素进入时,由于深度缓冲而被丢弃.
我确实尝试禁用深度缓冲区,并"将混合因子设置为GL_SRC_ALPHA_SATURATE(源)和GL_ONE(目标)",如下所示:http://www.glprogramming.com/red/chapter06.html .这导致绘制纯白色像素 - 不确定那里发生了什么.
我的纹理上的图形都被填充,因此WebGL不应该有过滤问题.我已经使填充极端,以确保这不是一个促成因素.
我已经glSampleCoverage()在黑暗中探索并尝试了几次射击,随机值不会产生任何价值.我不熟悉它实际上做了什么,除了一些抽象的建议外,在网上找不到任何好的例子.
我宁愿不禁用深度缓冲区.
GL_MULTISAMPLE 不可用.
我有一个带C++环境的Emscripten - 但这没关系,我可以根据需要编写内联javascript - 但我认为这是通用的OpenGL解决方案.
有没有办法在WebGL中仅为某些几何体禁用抗锯齿?
好:

坏:

我正在尝试一个简单的例子,用JavaScript调用编译为.wasm的C函数.
这是counter.c文件:
#include <emscripten.h>
int counter = 100;
EMSCRIPTEN_KEEPALIVE
int count() {
counter += 1;
return counter;
}
Run Code Online (Sandbox Code Playgroud)
我用它编译了它emcc counter.c -s WASM=1 -o counter.js.
我的main.jsJavaScript文件:
const count = Module.cwrap('count ', 'number');
console.log(count());
Run Code Online (Sandbox Code Playgroud)
我的index.html文件只加载正文中的两个.js文件,没有别的:
<script type="text/javascript" src="counter.js"></script>
<script type="text/javascript" src="main.js"></script>
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
Uncaught abort("Assertion failed: you need to wait for the runtime to be ready (e.g. wait for main() to be called)") at Error
当我试着打电话count()的时候main.js.我怎么能等待运行时准备好?
emscripten ×10
javascript ×6
asm.js ×3
c++ ×3
c ×1
canvas ×1
jquery ×1
opengl-es ×1
rust ×1
ubuntu ×1
webassembly ×1
webgl ×1
xtermjs ×1