如何在emscripten

时间:2018-06-12 14:45:30

标签: canvas emscripten webassembly

我正在开发一个webassembly程序。 我可以使用emscripten_set_canvas_size来设置画布大小(通过我读到我需要切换到新的API,因为这个将被折旧)...

但我的问题是:如何在画布上设置像素? 我的程序为画布生成一个32位颜色的数组,我需要将所有位从内部存储器传输到画布。我怎么能这样做?

或者,如果我可以获取画布数据的内存指针,我可以直接在所述内存中写入...

我希望,如果可能的话,这样做而不必重新考虑任何其他API(GL,SDL ......)我需要的是尽可能快地将颜色转移到画布上......没有什么比这一点。

理想情况下,我正在寻找一个简短的示例程序:

#include <...>
  uint32_t screen[320*320];
 static void main_loop()
 {
   memset(screen, 0, 320*320*4); // Clear screen
   for (int x=0; x<320; x++)
     for (int y=0; y<320; y++)
       screen[320*(x|y) + (x&y)]= 0xffffff; // set pixel(x or y, x and y) to white... (will draw a serpinsky triangle)
   Copy_ToCanvas(screen);  // THIS IS THE FUNCTION THAT I AM LOOKING FOR
 }

int main()
{
  emscripten_set_canvas_size(320, 320);
  emscripten_set_main_loop(main_loop, 100, true);
  return 0;
} 

谢谢, 西里尔

2 个答案:

答案 0 :(得分:3)

如果没有SDL,则需要低级代码。

void Copy_ToCanvas(uint32_t* ptr, int w, int h) {
  EM_ASM_({
      let data = Module.HEAPU8.slice($0, $0 + $1 * $2 * 4);
      let context = Module['canvas'].getContext('2d');
      let imageData = context.getImageData(0, 0, $1, $2);
      imageData.data.set(data);
      context.putImageData(imageData, 0, 0);
    }, ptr, w, h);
}

static void main_loop()
{
  memset(screen, 0, 320*320*4); // Clear screen
  for (int x=0; x<320; x++)
    for (int y=0; y<320; y++)
      screen[320*(x|y) + (x&y)]= 0xffffffff; // set pixel(x or y, x and y) to white... (will draw a serpinsky triangle)
  Copy_ToCanvas(screen, 320, 320);
}

答案 1 :(得分:0)

仅需注意,上面的有用答案将无法正确显示,因为memset()调用不会将浏览器屏幕清除为黑色。显然,您必须显式设置Alpha通道。因此,除了memset()之外,

    int screen[320*320],idx=0;
    for (int x=0; x<320*320; x++)
        screen[idx++] = 0xff000000;