根据我创建纹理的位置获取 "invalid texture"

Getting "invalid texture" depending on where I create the texture

纹理没有出现在屏幕上并且SDL_RenderCopyreturns错误代码"invalid texture"。但是,只有在构造函数中而不是 Init 函数中加载表面时才会发生这种情况。

如果我不破坏纹理也不会发生:

SDL_DestroyTexture(image_);

我用它来加载图像(没有执行这部分代码):

SDL_Texture* ImageFunc::LoadSprites(const char* filename,bool alpha,int r, int g, int b)
{
    SDL_Surface* old_image=NULL;
    SDL_Texture* new_image=NULL;
    old_image=SDL_LoadBMP(filename);

    if(!old_image)
        printf("image loadinf failure: image func: SDL_LoadBMP \n");

    if(alpha)
        SDL_SetColorKey( old_image, SDL_TRUE, SDL_MapRGB( old_image->format,r, g,b ) );

    new_image=SDL_CreateTextureFromSurface(Global::renderer,old_image);

    if(!new_image)
        printf("image loading failure: image_func\n");

    SDL_FreeSurface(old_image);
    return new_image;
}

(ImageFunc 是一个命名空间)

所以这行不通:

void Button::Init()
{
}

Button::Button()
{
    position_.x = 0;
    position_.y = 0;
    position_.w = 200;
    position_.h = 100;
    image_ = ImageFunc::LoadSprites("Images/ButtonPlay.bmp");
}

但如果我将加载 LoadSprite 放在 Init 方法中,它就会工作。

构造函数和 init 方法同时调用:

buttonPlay_ = Button();
buttonPlay_.Init();

值得注意的是,它在构造函数中,而 buttonPlay_ 是一个属性。

知道是什么原因造成的吗?

您无法轻松复制包含原始指针的 class。纹理是您 class 的资源,您必须管理它(及其生命周期)。

buttonPlay_ = Button();

- 创建临时 Button,将其复制到 buttonPlay_ 并销毁临时 Button,调用 SDL_DestroyTexture(image_)。这导致在 buttonPlay_ 中悬空 image_ 指针。它指向被破坏的纹理。

如果可以,最简单的做法是禁止复制 Button 并只初始化 buttonPlay_ 一次,不要重新分配它。但是如果你需要 Button 是可复制的,你应该可以用 SDL_RenderCopy or SDL_RenderCopyEx 进行深度复制。不过我推荐第一个选项。

编辑:

如果buttonPlay_ = Button();在构造函数中,它应该在成员初始化列表中初始化,避免复制构造函数调用:

SomeClass::SomeClass() :
buttonPlay_()
{
}

你的构造函数无论如何都会默认构造 buttonPlay_,如果你没有声明的话。