带emscripten和SDL的Wasm-如何仅清除部分渲染器

带emscripten和SDL的Wasm-如何仅清除部分渲染器,c,html5-canvas,sdl,webassembly,emscripten,C,Html5 Canvas,Sdl,Webassembly,Emscripten,我已经使用emscripten和SDL创建了一个Wasm动画。我现在尝试创建一个按钮,用户可以在其中启动和停止/暂停动画。我的问题是每次迭代都会清除整个画布。在我看来,这里有3个选项: 在每一帧上重新绘制按钮 仅清除动画在每次迭代中使用的画布部分 使用HTML表单作为输入按钮 (1) 似乎效率低下。(3) 需要我开始在JS和Wasm之间进行互操作。到目前为止,我已经能够在不编写一行JS的情况下构建整个过程,并且更愿意保持这种方式。所以可能(2)是最好的 我知道使用JS可以指定clearRect调

我已经使用emscripten和SDL创建了一个Wasm动画。我现在尝试创建一个按钮,用户可以在其中启动和停止/暂停动画。我的问题是每次迭代都会清除整个画布。在我看来,这里有3个选项:

  • 在每一帧上重新绘制按钮
  • 仅清除动画在每次迭代中使用的画布部分
  • 使用HTML表单作为输入按钮
  • (1) 似乎效率低下。(3) 需要我开始在JS和Wasm之间进行互操作。到目前为止,我已经能够在不编写一行JS的情况下构建整个过程,并且更愿意保持这种方式。所以可能(2)是最好的

    我知道使用JS可以指定clearRect调用的维度。但是,我在SDLAPI中找不到此功能

    下面是mainLoop函数(每秒调用大约60次)(如果不清楚,这是用C编写的,不是C++)。我的问题是,如何调整“SDL_RenderClear”,使其只清除画布的一半?(带动画的那一半。即,不要清除我要制作按钮的那一半

    main.c

    #include <stdio.h>
    #include <SDL2/SDL.h>
    #include <emscripten.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    <....>
    
    /**
     * The loop handler, will be called repeatedly
     */
    void mainLoop(void *arg) {
        struct Context *ctx = arg;
        printf("iteration: %d\n", ctx->iteration);
    
        SDL_SetRenderDrawColor(ctx->renderer, 255, 0, 100, 255);
        SDL_RenderClear(ctx->renderer);
    
        bool running = true;
    
        if (running) {
            for (int j=1; j<8; j++) {
                for (int i=1; i<130; i++) {
                    // drawRect is another app function that calls the SDL to draw a rectangles.
                    drawRectangle(ctx, i, j);
                }
            }
        }
        SDL_RenderPresent(ctx->renderer);
        ctx->iteration++;
    }
    
    <....>
    
    #包括
    #包括
    #包括
    #包括
    #包括
    /**
    *循环处理程序将被重复调用
    */
    void主循环(void*arg){
    结构上下文*ctx=arg;
    printf(“迭代:%d\n”,ctx->迭代);
    SDL_SetRenderDrawColor(ctx->渲染器,255,010025);
    SDL_渲染器(ctx->渲染器);
    bool running=true;
    如果(正在运行){
    对于(int j=1;jitation++;
    }
    
    你可以在你不想要的部分上画画。但是,除非你做了很多的诡计,否则这并没有多大帮助

    正式原因-表示“backbuffer在每次出现后都应被视为无效;不要假设帧之间会存在以前的内容。”

    在许多情况下,缓冲区将(部分)失效,例如,将窗口移出屏幕边界。我不知道webasm,如果承诺提供任何有关缓冲区内容的信息,您可能需要查看webgl文档

    即使您可以依赖于要保留的内容,但例如,您有双缓冲设置。您已经渲染到第一个缓冲区,执行了缓冲区交换-现在您有了第二个缓冲区,该缓冲区的内容尚未初始化。第二次交换后,内容可能或多或少相似,但任何更改都将滞后于1帧


    一些3d软件(如搅拌器)按照您所描述的做了,但即使在那里,它也不是100%稳定的,通常有一个选项来禁用该行为。执行完全重画比您想象的要便宜得多,如果成本太高,您可以始终将屏幕的一部分渲染为渲染纹理,并将其用作单个静态图像,在必要时进行更新。

    您可以在你不想要的部分涂上油漆。然而,除非你做了很多的欺骗,否则这是没有多大帮助的

    正式原因-表示“backbuffer在每次出现后都应被视为无效;不要假设帧之间会存在以前的内容。”

    在许多情况下,缓冲区将(部分)失效,例如,将窗口移出屏幕边界。我不知道webasm,如果承诺提供任何有关缓冲区内容的信息,您可能需要查看webgl文档

    即使您可以依赖于要保留的内容,但例如,您有双缓冲设置。您已经渲染到第一个缓冲区,执行了缓冲区交换-现在您有了第二个缓冲区,该缓冲区的内容尚未初始化。第二次交换后,内容可能或多或少相似,但任何更改都将滞后于1帧


    一些3d软件(如搅拌器)按照您描述的做了,但即使在那里,它也不是100%稳定的,通常有一个选项可以禁用该行为。执行完全重画比您想象的要便宜得多,如果成本太高,您可以始终将屏幕的一部分渲染为渲染纹理,并将其用作单个静态图像,在必要时进行更新。

    您可以使用
    SDL\u RenderFillRect
    以清晰的颜色填充指定区域。但是,重新绘制屏幕的部分可能会有很大的问题,特别是如果您有双缓冲。谢谢。如果您想详细说明,听起来您可以发布答案?您可以使用
    SDL\u RenderFillRect
    以清晰的颜色填充指定区域。您好er重画屏幕的部分可能会很麻烦,特别是如果你有双缓冲。谢谢。如果你想详细说明,听起来你可以发布一个答案?