根据我创建纹理的位置获取 "invalid texture"
Getting "invalid texture" depending on where I create the texture
纹理没有出现在屏幕上并且SDL_RenderCopy
returns错误代码"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_
,如果你没有声明的话。
纹理没有出现在屏幕上并且SDL_RenderCopy
returns错误代码"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_
,如果你没有声明的话。