我已经用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
。
1条答案
按热度按时间mw3dktmi1#
我用
NULL
替换了&this->dimensions
,因为当我创建游戏对象时,x
和y
的值被分配给了非常大的数字SDL_WINDOWPOS_CENTERED
(十六进制为0x2FFF0000,十进制为805240832),所以它在屏幕外渲染纹理。