SDL2 不将纹理复制到渲染器

问题描述 投票:0回答:1

我已经使用 SDL2 制作一个简单的游戏几个月了。我最近尝试添加照明,但是当我尝试渲染灯光或任何其他图层时,屏幕只是黑色。

我在不同的

testing
项目上尝试了相同的代码,并且它有效。我也无法再渲染 png,除非有时可以。我不知道是什么导致了这个问题。

这就是我的表面在我的主代码和

testing
代码中初始化的方式(只是简单的SDL_Texture *)

this->background = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, this->dimensions.w, this->dimensions.h);

this->lightLayer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, this->dimensions.w, this->dimensions.h);
SDL_SetTextureBlendMode(lightLayer, SDL_BLENDMODE_MOD);

this->resultLayer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, this->dimensions.w, this->dimensions.h);
SDL_SetTextureBlendMode(resultLayer, SDL_BLENDMODE_BLEND);

SDL_SetRenderDrawColor(this->renderer, 0x00, 0x00, 0x00, 0xff);

我的渲染函数(这就是问题所在)

// Not using lightLayer until I get the background working
SDL_SetRenderTarget(this->renderer, this->resultLayer);
SDL_RenderClear(this->renderer);

SDL_RenderCopy(this->renderer, this->background, NULL, &this->dimensions);
// SDL_RenderCopy(this->renderer, this->lightLayer, NULL, &this->dimensions);

SDL_RenderPresent(this->renderer);

SDL_SetRenderTarget(this->renderer, this->background);
SDL_RenderClear(this->renderer);

// SDL_SetRenderTarget(this->renderer, this->lightLayer);
// SDL_RenderClear(this->renderer);

我的背景被渲染的地方。如果我将渲染目标设置为

NULL
(渲染窗口),则效果很好,但如果我渲染到
background
,则屏幕只会显示为黑色,因为
background
没有被渲染。

void Game::renderSprite(Entity& entity, SDL_Texture* renderSurface)
{
    SDL_SetRenderTarget(this->renderer, this->background); // If I set the second argument to null, it works fine

    //std::cout << "Rendered " << entity.type() << " at " << entity.getCoords().x << ", " << entity.getCoords().y << "\n";
    SDL_Rect src;
    src.x = entity.getSpriteSheetRect().x;
    src.y = entity.getSpriteSheetRect().y;
    src.w = entity.getSpriteSheetRect().w;
    src.h = entity.getSpriteSheetRect().h;

    SDL_Rect dest;
    dest.x = entity.getDimensions().x;
    dest.y = entity.getDimensions().y;
    dest.w = entity.getDimensions().w;
    dest.h = entity.getDimensions().h;

    SDL_RenderCopy(this->renderer, entity.getTexture(), &src, &dest);
}

这是我调用函数的主循环

// Renders all the tiles to the screen
for (Chunk& chunk : *renderVec)
{
    for (Tile& tile : chunk.getTiles())
    {
        game.renderSprite(tile, game.background);
    }
}

...

game.present();

这是我的测试代码,运行良好。测试代码和我的实际代码之间存在一些不一致,但这是因为调试的原因。我把测试代码复制粘贴进去了,还是不行。

SDL_Texture* bgTexture = loadTexture(renderer, "game.png");

// light spot
SDL_Texture* light = loadTexture(renderer, "spot.png");
// layers
SDL_Texture* background = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 640, 480);
SDL_Texture* lightLayer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 640, 480);
SDL_SetTextureBlendMode(lightLayer, SDL_BLENDMODE_MOD);
SDL_Texture* resultLayer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 640, 480);
SDL_SetTextureBlendMode(resultLayer, SDL_BLENDMODE_BLEND);

SDL_Rect spot1 = { 10, 10, 200, 200 };

while (quit != 1)
{
    // Rendering sprites
    // Background
    SDL_SetRenderTarget(renderer, background);
    SDL_RenderCopy(renderer, bgTexture, NULL, NULL);

    // Lights
    SDL_SetRenderTarget(renderer, lightLayer);
    SDL_Rect spot = { 640, 360, 300, 300 };
    SDL_RenderCopy(renderer, light, NULL, &spot); // Middle-ish



    // Rendering everything
    SDL_SetRenderTarget(renderer, resultLayer);
    // Background
    SDL_RenderCopy(renderer, background, NULL, &dimensions);
    // Lights
    SDL_RenderCopy(renderer, lightLayer, NULL, &dimensions);

    // Putting everything on the screen
    SDL_SetRenderTarget(renderer, NULL);
    SDL_RenderCopy(renderer, resultLayer, NULL, &dimensions);

    // Presenting
    SDL_RenderPresent(renderer);



    // Clearing render targets; which also draws the desired color
    // Window
    SDL_RenderClear(renderer);

    // Background
    SDL_SetRenderTarget(renderer, background);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xff);
    SDL_RenderClear(renderer);

    // Shadow/light layer        Set to SDL_BLENDMODE_MOD
    SDL_SetRenderTarget(renderer, lightLayer);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xff); // Alpha value doesn't matter
    // any color besides black is some degree of transparent. Eg. Blue is seen below
    //SDL_SetRenderDrawColor(renderer, 50, 69, 155, 255); // More transparent color
    // Fill screen with color; Doesn't matter which one
    //SDL_RenderFillRect(renderer, NULL);
    SDL_RenderClear(renderer); // Prefered: Can clear the surface and set color, and is platform independant

    // Result layer              Set to SDL_BLENDMODE_BLEND
    SDL_SetRenderTarget(renderer, resultLayer);
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xff);
    SDL_RenderClear(renderer);

我正在使用带有 MSVC 编译器的 Visual Studio 2022,并且

C++20

这是我的第一篇文章,所以我可能错过了一些东西。

c++ sdl sdl-2 render-to-texture
1个回答
0
投票

我建议您阅读 SDL_SetRenderTarget() 文档,还有这个答案:https://stackoverflow.com/a/21007477/8204677 这可能会清除您遇到的问题。

你的渲染函数

// Not using lightLayer until I get the background working
SDL_SetRenderTarget(this->renderer, this->resultLayer);
SDL_RenderClear(this->renderer);

SDL_RenderCopy(this->renderer, this->background, NULL, &this->dimensions);
// SDL_RenderCopy(this->renderer, this->lightLayer, NULL, &this->dimensions);

SDL_RenderPresent(this->renderer);

SDL_SetRenderTarget(this->renderer, this->background);
SDL_RenderClear(this->renderer);

// SDL_SetRenderTarget(this->renderer, this->lightLayer);
// SDL_RenderClear(this->renderer);

我的背景被渲染的地方。如果我设置渲染,效果很好 目标为 NULL (渲染窗口),但如果我渲染到背景 屏幕只是显示为黑色,因为背景未渲染。

要回答这个具体问题,我相信你需要了解渲染的工作原理。在您的渲染函数中,您声称您正在尝试渲染背景,但它不起作用。我想您正在谈论使用

SDL_RenderPresent(this->renderer);
复制背景后的
SDL_RenderCopy()
。由于您之前使用
this->resultlayer
将渲染目标设置为
SDL_SetRenderTarget()
,因此您不再渲染到窗口。要根据文档执行此操作,您需要:

停止渲染到纹理并渲染到窗口 再次使用 NULL 纹理调用此函数。

我相信你自己也提到过。与您在“测试代码”中所做的类似,如果您希望将结果层呈现到窗口中,您可以对结果层执行此操作:

// Putting everything on the screen
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderCopy(renderer, resultLayer, NULL, &dimensions);

我想总结/TLDR是:您正在渲染纹理而不是窗口,这就是您遇到黑屏的原因。

© www.soinside.com 2019 - 2024. All rights reserved.