我有一个Emscripten驱动的webGL画布,我需要将其保存为来自Javascript处理程序的图像。让我们说一个简单的JS" Save"按钮。
<script type="text/javascript">
var Exporter = {
preRun: [],
postRun: [],
save: function() {
var c=Module.canvas;
var d=c.toDataURL("image/png");
var w=window.open('about:blank','image from canvas');
w.document.write("<img src='"+d+"' alt='from canvas'/>");
}
};
</script>
<input type="button" value="Save" onclick="Exporter.save()" />
默认情况下,webGL上下文将preserveDrawingBuffer设置为false,因此生成的图像为空。
要使图像显示渲染的webGL场景,我需要将preserveDrawingBuffer: true
添加到我编译的Empscripten代码中的getContext调用中传递的属性中。我可以手动编辑已编译的empscripten js代码;结果图像是正确的,但我想避免这种黑客攻击 - 我必须在每次重新编译后都这样做。
是否有更简单,更清晰的方式从外部向preserveDrawingBuffer
添加webGLContextAttributes
?即作为emcc
的编译选项,C代码中的某些SDL参数或托管页面中的Javascript?
更新
请参阅下面的解决方案;我遇到的无关问题是保存的图像具有较低的位深度,并且消除锯齿的线看起来非常糟糕。使用c.toDataURL( "image/jpeg" )
解决了这个问题。
答案 0 :(得分:1)
嗯,首先,所有的emscripten和所有的库都是开源的,所以你可以改变它们。
特别是将library_gl.js
复制到您的项目文件夹,然后移除-lGL
并将--js-library library_gl.js
添加到您的构建脚本中,然后您可以破解您当地的library_gl.js
做任何事情想。
否则我根本不了解SDL,但您可以在调用emscripten代码之前自己获取上下文。画布只能有一个上下文,如果再次为同一类型的上下文调用getContext
,您将获得相同的上下文。换句话说,如果您的JavaScript首先创建上下文,则emscripten代码将获得相同的上下文
所以这应该有用
theCanvasElement.getContext("webgl", {preserveDrawingBuffer: true});
... now execute emscripten and have it use `theCanvasElement`
如果你甚至不能这样做,你可以覆盖getContext
HTMLCanvasElement.prototype.getContext = (function(oldGetContextFn) {
return function(type, attrs) {
attrs = attrs || {};
if (type === "webgl") {
attrs.preserveDrawingBuffer = true;
}
return oldGetContextFn.apply(this, type, attrs);
};
}(HTMLCanvasElement.prototype.getContext));