将 SDL2 RenderDraw 函数与 Emscripten 一起使用

Posted

技术标签:

【中文标题】将 SDL2 RenderDraw 函数与 Emscripten 一起使用【英文标题】:Using SDL2 RenderDraw functions with Emscripten 【发布时间】:2015-03-29 22:10:39 【问题描述】:

我一直在努力使用 emscripten 将一个使用 SDL2 用于图形的简单 C 程序移植到网络上。我浏览了示例程序,但找不到使用 SDL_RenderDrawPoint、SDL_RenderDrawLine 或 SDL_RenderDrawRect 绘制到屏幕的程序。这些功能适用于我的程序的 windows/ubuntu 版本,但不适用于 emscripten 版本。我只是看到屏幕上涂有清除的颜色,但没有任何内容。

这里是展示问题的示例代码。

#include <stdio.h>
#include <SDL2/SDL.h>
#include <assert.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

int main(int argc, char* argv[])

    // setup
    SDL_Window * window;
    SDL_Renderer * renderer;
    assert(SDL_Init(SDL_INIT_VIDEO) == 0);
    SDL_CreateWindowAndRenderer(640, 320, 0, &window, &renderer);

    // clear screen with red color
    SDL_SetRenderDrawColor(renderer, 200, 0, 0, 255);
    SDL_RenderClear(renderer);

    // draw green line across screen
    SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
    SDL_RenderDrawLine(renderer, 0, 0, 640, 320);
    SDL_RenderPresent(renderer);

    SDL_Delay(2000);

    // free resources
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;

我将此代码保存到 main.c 然后运行:

emcc main.c -s USE_SDL=2 -o a.html

在 Windows/Ubuntu 上,我看到:

在 Emscripten (Chrome) 上,我看到了这个:

这是一个错误,还是我做错了什么?

【问题讨论】:

【参考方案1】:

使用 emscripten,您几乎总是必须使用其主循环方法。使用SDL_Delay 或任何其他形式的睡眠是不好的,因为它与普通PC 目标的工作方式不同(更像自旋锁而不是睡眠)。你应该使用类似的东西:

#include <stdio.h>
#include <SDL2/SDL.h>
#include <assert.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

SDL_Window * window;
SDL_Renderer * renderer;

void render_func(void) 
    SDL_SetRenderDrawColor(renderer, 200, 0, 0, 255);
    SDL_RenderClear(renderer);

    SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
    SDL_RenderDrawLine(renderer, 0, 0, 640, 320);
    SDL_RenderPresent(renderer);

#ifdef EMSCRIPTEN
    emscripten_cancel_main_loop();
#endif


int main(int argc, char* argv[])

    assert(SDL_Init(SDL_INIT_VIDEO) == 0);
    SDL_CreateWindowAndRenderer(640, 320, 0, &window, &renderer);

#ifdef EMSCRIPTEN
    emscripten_set_main_loop(render_func, 60, 1);
#else
    render_func();
#endif

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;

【讨论】:

谢谢。很多。您在虚拟 sn-p 中指出了问题。查看您的代码后,我意识到您传递给 emscripten_set_main_loop 的最后一个参数是 1。在我的实际程序中,我使用了 emscripten_set_main_loop,但传递了 0 作为最后一个参数。屏幕上没有打印任何内容。进行更改后,它按预期工作。我看了最后一个参数here的描述,但我不太明白它是如何工作的。 post-emscripten_set_main_loop() 清理代码是否真的用 2015 年的 Emscripten 执行了?

以上是关于将 SDL2 RenderDraw 函数与 Emscripten 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

用 SDL2 加载PNG平铺背景并显示前景

SDL2 - 应该返回 True 的函数评估为 False

SDL2 未定义对 MinGW 的几个函数的引用

EMS、ESB 和 MOM、JMS

SDL2+OpenGL 混合图像产生动态效果

SDL2 丢失 OpenGL 上下文或未定义函数