[英]SFML - Sprite is blank after loading from texture
I am using SFML to display a sprite on the screen.我正在使用 SFML 在屏幕上显示一个精灵。 I first use a texture and call loadFromFile() to load the image.
我首先使用纹理并调用 loadFromFile() 来加载图像。 This works well with no errors occurring.
这很有效,不会发生错误。 It seems that the image path is correct and it loads the image, but it doesn't seem to store the data in the sprite.
似乎图像路径是正确的,它加载了图像,但它似乎没有将数据存储在精灵中。 The sprite is displayed without error, but it shows a blank white image.
精灵显示没有错误,但显示空白图像。
Is there a problem with my code in the following snippets?我的以下代码段中的代码有问题吗? They should be fairly easy to read :).
它们应该很容易阅读:)。
My code:我的代码:
Main.cpp主程序
#include <SFML/Graphics.hpp>
#include "Menu.h"
using namespace sf;
int main()
{
VideoMode vm = VideoMode::getDesktopMode();
int width = vm.width, height = vm.height;
RenderWindow window(VideoMode(width, height), "Score Arena v1.0", Style::Fullscreen);
window.setPosition(Vector2i(0, 0));
Menu menu(width, height);
while (window.isOpen())
{
Event event;
while (window.pollEvent(event))
{
switch (event.type) {
case Event::Closed:
window.close();
break;
//when a key is pressed
case Event::KeyPressed:
if (Keyboard::isKeyPressed(Keyboard::Escape))
window.close();
break;
}
}
window.clear();
menu.draw(window);
window.display();
}
return 0;
}
Menu.h菜单.h
#pragma once
#include <string>
#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;
class Menu {
int page = 0;
string title = "Score Arena";
string labels[4]{
"Single Player",
"Multi Player",
"Options",
"Exit"
};
Sprite background;
int width, height;
public:
Menu(int, int);
void draw(RenderWindow &window);
};
Menu.cpp菜单.cpp
#include "Menu.h"
#include <SFML/Graphics.hpp>
#include <iostream>
Menu::Menu(int width, int height) {
this->width = width;
this->height = height;
Texture bg;
if (!bg.loadFromFile("menuBg.jpg"))
std::cout << "Error loading image!" << std::endl;
background.setTexture(bg);
}
void Menu::draw(RenderWindow &window) {
window.draw(background, RenderStates::Default);
}
An sf::Sprite
object doesn't internally copy the passed sf::Texture
object when you call the setTexture()
member function.当您调用
setTexture()
成员函数时, sf::Sprite
对象不会在内部复制传递的sf::Texture
对象。 An sf::Sprite
just refers to an sf::Texture
;一个
sf::Sprite
只是指一个sf::Texture
; the former doesn't own the latter.前者不拥有后者。 The associated
sf::Texture
must exist when you render the sf::Sprite
.渲染
sf::Sprite
时,关联的sf::Texture
必须存在。
It is stated in the documentation for sf::Sprite
:它在
sf::Sprite
的文档中说明:
It is important to note that the
sf::Sprite
instance doesn't copy the texture that it uses, it only keeps a reference to it.重要的是要注意
sf::Sprite
实例不会复制它使用的纹理,它只保留对它的引用。 Thus, asf::Texture
must not be destroyed while it is used by asf::Sprite
(ie never write a function that uses a localsf::Texture
instance for creating a sprite).因此,当
sf::Texture
被sf::Sprite
使用时,不得销毁它(即永远不要编写使用本地sf::Texture
实例来创建 sprite 的函数)。
The problem is in your Menu
's constructor:问题出在您的
Menu
的构造函数中:
Menu::Menu(int width, int height) {
this->width = width;
this->height = height;
Texture bg; // <-- it is local variable !!!
if (!bg.loadFromFile("menuBg.jpg"))
std::cout << "Error loading image!" << std::endl;
background.setTexture(bg); // <-- associating sprite to a local object!!!
// bg goes out of existence!!!
}
The sf::Texture
object, bg
, ceases to exist as soon the program control flow leaves the constructor because bg
is a local variable inside the constructor.一旦程序控制流离开构造函数,
sf::Texture
对象bg
就不再存在,因为bg
是构造函数内部的局部变量。 As a result, the sf::Sprite
object, background
– a Menu
data member – outlives its associated sf::Texture
object, bg
– a local object.因此,
sf::Sprite
对象background
——一个Menu
数据成员——比其关联的sf::Texture
对象, bg
一个本地对象的寿命更长。
Then, in Menu::draw()
you use this sf::Sprite
object, background
, which internally refers to an sf::Texture
object that no longer exists:然后,在
Menu::draw()
使用这个sf::Sprite
对象background
,它在内部引用一个不再存在的sf::Texture
对象:
void Menu::draw(RenderWindow &window) {
window.draw(background, RenderStates::Default);
}
Instead of the sf::Texture
object being a local object in Menu
's constructor, you could make it a data member of Menu
:取而代之的是的
sf::Texture
对象是在本地对象Menu
的构造函数,你可以把它的数据成员Menu
:
class Menu {
// ...
Texture bg;
Sprite background;
// ...
};
This way, Menu
owns bg
(in contrast to Menu
's constructor owning bg
as was the case before), and therefore Menu
controls bg
's lifetime: bg
is kept alive while the Menu
object lives.这样,
Menu
拥有bg
(与之前的情况相比, Menu
的构造函数拥有bg
),因此Menu
控制bg
的生命周期: bg
在Menu
对象存在时保持活动状态。 This time, when you call Menu::draw()
, the sf::Sprite
object does refer to a living sf::Texture
object.这一次,当您调用
Menu::draw()
, sf::Sprite
对象确实引用了一个活的sf::Texture
对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.