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
时,我们得到的是原生纹理,它可能不同也可能不同。
我正在尝试使用 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
时,我们得到的是原生纹理,它可能不同也可能不同。