SDL_SetRenderTarget 没有设置目标

SDL_SetRenderTarget doesn't set the tartget

我正在尝试使用 Sol2 绑定编写已注册并在 Lua 中使用的 C++ lambda。下面的回调应该创建一个 SDL_Texture,并将其清除为一种颜色。 Lua_Texture 只是 SDL_Texture 的包装,而 l_txt.texture 的类型是 SDL_Texture*.

lua.set_function("init_texture",
    [render](Lua_Texture &l_txt, int w, int h)
    {
        // free any previous texture
        l_txt.deleteTexture();

        l_txt.texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);

        SDL_SetRenderTarget(render, l_txt.texture);
        SDL_Texture *target = SDL_GetRenderTarget(render);

        assert(l_txt.texture == target);
        assert(target == nullptr);

        SDL_SetRenderDrawColor(render, 0xFF, 0x22, 0x22, 0xFF);
        SDL_RenderClear(render);
    });

我的问题是 SDL_SetRenderTarget 没有按照我的预期运行。我尝试将纹理设置为目标以便清除它的颜色,但是当我尝试将纹理绘制到屏幕时它仍然是空白的。上面代码中的断言都失败了,并表明当前目标纹理没有设置为我试图清除并稍后使用的纹理,也不是 Null(如果没有当前目标纹理,这是预期值)。

我之前在 c++ 中使用过这段代码(不是作为 Lua 回调)并且它按预期工作。不知何故,将其嵌入 Lua 会导致行为发生变化。非常感谢任何帮助,因为我已经为此苦恼了一段时间,谢谢!

我可能会给你一个答案,但你不会喜欢的。

看起来 SDL_GetRenderTarget 没有按预期工作。

我遇到了与您完全相同的问题(这就是我发现您的问题的方式),并且我可以使用这个简单的程序可靠地重现它:

int rendererIndex;

[snipped code : rendererIndex is set to the index of the DX11 renderer]

SDL_Renderer * renderer = SDL_CreateRenderer(pWindow->pWindow, rendererIndex, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE);

SDL_Texture* rtTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 200, 200);

SDL_SetRenderTarget(renderer, rtTexture);

if(SDL_GetRenderTarget(renderer) != rtTexture)
  printf("ERROR.");

这总是产生:

ERROR.

我使用的解决方法是将指针保存到我为渲染器设置的渲染目标纹理,但我不使用 SDL_GetRenderTarget

编辑:

我很好奇为什么我获取的时候没有得到正确的render target,我翻了一下SDL2的源码。我找到了原因(为了清楚起见,代码被剪掉了):

int
SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
{

// CODE SNIPPED

    /* texture == NULL is valid and means reset the target to the window */
    if (texture) {
        CHECK_TEXTURE_MAGIC(texture, -1);
        if (renderer != texture->renderer) {
            return SDL_SetError("Texture was not created with this renderer");
        }
        if (texture->access != SDL_TEXTUREACCESS_TARGET) {
            return SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET");
        }
// *** EMPHASIS MINE : This is the problem.
        if (texture->native) {
            /* Always render to the native texture */
            texture = texture->native;
        }
    }

// CODE SNIPPED

    renderer->target = texture;

// CODE SNIPPED
}

SDL_Texture *
SDL_GetRenderTarget(SDL_Renderer *renderer)
{
    return renderer->target;
}

简而言之,渲染器将当前渲染目标保存在 renderer->target 中,但不会在将当前纹理转换为其原始形式之前保存。当我们使用 SDL_GetRenderTarget 时,我们得到的是原生纹理,它可能不同也可能不同。