c++ SDL 2未将纹理复制到渲染器

pkwftd7m  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(87)

我已经用SDL 2做了几个月的简单游戏。我最近尝试添加灯光,但当我尝试渲染灯光或任何其他图层时,屏幕只是黑色的。
我在另一个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);

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

// 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_SetRenderTarget(this->renderer, NULL);
SDL_RenderCopy(this->renderer, this->resultLayer, NULL, &this->dimensions);
SDL_RenderPresent(this->renderer);

SDL_RenderClear(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);

我使用的是Visual Studio 2022和MSVC编译器,以及C++20

mw3dktmi

mw3dktmi1#

我用NULL替换了&this->dimensions,因为当我创建游戏对象时,xy的值被分配给了非常大的数字SDL_WINDOWPOS_CENTERED(十六进制为0x2FFF0000,十进制为805240832),所以它在屏幕外渲染纹理。

相关问题